BBS仿博客园 表分析 注册功能的实现
一、表分析
存在7张表 :
用户表UserInfo
站点表Blog
标签表Tag
分类表Category
点赞表 UpAndDown
评论表 Comment
文章表 Article
用户表 UserInfo 继承django自带的auth组件里的user 表 用户电话 phone 用户头像 avatar 创建时间 create_time
blog 一对一
站点表 Blog 站点名 name 标题 title 主题 theme 存放html样式
标签表Tag 标签名 name blog 一对多 atricle 多对多 创建第三张表,可以实现添加字段的功能
分类表 Category 类名 name blog 一对多
点赞表 UpAndDown
点赞与否 is_up user 一对多 article 一对多
评论表 Comment 内容 content 评论时间 create_time user 一对多 article 一对多 parent 对自己 考虑到对作者评论,对其他用户评论
models.py
from django.db import models from django.contrib.auth.models import AbstractUser class UserInfo(AbstractUser): phone = models.BigIntegerField() create_time = models.DateField(auto_now_add=True) # 该字段会将接受到文件自动存放到avatar文件夹下,只存该文件的路径 比如:avatar/111.png avatar = models.FileField(upload_to='avatar/', default='avatar/default.png') 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) class Tag(models.Model): name = models.CharField(max_length=16) blog = models.ForeignKey(to='Blog', null=True) class Category(models.Model): name = models.CharField(max_length=16) blog = models.ForeignKey(to='Blog', null=True) 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) # 数据库查询优化 comment_num = models.IntegerField() up_num = models.IntegerField() down_num = models.IntegerField() blog = models.ForeignKey(to='Blog', null=True) category = models.ForeignKey(to='Category', null=True) tags = models.ManyToManyField(to='Tag', through='Article_Tag', through_fields=('article', 'tag')) class Article_Tag(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() class Comment(models.Model): user = models.ForeignKey(to='UserInfo') article = models.ForeignKey(to='Article') content = models.CharField(max_length=255) create_time = models.DateField(auto_now_add=True) parent = models.ForeignKey(to='self', null=True)
自定义form组件实现输入信息的初步校核
myform.py
from django import forms from django.forms import widgets from app01 import models class MyForm(forms.Form): username = forms.CharField(max_length=12, min_length=4, label='用户名', widget=widgets.TextInput(attrs={'class': 'form-control'}), error_messages={ 'max_length': '用户名长度最多不超过12位', 'min_length': '用户名长度最短不低于4位', 'required': '用户名不能为空' }) password = forms.CharField(max_length=12, min_length=4, label='密码', widget=widgets.PasswordInput(attrs={'class': 'form-control'}), error_messages={ 'max_length': '密码长度最多不超过12位', 'min_length': '密码长度最短不低于4位', 'required': '密码不能为空' }) re_password = forms.CharField(max_length=12, min_length=4, label='确认密码', widget=widgets.PasswordInput(attrs={'class': 'form-control'}), error_messages={ 'max_length' : '确认密码长度最多不超过12位', 'min_length': '确认密码长度最短不低于4位', 'required': '确认密码不能为空' }) email = forms.EmailField(label='邮箱',widget=widgets.EmailInput(attrs={'class':'form-control'}) ,error_messages={ 'required':'邮箱不能为空', 'invalid': '邮箱格式不正确' }) phone = forms.IntegerField(label='手机号码',widget=widgets.PasswordInput(attrs={'class': 'form-control'}),error_messages={ 'invalid':'请输入正确的手机号码', 'required':'手机号码不能为空' }) def clean_username(self): username = self.cleaned_data.get('username') user_obj = models.UserInfo.objects.filter(username=username).first() if user_obj: self.add_error('username','该账号已经存在!') return username def clean(self): password = self.cleaned_data.get('password') re_password = self.cleaned_data.get('re_password') if password != re_password: self.add_error('re_password','两次密码不一致!') return self.cleaned_data
view.py 下的register
from django.shortcuts import render,HttpResponse,redirect # Create your views here. from app01 import myform from app01 import models from django.http import JsonResponse def register(request): back_dic = {'code':100,'msg':''} form_obj = myform.MyForm() if request.method == 'POST': form_obj = myform.MyForm(request.POST) if form_obj.is_valid(): data = form_obj.cleaned_data #将re_password 去掉 data.pop('re_password') #获取用户上传的文件对象 file_obj = request.FILES.get('myfile') #判断用户是否上传了头像 if file_obj: #往data里添加一组键值 data['avatar'] = file_obj models.UserInfo.objects.create_superuser(**data) back_dic['msg'] = '注册成功' back_dic['url'] = '/login/' else: back_dic['code'] = 101 back_dic['msg'] = form_obj.errors return JsonResponse(back_dic) return render(request,'register.html',locals())
register.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/twitter-bootstrap/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" style="color: #4cae4c"> <h2 class="text-center">注册页面</h2> <form novalidate id="myform" > {% csrf_token %} <div class="form-group"> {% for foo in form_obj %} <label for="{{ foo.auto_id }}" style="margin-top: 10px">{{ foo.label }}</label> {{ foo }} <span class="error pull-right" style="color: #ff7090;margin-top: 10px" ></span> {% endfor %} </div> </form> <div class="form-group"> <label for="id_myfile">大头贴 <img src="/static/img/default.png" alt="" width="80px" style="margin-left: 20px" id="id_img"> </label> <input type="file" name="myfile" id="id_myfile" style="display: none"> </div> <button class="btn btn-success pull-right" id="id_submit">注册</button> </div> </div> </div> <script> $('#id_myfile').change(function () { {#获取上传的文件对象#} let file_obj = this.files[0]; {#生成一个内置对象#} let fileReader = new FileReader(); {#将文件对象传递给内置对象#} fileReader.readAsDataURL(file_obj); {#将读取出的文件对象替换到img标签#} fileReader.onload = function () { {#等待文件阅读器读取完毕再渲染图片#} $('#id_img').attr('src',fileReader.result) } }); {#ajax提交数据#} $('#id_submit').click(function () { {#生成一个Formdata对象#} let formData = new FormData(); {#往Formdata对象中添加键值#} {#下面这行代码很有意思#} $.each($('#myform').serializeArray(),function (index,obj) { formData.append(obj.name,obj.value) }); {#手动添加文件数据#} formData.append('myfile',$('#id_myfile')[0].files[0]); $.ajax({ url:'', type: 'post', data:formData, {#传输文件时指定两个参数#} processData: false, contentType:false, success:function (datas) { if (datas.code == 100){ {#跳到登陆页面#} location.href = datas.url }else{ $.each(datas.msg,function (index,obj) { let targetId = '#id_' + index; {#id_username,id_password#} $(targetId).next().html(obj[0]).parent().addClass('has-error') }) } } }) }); $('input').focus(function () { $(this).next().html('').parent().removeClass('has-error') }) </script> </body> </html>
初步效果:
posted on 2019-06-19 21:59 michael-chang 阅读(285) 评论(0) 编辑 收藏 举报