一、注册功能
- ajax上传文件
![]()
from django.shortcuts import render, HttpResponse
def upload(request):
"""
上传文件操作
:param request:
:return:
"""
if request.method == "POST":
# 从上传的文件数据中拿到 avatar对应的文件对象
file_obj = request.FILES.get("avatar")
# 在服务端新建一个和上传文件同名的新文件
with open(file_obj.name, "wb") as f:
# 从上传文件对象中一点一点读数据
for i in file_obj:
# 写入服务端新建的文件
f.write(i)
return HttpResponse("上传成功")
return render(request, "upload.html")
def upload_ajax(request):
"""
使用ajax方式上传
:param request:
:return:
"""
return render(request, "upload_ajax.html")
views.py
![]()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传文件</title>
</head>
<body>
<form action="" method="post" enctype="multipart/form-data"> // 必须加 enctype="multipart/form-data"
{% csrf_token %}
<label>
<input type="file" name="avatar">
</label>
<label>
<input type="submit" value="上传">
</label>
</form>
</body>
</html>
upload.html
![]()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传文件</title>
</head>
<body>
{% csrf_token %}
<input type="file" name="avatar" class="f1">
<input type="button" class="b1" value="上传"> // 使用ajax时候不要用submit
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>
$(".b1").click(function () {
// 先生成一个FromData对象
var fd = new FormData();
// 将要提交的数据
fd.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());
fd.append("avatar", $(".f1")[0].files[0]);
$.ajax({
url: "/upload/",
type: "post",
data: fd,
contentType: false,
processData: false,
success: function (res) {
console.log(res)
}
})
});
</script>
</body>
</html>
upload_ajax.html
- 头像预览
![]()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传文件</title>
</head>
<body>
{% csrf_token %}
{#style="width: 40px; border-radius: 50% 设置图片大小并修改成圆头像#}
{#accept="image/*" 只显示图片类型的文件#}
<label><img src="/static/images/default.png" alt="" style="width: 40px; border-radius: 50%">
<input type="file" name="avatar" class="f1" style="display: none;" accept="image/*">
</label>
<input type="button" class="b1" value="上传">
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>
// Ajax上传头像
$(".b1").click(function () {
// 先生成一个FromData对象
var fd = new FormData();
// 将要提交的数据
fd.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());
fd.append("avatar", $(".f1")[0].files[0]);
$.ajax({
url: "/upload/",
type: "post",
data: fd,
contentType: false,
processData: false,
success: function (res) {
console.log(res)
}
})
});
// 预览头像
$(".f1").change(function () {
// 取到用户选中的头像文件
var fileobj = this.files[0];
// 新新建一个FileReader对象, 从本地磁盘加载文件数据
var fr = new FileReader();
fr.readAsDataURL(fileobj);
// 读取文件需要时间
fr.onload=function () {
// 找到预览头像的img标签,把踏的src属性设置成读取的用户选中的图片
$("img").attr("src", fr.result)
}
});
</script>
</body>
</html>
头像预览
- Django项目上传文件之后怎么查看
1. 配置上传的文件保存在哪里
settings.py中 MEDIA_ROOT = os.path.join(BASE_DIR, "media")
上传文件需要注意两点:
1. 前端使用form表单上传需要配置 enctype="multipart/form-data"
<form class="form-horizontal" action="" method="post" novalidate enctype="multipart/form-data">
2. 后端接收
avatar_obj = request.FILES.get("avatar")
2. 如何查看上传的文件
/media/xx/oo.jpg
1. settings.py中设置 MEDIA_URL="/media/"(别名)
2. urls.py中设置 media开头的路径用什么视图函数处理
url(r'^media/(?P<path>.*)', serve, {"document_root": settings.MEDIA_ROOT}),
二、CMS表结构设计
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class UserInfo(AbstractUser):
"""
用户表,
新增手机号字段
新增头像字段
verbose_name 在admin中显示的字段名称
"""
phone = models.CharField(max_length=11, verbose_name="手机号")
avatar = models.FileField(upload_to="avatars", default="avatars/default.png", verbose_name="头像")
class Meta:
"""
verbose_name 在admin中显示的表名称
"""
verbose_name = "用户管理"
verbose_name_plural = verbose_name
class Fault(models.Model):
"""
故障表
"""
title = models.CharField(max_length=50, verbose_name="故障标题")
summary = models.TextField(max_length=100, verbose_name="故障概述")
create_time = models.DateTimeField(auto_now_add=True, verbose_name="发布时间")
modify_time = models.DateTimeField(auto_now=True, verbose_name="最后修改时间")
tags = models.ManyToManyField(to="Tag",
through="Fault2Tag", # 指定第三张关系表
through_fields=("fault", "tag"), # 通过哪些字段建立多对多关系
verbose_name="标签")
classify = models.ForeignKey(to="Classify", verbose_name="分类", null=True)
user = models.ForeignKey(to="UserInfo", verbose_name="发布用户")
comment_count = models.IntegerField(default=0, verbose_name="评论总数")
up_count = models.IntegerField(default=0, verbose_name="点赞总数")
down_count = models.IntegerField(default=0, verbose_name="反正总数")
def __str__(self):
return self.title
class Meta:
verbose_name = "故障管理"
verbose_name_plural = verbose_name
class Tag(models.Model):
"""
标签表
"""
name = models.CharField(max_length=30, verbose_name="标签名称", unique=True)
def __str__(self):
return self.name
class Meta:
verbose_name = "标签管理"
verbose_name_plural = verbose_name
class Classify(models.Model):
"""
分类表
"""
name = models.CharField(max_length=30, verbose_name="业务线名称", unique=True)
def __str__(self):
return self.name
class Meta:
verbose_name = "业务线管理"
verbose_name_plural = verbose_name
class Comment(models.Model):
"""
评论表
"""
content = models.CharField(max_length=100, verbose_name="评论内容")
comment_date = models.DateTimeField(auto_now_add=True, verbose_name="评论时间")
fault = models.ForeignKey(to="Fault", verbose_name="故障总结")
user = models.ForeignKey(to="UserInfo", verbose_name="评论用户")
parent_comment = models.ForeignKey(to="self", null=True, blank=True, verbose_name="父级评论") # 自己关联自己,用户可以评论其他人的评论
def __str__(self):
return self.content
class Meta:
verbose_name = "评论管理"
verbose_name_plural = verbose_name
class UpDown(models.Model):
"""
点赞表
同一个用户只能对一篇文章进行点赞或者反对,如果点赞了就不能反对,二选一
"""
user = models.ForeignKey(to="UserInfo", verbose_name="用户")
fault = models.ForeignKey(to="Fault", verbose_name="故障总结")
is_up = models.BooleanField(default=True, verbose_name="支持/反对")
def __str__(self):
return "{}-{}-{}".format(self.user.username, self.fault.title, "支持" if self.is_up else "反对")
class Meta:
"""
unique_together联合唯一,限制一用户只能对一篇文章进行点赞或者反对
"""
unique_together = (("user", "fault"),)
verbose_name = "支持/反对"
verbose_name_plural = verbose_name
class Fault2Tag(models.Model):
"""
故障报告和标签多对多关联表
手动生产第三张表,可以在第三张表增加新的字段
"""
fault = models.ForeignKey(to="Fault", verbose_name="故障总结")
tag = models.ForeignKey(to="Tag", verbose_name="标签名称")
def __str__(self):
return "{}-{}".format(self.fault.title, self.tag.name)
class Meta:
unique_together = (("fault", "tag"),)
verbose_name = "故障-标签"
verbose_name_plural = verbose_name
class FaultDetail(models.Model):
"""
故障内容表
为什么不和故障表放到一起?
故障内容可能多,用户每次请求页面的时候都请求故障内容,就会很慢。
"""
content = models.TextField(verbose_name="故障内容")
fault = models.ForeignKey(to="Fault", verbose_name="故障总结")
def __str__(self):
return self.content
class Meta:
verbose_name = "故障详情"
verbose_name_plural = verbose_name
三、CMS首页和个人中心页面实现
ORM 高阶用法都在 --> https://www.cnblogs.com/liwenzhou/p/8660826.html
1. ORM分组和聚合查询
聚合内置函数:from django.db.models import Avg, Sum, Max, Min, Count
annotate()
annotate()前面查的是什么就按照什么分组
.values("dept").annotate()就表示按照dept分组
2. 时间格式化函数
1. MySQL
DATE_FORMAT(字段, '格式')
示例:models.Fault.objects.all().extra(select={"ym": "date_format(create_time, '%%Y-%%m')"}).values("ym").annotate(num=Count("id")).values("ym", "num")
2. sqlite
strftime('格式', 字段)
示例:models.Fault.objects.all().extra(select={"ym": "strftime('%%Y-%%m', create_time)"}).values("ym").annotate(num=Count("id")).values("ym", "num")
3. Django ORM执行原生SQL语句
1. 使用extra()执行部分sql语句
示例:models.Fault.objects.all().extra(select={"ym": "date_format(create_time, '%%Y-%%m')"}).values("ym").annotate(num=Count("id")).values("ym", "num")
2. 类似pymysql执行方式
4. 二级路由
1. 保障系统4合1
代码示例:
CMS urls.py:
from fault_reporting import urls as fault_urls
urlpatterns = [
url(r'^fault-report/', include(fault_urls))
]
fault_reporting urls.py:
urlpatterns = [
# 根据产品线,标签,日期归档分类 ()在正则是分组的意思,这里分2个组传了2个参数
url(r'(class|tag|archive)/(.*)/$', views.index)
]