简单实现BBS注册与登录

一. 数据库的表设计

数据库表设计
    用户表(利用auth_user, 额外扩张几个字段,不用添加auth_user原表里的字段)
    phone  
    avatar
    create_time
 
     blog   # 一对一个人站点表     用户表与个人站点表
    
    个人站点表
    site_name  # 站点名称
    site_title   # 每个人站点的名言警句,随便写的
    site_theme  # 站点的样式,  存css的路径
    # 个人站点表经常不会出现外接字段
    标签表   # 存到底有几个标签,名字是谁呢
     name
     blog   # 与个人站点表是一对多的关系,每个站点看似有多个标签,每个标签看似在每个站点都有,实则不是,标签虽然名字一样,但是是不同的人创建的
    分类表
     name
     blog   # 一对多个人站点
    文章表
     title
     desc  # 文章摘要,独白
     content   # 文章内容
     create_time   # 发布时间
     blog   # 文章和个人站点一对多
     tag   # 多对多
     category   #  文章分类, 一对多的关系
如果想统计某个文章的点赞点踩数, 到个人站点有好多文章,如果我们要跨表查询的话,无疑是给数据库增加压力,那我们可以在文章表里建几个普通字段
     # 数据库设计优化
     comment_num      # 普通字段
     up_num     # 普通字段
     down_num   # 普通字段
建立这几个普通字段,我们可以和点赞点踩表,评论表开个事务,之后在想看评论数的话直接点comment_num就可以拿到评论数,不再需要跨表查

    点赞点踩表
     user       # 一对多用户表
     article     # 一对多文章表
     is_up
     针对点赞来说,赞可以有多个人来点,赞对人来说是一对多的关系
    评论表
    user  #  一对多用户表
    article  # 一对多文章表
    comment  # 评论的内容
    create_time   
    parent     #     一对多评论表 ,自己跟自己关联      根评论,子评论    这个是根评论的id   如果有值说明是子评论, 如果没值就是根评论 

 

数据库同步

  models里面的配置

 1 from django.db import models
 2 from django.contrib.auth.models import AbstractUser
 3 # Create your models here.
 4 class UserInfo(AbstractUser):
 5     phone = models.BigIntegerField(null=True)
 6     # avatar存的是用户头像文件路径 用户上传的头像会自动保存到avatar文件夹下
 7     avatar = models.FileField(upload_to='avatar/',default='avatar/default.jpg')
 8     create_time = models.DateField(auto_now_add=True)
 9 
10     blog = models.OneToOneField(to='Blog',null=True)   # 用户创建出来可以不绑定主页
11 
12 
13 class Blog(models.Model):
14     site_title = models.CharField(max_length=32)
15     site_name = models.CharField(max_length=32)
16     site_theme = models.CharField(max_length=255)
17 
18 
19 class Category(models.Model):
20     name = models.CharField(max_length=32)
21     blog = models.ForeignKey(to='Blog')
22 
23 
24 class Tag(models.Model):
25     name = models.CharField(max_length=32)
26     blog = models.ForeignKey(to='Blog')
27 
28 
29 class Article(models.Model):    # 多对多的时候建议用第三个方法也就是半自动化创建第三张表
30     title = models.CharField(max_length=255)
31     desc = models.CharField(max_length=255)
32     content = models.TextField()  # 存大段文本
33     create_time = models.DateField(auto_now_add=True)
34 
35     # 数据库优化字段
36     comment_num = models.IntegerField(default=0)
37     up_num = models.IntegerField(default=0)
38     down_num = models.IntegerField(default=0)
39 
40     # 外键字段
41     blog = models.ForeignKey(to='Blog',null=True)
42     category = models.ForeignKey(to='Category',null=True)
43     tag = models.ManyToManyField(to='Tag',through='Article2Tag',through_fields=('article','tag'))
44 
45 class Article2Tag(models.Model):
46     article = models.ForeignKey(to='Article')
47     tag = models.ForeignKey(to='Tag')
48 
49 
50 class UpAndDown(models.Model):
51     user = models.ForeignKey(to='UserInfo')
52     article = models.ForeignKey(to='Article')
53     is_up = models.BooleanField()  # 传布尔值  存0/1
54 
55 
56 class Comment(models.Model):
57     user = models.ForeignKey(to='UserInfo')
58     article = models.ForeignKey(to='Article')
59     content = models.CharField(max_length=255)
60     create_time = models.DateField(auto_now_add=True)
61     parent = models.ForeignKey(to='self',null=True)
模型层代码

 

