BBS项目表设计

BBS项目表设计


  • CBV添加装饰器

    from django.views import View
    # method_decorator
    
    
    @method_decorator(login_auth, name='get') # 第二种方式
    class IndexView(View):
        @method_decorator(login_auth)  # 第三种方式
        def dispatch(self, request, *args, **kwargs)
        
        @method_decorator(login_auth)  # 第一种方式
        def get(self):
            pass
    
  • csrf跨站请求

    1. form表单
    	{% csrf_token %}
    2.ajax
    # 第一种方式  利用标签查找页面的随机字符串
        data:{
            'username':'zhang',
            'csrfmiddlewaretoken':$('[name=csrfmiddlewaretoken]').val()},
    
    # 第二种方式 利用模板语法
        data:{
            'username':'zhang',
            'csrfmiddlewaretoken': '{{ csrf_token }}'},#}
    # 第三种方式引入一个js文件直接复制就好了
    
    #相关装饰器
    	csrf_protect : 需要验证
        csrf_exempt:不需要验证
        在CBV中,针对csrf_protect三种添加方式都可以
        针对csrf_exempt,第一种方式,第二种方式都不行,第三种方式可以
        
        第一种是在类里函数的上面加装饰器
        第二种是在类上面加装饰器
        第三种是在类里重写父类的dispatch方法 再次方法上面加
    
  • auth模块

    from django.contrib import auth
    1. 登录:
    	auth.authenticate(request)  # 验证用户名和密码是否正确
        '''
        	1. 自动会从auth_user表中查询数据
        	2. 密码自动加密进行比较
        	3. 用户名和密码必须同时传入
        '''
        
        # 保存用户信息
        auth.login(rqeuest, user_obj)  # request.session[key] = user_obj
        '''
        	在全局任何地方,只要是能够拿到request对象的地方,都可以通过request.user取到用户对象
        '''
        
    2. 验证是否登录
    	request.user.is_authenticate()
    3. 验证登录的装饰器
    	@login_required
    4. 修改密码
    	# 验证老密码是否正确
        is_right = request.user.check_password(old_password)
        
        # 修改密码
        request.user.set_password(new_password) # 只是修改了数据属性
        request.user.save()  # 真正的操作数据库
    5. 注销用户
    	auth.logout(request)
        
    6. 注册用户
    	User
        User.objects.create()  # 密码不加密
        User.objects.create_user()  # 密码加密
        
    
    • 扩展auth_user表字段

    # 前提:如果你已经执行了数据库迁移命令,这个时候就不能在扩展auth_user表了
    #       设计表阶段就要明确需不需要扩展表
    from django.contrib.auth.models import User
    1. 扩展auth_user表要继承AbstractUser类
    	auth_user表不会创建出来了 会出现一个新的表
        你的类的名字就是表名
    2. 扩展字段不要动原来的字段,你只需要在继承的类中写你自己想要扩展的字段
    3. 生成一个新表,该表有原来的字段加上你扩展出来的字段
    4. 在settings.py中加个配置:
    	AUTH_USER_MODEL = '应用名.表名'
    5. 扩展表之后,auth_user表就没有了
    

 

  • 需求分析(仿照博客园)

  • 创建数据表(核心)

  • 注册功能

 

  • 需求分析(仿照博客园)

    需要七张表
    1.扩展auth_user表(继承abstractuser)
    	phone     电话
        avatar    头像
        creattime 创建时间
        
     #   外键字段
        blog  一对一   #一对一个人站点表
        
    2.站点表 blog
    	site_name    站点名称
        site_title    站点标题
        site_theme    站点主题  css样式
        
       
     
    3.标签表 
    	name    标签名
        
        外键字段 多个标签对一个站点
        一对多站点表   
        
    4.分类表
    	name   分类名
        
         #外键字段 
        一对多站点表   (多个分类对一个站点)
    
    5.文章表
    	title   	标题
        desc		简介
        content		内容
        create_time	创建时间
        #####优化字段#########
        '''
        	下面这几个字段可以从其他表查询计算得出,但是频繁跨表查询 效率低 所以自己写三个 为了提高效率
        	up_num			点赞数
        	down_num		点踩数
        	comment_num		评论数
        '''
        
       # 外键字段  
        一对多站点表  (多个文章对应一个站点)
        多对多文章标签  (一个文章有多个标签  一个标签有多个文章)
        一对多文章分类   (一个文章一个分类  一个分类多个文章)
        
    6.点赞点踩表 (记录哪个用户给哪篇文章点了赞还是点了踩)
    	user		foreignkey(to='User')
        article		foreignkey(to='Article')
        is_up  		booleanfiled
        
        #外键字段
        id   user    is_up   
        1     1        1		
        2     2  	  0
    
    7.文章评论表(记录哪个用户给那篇文章写了那些评论内容)
    	user				foreignkey(to='User')
        article				foreignkey(to='Article')
        content				评论内容charfiled
        comment_time 		评论时间datafiled
    
    
        #自关联 自己跟自己关联  可以为空
        #parent_id     ForeignKey(to='Comment', null=True)
        #orm提供的专门自关联写法   里面存放的是跟评论的主键值
        parent_id     ForeignKey(to='self', null=True)   
    根评论与子评论的概念
        	# 根评论就是评论这篇文章的
         	# 子评论
            	1. PHP是世界上最好的语言
                	1.1 python才是
                    1.2 你滚蛋
    
  • 创建数据表(核心)

    创建数据库bbs
    settings 配置连接数据库
    #先写普通字段在写外键字段
    from django.db import models
    
    
    from django.contrib.auth.models import AbstractUser
    
    #用户表
    class UserInfo(AbstractUser):
        phone=models.BigIntegerField(verbose_name='手机号',null=True)
        avatar=models.FileField(upload_to='static/img',default='static/img/default.jpg')
        '''
                以后用户上传头像会直接上传到'static/img'路径下
                如果没有上传,使用默认的:static/img/default.png
        '''
        create_time=models.DateTimeField(auto_now_add=True)
        #外键字段 一对一
        blog=models.OneToOneField(to='Blog',null=True)
    
    #站点表
    class Blog(models.Model):
        site_name=models.CharField(verbose_name='站点名称',max_length=32)
        site_title=models.CharField(verbose_name='站点标题',max_length=32)
        #存css或者js文件的路径
        site_theme=models.CharField(verbose_name='站点样式',max_length=64)
    
    
    
    #标签表
    class Tag(models.Model):
        name=models.CharField(verbose_name='文章标签',max_length=32)
        #外键字段 一对多
        blog=models.ForeignKey(to='Blog',null=True)
    
    
    #分类表
    class Category(models.Model):
        name=models.CharField(verbose_name='文章分类',max_length=32)
        # 外键字段 一对多
        blog = models.ForeignKey(to='Blog', null=True)
    
    
    #文章表
    class Article(models.Model):
        title=models.CharField(verbose_name='文章标题',max_length=64)
        desc=models.CharField(verbose_name='文章简介',max_length=255)
        #文章内容比较多一般使用 TextField
        content=models.TextField(verbose_name='文章内容')
        create_time=models.DateField(auto_now_add=True)
        #数据库优化字段
        up_num=models.BigIntegerField(verbose_name='点赞数',default=0)
        down_num=models.BigIntegerField(verbose_name='点踩数',default=0)
        comment_num=models.BigIntegerField(verbose_name='评论数',default=0)
    
        #外键字段
        blog=models.ForeignKey(to='Blog',null=True)#一对多 文章和站点
        category=models.ForeignKey(to='Category',null=True)#一对多 文章和分类表
        tags=models.ManyToManyField(to='Tag',
                                    through='Article2Tag',
                                    through_fields=('article','tag')
                                    )#多对多 文章和标签表
    
    #第三种关系表 manytomany
    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.CharField(verbose_name='评论内容',max_length=512)
        comment_time=models.DateTimeField(verbose_name='评论时间',auto_now_add=True)
        #加null等于True 是因为有些评论就是跟评论,他没有子评论
        parent = models.ForeignKey(to='self', null=True)
    
    
    
  • 注册功能

