表结构设计
用户表(利用auth_user表) phone avatar create_time blog # 一对一个人站点 ps:DateField() auto_now:每次操作数据都会将当前时间更新 auto_now_add:自动将创建该数据的时间记录下来之后不再改变 个人站点表 站点名称 site_name 站点标题 site_title 站点样式 site_theme 文章表 文章标题 title 文章简介 desc 文章内容 content 发布时间 create_time blog 一对多个人站点 category 一对多分类表 tag 多对多标签表 # 数据库设计优化(******) up_num down_num comment_num # 当你操作点赞点踩表或者评论表的时候 只要保证上面三个同步更新 标签表 tag_name blog 一对多个人站点 分类表 category_name blog 一对多个人站点 点赞点踩表 user 一对多user表 article 一对多article表 is_up 0/1 文章评论表 user 一对多user表 article 一对多article表 content create_time parent 自关联评论表 (to='self') # self表示的就是当前表
注意:
如果一张表内的数据分成两块 一块是经常使用的 一块是不经常使用的,这个时候考虑数据优化的问题
一对一关系两种:
1.一张表拆成了两张表
2.两张表中的数据是一一对应的
表与表之间关系判断:
表中的一条数据能否对于另外一张表的多条数
img标签的src属性可以接受三种类型的值:
1.图片的文件路径
2.图片的二进制数据
3.url地址
models
from django.db import models from django.contrib.auth.models import AbstractUser # Create your models here. class Userinfo(AbstractUser): phone = models.CharField(max_length=11,null=True) avatar = models.FileField(upload_to='avatar/',default='avatar/default.jpg') # 当用户上传自己的头像的时候 会将用户上传的头像文件自动存入avatar文件夹下 create_time = models.DateField(auto_now_add=True) # 创建数据的时候自动添加当前时间 blog = models.OneToOneField(to='Blog',null=True) class Blog(models.Model): site_name = models.CharField(max_length=32) site_title = models.CharField(max_length=32) site_theme = models.CharField(max_length=64) # 存放的是css文件的路径 class Tag(models.Model): tag_name = models.CharField(max_length=32) blog = models.ForeignKey(to='Blog') class Category(models.Model): category_name = models.CharField(max_length=32) blog = models.ForeignKey(to='Blog') class Article(models.Model): title = models.CharField(max_length=32) desc = models.CharField(max_length=255) content = models.TextField() # 存大段文本内容 create_time = models.DateField(auto_now_add=True) # 数据库优化相关字段 up_num = models.IntegerField(default=0) down_num = models.IntegerField(default=0) comment_num = models.IntegerField(default=0) blog = models.ForeignKey(to='Blog',null=True) category = models.ForeignKey(to='Category',null=True) tag = models.ManyToManyField(to='Tag',through='Article2Tag',through_fields=('article','tag')) class Article2Tag(models.Model): article = models.ForeignKey(to='Article') tag = models.ForeignKey(to='Tag') class UpAndDown(models.Model): user = models.ForeignKey(to='Userinfo') article = models.ForeignKey(to='Article') is_up = models.BooleanField() # 传布尔类型 数据库里面会存成 0/1 class Comment(models.Model): user = models.ForeignKey(to='Userinfo') article = models.ForeignKey(to='Article') content = models.TextField() create_time = models.DateField(auto_now_add=True) parent = models.ForeignKey(to='self',null=True)
html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link rel="stylesheet" href="/static/bs-3.3.7/css/bootstrap.css"> <script src="/static/bs-3.3.7/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <h1 class="text-center">注册</h1> <hr> <form id="myform" novalidate> {% csrf_token %} {% for foo in form_obj %} <div class="form-group"> <label for="{{ foo.auto_id }}">{{ foo.label }}</label> {{ foo }} <span class="pull-right" style="color: red"></span> </div> {% endfor %} <div class="form-group"> <label for="id_file">头像 <img src="/static/image/default.jpg" alt="" width="80" style="margin-left: 20px" id="id_img"> #将服务器的静态资源放到html返回给浏览器 </label> <input type="file" name="myfile" id="id_file" class="hidden"> </div> <input type="button" class="btn btn-success pull-right" value="注册" id="id_submit"> </form> </div> </div> </div> <script> $("#id_file").change(function () { var fileObj = $(this)[0].files[0]; // 获取文件对象 var fileReader = new FileReader(); // 利用内置对象 文件阅读器 FileReader fileReader.readAsDataURL(fileObj); // 将文件对象交给文件阅读器 生成文件对象的二进制数据(异步操作) fileReader.onload = function (){ $('#id_img').attr('src',fileReader.result) // 修改img标签的src属性值 }; }); $('#id_submit').click(function () { var formData = new FormData(); // 利用内置对象FormData完成既有普通键值又有文件数据的发送 // 添加普通键值对 // formData.append('','') // console.log($('#myform').serializeArray()); // 会将form标签内的数据,以普通的键值对的形式,自动组成一个列表的形式返回给你 $.each($('#myform').serializeArray(),function (index,obj) { // $.each(你想要被循环的对象,函数(索引,单个单个的对象)) // console.log(index,obj) formData.append(obj.name,obj.value) // 将普通的键值对添加进去 }); formData.append('my_avatar',$('#id_file')[0].files[0]); // 添加文件数据 $.ajax({ url:'', type:'post', data:formData, contentType:false, processData:false, success:function (data) { if (data.code==2000){ location.href = data.url }else{ // console.log(data.msg) $.each(data.msg,function (index,obj) { {#console.log(index,obj)#} var targetId = '#id_' + index; //input隐藏id_username这样的标签 $(targetId).next().html(obj[0]).parent().addClass('has-error') }) } } }) }); $('input').focus(function () { $(this).next().html('').parent().removeClass('has-error') // 将当前input所在的div移除has-error属性 并将下面的span标签内的内容也移除了 }) </script> </body> </html>
views
from django.shortcuts import render,HttpResponse,redirect from app01 import models from app01.myforms import RegForm from django.http import JsonResponse # Create your views here. def register(request): back_dic = {"code":None,'msg':''} form_obj = RegForm() if request.method == 'POST': form_obj = RegForm(request.POST) # 利用forms组件校验 普通字段的数据 if form_obj.is_valid(): clean_data = form_obj.cleaned_data """ clean_data = {'username':'','password':'','confirm_password':'','email':''} """ clean_data.pop('confirm_password') # 将confirm_password键值对从clean_data去除掉 """ clean_data = {'username':'','password':'','email':''} """ avatar = request.FILES.get("my_avatar") if avatar: # 如果用户没有选择头像 那么该值为空 ,如果空就利用不到models中头像的默认值 #只有当用户选择了自己的头像 才应该将avatar添加到clean_data字典中 clean_data['avatar'] = avatar """ clean_data = {'username':'','password':'','email':'','avatar':'文件对象'} """ models.Userinfo.objects.create_user(**clean_data) back_dic['code'] = 2000 back_dic['msg'] = '注册成功' back_dic['url'] = '/login/' # 当用户注册成功 直接跳转到登录页面 else: back_dic['code'] = 2001 back_dic['msg'] = form_obj.errors return JsonResponse(back_dic) return render(request,'register.html',locals())