注册功能

 1 from django import forms
 2 from django.forms import widgets
 3 from app01 import models
 4 
 5 
 6 class MyRegForm(forms.Form):
 7     username = forms.CharField(max_length=8, min_length=3, label='用户名',
 8                                error_messages={
 9                                    'max_length': '用户名最大八位',
10                                    'min_length': '用户名最小三位',
11                                    'required': '用户名不能为空'
12                                }, widget=widgets.TextInput(attrs={'class': 'form-control'})
13                                )
14     password = forms.CharField(max_length=8, min_length=3, label='密码',
15                                error_messages={
16                                    'max_length': '密码最大八位',
17                                    'min_length': '密码最小三位',
18                                    'required': '密码不能为空'
19                                }, widget=widgets.PasswordInput(attrs={'class': 'form-control'})
20                                )
21     confirm_password = forms.CharField(max_length=8, min_length=3, label='确认密码',
22                                        error_messages={
23                                            'max_length': '确认密码最大八位',
24                                            'min_length': '确认密码最小三位',
25                                            'required': '确认密码不能为空'
26                                        }, widget=widgets.PasswordInput(attrs={'class': 'form-control'})
27                                        )
28     email = forms.EmailField(label='邮箱', error_messages={
29         'required': "邮箱不能为空",
30         'invalid': "邮箱格式错误"
31     }, widget=widgets.EmailInput(attrs={'class': 'form-control'}))
32 
33     # 局部钩子 校验用户名是否已存在
34     def clean_username(self):
35         username = self.cleaned_data.get('username')
36         is_user = models.UserInfo.objects.filter(username=username)
37         if is_user:
38             self.add_error('username', '用户名已存在')
39         return username
40 
41     # 全局钩子 校验密码是否一致
42     def clean(self):
43         password = self.cleaned_data.get('password')
44         confirm_password = self.cleaned_data.get('confirm_password')
45         if not password == confirm_password:
46             self.add_error('confirm_password', '两次密码不一致')
47         return self.cleaned_data
form组件代码

前端代码:

  1 
  2 "en">
  3 
  4     "UTF-8">
  5     Title
  6     
  7     {% load static %}
  8     "stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
  9     
 10 
 11 
 12 
class="container"> 13
class="row"> 14
class="col-md-8 col-md-offset-2"> 15

class="text-center">注册

16 {# novalidate是告诉前端不要让前端去校验#} 17
"myform" novalidate> 18 {% csrf_token %} 19 {% for foo in form_obj %} 20
class="form-group"> 21 {#foo.auto_id获取foo渲染的input框的id值,效果就是在标签上点动就会在input框里有光标在晃动#} 22 23 {{ foo }} 24 class="errors pull-right" style="color: red;"> 25
26 {% endfor %} 27 {# form-group的效果就是让input框的距离稍远一点,不加的话就两个input框就会挨的近一点#} 28
class="form-group"> 29 33 {# 将选择文件的那几个字消失#} 34 "file" name="avatar" id="myfile" style="display: none"> 35
36 "button" class="btn btn-primary pull-right" value="注册" id="id_submit"> 37
38
39
40
41 42 103 104
前端代码

后端代码:

 1 from django.shortcuts import render,HttpResponse
 2 from django.http import JsonResponse
 3 from app01 import myforms
 4 from app01 import models
 5 from django.contrib import auth
 6 # Create your views here.
 7 
 8 
 9 def register(request):
10     form_obj = myforms.MyRegForm()
11     if request.method == 'POST':
12         back_dic = {'code':100,'msg':''}
13         # 校验用户信息是否合法
14         form_obj = myforms.MyRegForm(request.POST)
15         if form_obj.is_valid():
16             clean_data = form_obj.cleaned_data  # clean_data = {'username':'','password':'','confirm_password':'','email':''}
17             clean_data.pop('confirm_password')  # clean_data = {'username':'','password':'','email':''}
18             # 手动获取用户头像
19             user_file = request.FILES.get('myfile')
20             if user_file:  # 一定要判断用户是否传头像了 如果传了才往字典里面添加  没传不用添加 因为有默认
21                 clean_data['avatar'] = user_file
22             # 创建数据
23             models.UserInfo.objects.create_user(**clean_data)
24             back_dic['msg'] = '注册成功'
25             back_dic['url'] = '/login/'
26         else:
27             back_dic['code'] = 101
28             back_dic['msg'] = form_obj.errors   # 数据不合法,错误数据全都在errors里面,将全部错误信息返回前端
29         return JsonResponse(back_dic)   # ajax通常返回的都是一个字典,先在上面定义一个字典
30 
31     return render(request,'register.html',locals())
后端代码

 

 

 

 

 

 

 

 

 

 

  

转载于:https://www.cnblogs.com/panshao51km-cn/p/11593317.html

你可能感兴趣的:(简单实现BBS注册与登录)