##views
from django.shortcuts import render
from django.http import JsonResponse
from app01 import models
# Create your views here.

#注册功能
def register(request):
    if request.method == 'POST':
        # 提前定义一个json格式的字典类型 ajax一般返回json格式
        back_dic = {'code': 200, 'msg': '注册成功'}
        ####1.接受参数
        username = request.POST.get('username')
        pwd = request.POST.get('pwd')
        re_pwd = request.POST.get('re_pwd')
        email = request.POST.get('email')
        avatar = request.FILES.get('myfile')

        #2.验证参数 前端验证可有可无   先验证不符合条件的
        if not username:
            back_dic['code']=201
            back_dic['msg']='用户名必须填写'
            return JsonResponse(back_dic)

        if not pwd:
            back_dic['code'] = 202
            back_dic['msg'] = '密码必须填写'
            return JsonResponse(back_dic)

        if not pwd == re_pwd:
            back_dic['code'] = 203
            back_dic['msg'] = '两次密码输入不一致'
            return JsonResponse(back_dic)

        if not email:
            back_dic['code'] = 204
            back_dic['msg'] = '邮箱未填写'
            return JsonResponse(back_dic)

        #3.查询数据库是不是有这个用户名 是否重复
        res=models.UserInfo.objects.filter(username=username).first()
        if res:
            back_dic['code'] = 205
            back_dic['msg'] = '用户已存在'
            return JsonResponse(back_dic)

        #4.头像是否上传   业务逻辑
        data_dic={}
        if avatar:
            data_dic['avatar']=avatar
        data_dic['username'] = username
        import hashlib
        m=hashlib.md5()
        m.update(pwd.encode('utf-8'))
        pwd=m.hexdigest()

        data_dic['password'] = pwd
        data_dic['email'] = email

        #5.入库  **字典打散成关键字参数
        models.UserInfo.objects.create(**data_dic)
        back_dic['url']='/login/'

        return JsonResponse(back_dic)  #返回格式化后的数据



    return render(request, 'register.html')



  • 注册前端页面

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
        <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        {% load static %}
        <script src="{% static 'layer-v3.5.1/layer/layer.js' %}"></script>
        <script src="{% static 'js/mysetup.js' %}"></script>
    
    </head>
    <body>
    <div class="container-fluid">
        <div class="row">
            <h1 class="text-center">注册页面</h1>
            <div class="col-md-8 col-md-offset-2">
                <form action="">
                    {#                {% csrf_token %}#}
                    <div class="form-group">
                        <label for="">用户名</label>
                        <input type="text" id="username" class="form-control">
                    </div>
                    <div class="form-group">
                        <label for="">密码</label>
                        <input type="password" id="pwd" class="form-control">
                    </div>
                    <div class="form-group">
                        <label for="">确认密码</label>
                        <input type="password" id="re_pwd" class="form-control">
                    </div>
                    <div class="form-group">
                        <label for="">邮箱</label>
                        <input type="email" id="email" class="form-control">
                    </div>
                    <div class="form-group">
                        <label for="myfile">头像
                            {% load static %}
                            <img src="{% static 'img/default.jpg' %}" id="myimg" alt="" width="112"
                                 style="margin-left: 30px">
                        </label>
                        <input type="file" id="myfile" class="form-control" style="display: none">
                    </div>
    
                    <input type="button" class="btn btn-success btn-block pull-right" value="注册">
    
                </form>
            </div>
    
        </div>
    
    </div>
    <script>
        //头像实时展示 借助于文件阅读器
        $('#myfile').change(function () {
            //1.创建文件阅读器对象
            var myFileReadobj = new FileReader();
            //2.获取图片数据
            var myImgObj = $('#myfile')[0].files[0];
    
            //3.图片数据交给文件阅读器读取
            myFileReadobj.readAsDataURL(myImgObj)  //这句是异步操作(不等他的结果)  io操作
            //放在onload 方法 等外面代码执行完 在读取里面的
            myFileReadobj.onload = function () {
                //4.改变img的src attr拿某个标签的内部属性
                $('#myimg').attr('src', myFileReadobj.result)
            }
    
    
        })
    
    
        $('.btn').click(function () {
            //前端验证
            var username = $('#username').val();
            var pwd = $('#pwd').val();
            var re_pwd = $('#re_pwd').val();
            var email = $('#email').val();
    
            if (!username) {
                layer.msg('请输入用户名')
                return
            }
            if (!pwd) {
                layer.msg('请输入密码')
                return
            }
            if (!re_pwd) {
                layer.msg('确认密码未输入')
                return
            }
            if (!email) {
                layer.msg('请输入邮箱')
                return
            }
    
    
            var formDataObj = new FormData()
            formDataObj.append('username', username);
            formDataObj.append('pwd', pwd);
            formDataObj.append('re_pwd', re_pwd);
            formDataObj.append('email', email);
            //添加文件数据
            formDataObj.append('myfile', $('#myfile')[0].files[0]);
    
            $.ajax({
                url: '',
                type: 'post',
                //用formdata提交需要指定
                contentType: false,
                processData: false,
                data: formDataObj,
                success: function (args) {
    
                    if (args.code == 200) {
                        layer.msg(args.msg, {icon: 1}, function () {
                            location.href = args.url
                        })
                    } else {
                        layer.msg(args.msg)
                    }
                }
            })
        })
    
    
    </script>
    </body>
    </html>
    
posted @ 2021-12-09 21:15  迪迦张  阅读(37)  评论(0编辑  收藏  举报