BBS思路

昨日内容回顾 BBS

项目流程
需求分析
项目设计(架构设计,框架选择,数据库...报价)
分任务开发(小组成员开发)
测试(测试)
交付上线(运行)

 

用户表(AbstractUser)  settings文件一定要告诉django    AUTH_USER_MODEL = 'app01.UserInfo' 
phone
avatar
create_time  

blog 一对一个人站点

 

个人站点(Blog)
site_name
site_title
site_theme

 

分类表
name
blog       一对多个人站点

 

标签表
name
blog       一对多个人站点

文章表
title
desc
content
create_time
# 数据库优化
comment_num
up_num
down_num

blog 一对多个人站点
category 一对多分类表
tag 多对多标签表

 

点赞点踩表
user             一对多用户      
article         一对多文章
is_up             0/1

 

评论表
user             一对多用户      
article         一对多文章
comment
parent           to='self',null=True

 

1.写forms组件
username
password
confirm_password
email
# 局部钩子 校验用户名是否存在
# 全局钩子 校验密码是否一致

 

2.搭建注册页面
1.利用forms组件渲染前端页面,手动添加获取用户头像的input框
2.将img标签放入label中,将input框隐藏
3.利用文件阅读器动态展示用户上传的头像
注意:需要等待文件阅读器读取完毕之后再赋值给src属性,利用onload
4.ajax发送post请求
利用内置对象FormData传递数据
利用form标签序列化数组
手动获取文件对象$('[input="file"]')[0].files[0]
formdata发数据需要手动修改两个参数
processData:false
contentType:false

 

    后端
利用cleaned_data是一个大字典特性,将confirm_password键值去掉
手动获取用户头像,判断用户是否上传头像,再决定要不要放入cleaned_data字典中
利用**{}将字典打散成关键字参数的形式

 

ps:在用ajax做前后端交互的时候通常后端都会实现定义一个字典作为数据交互的媒介

 

ps:img标签src属性可以放文件路径,也可以放文件二进制数据,还可以放url!

 

今日内容
登录
图片验证码

主页搭建
图片相关功能模块
pip3 install pillow

 

django settings文件逻辑
用户配置了就用用户的
用户没有配置就用默认的

 

 

昨日内容回顾

    登录
        1.搭建前端页面(用户名,密码,图片验证码)
        2.图片如何动态生成,实时变化
            1.img标签的src它既可以写文件路径,也可以放图片二进制数据,还可以放url
            2.推导步骤读取本地的图片二进制数据
            3.利用pillow模块动态生成图片(最新是6.0版本,建议使用4.0~5.0)
                from PIL import Image,ImageDraw,ImageFont
                Image.new("RGB",(长,宽),'red')
                Image.new("RGB",(长,宽),(255,255,255))
            4.为了能够让图片的颜色也能动态变化
                import random
                def get_random():
                    return random.randint(0,255),random.randint(0,255),random.randint(0,255)
            5.利用内存管理器模块io
                from io import BytesIO
                io_obj = BytesIO()  # 就当成文件句柄
                img_obj = Image.new("RGB",(长,宽),'red')
                img_obj.save(io_obj,'png')
            6.图片上写字,并生成随机验证码
                1.生成一个画笔对象(将生成好的图片当做参数传入实例化产生对象)
                2.生成一个字体对象(字体文件.ttf,字体大小)
                3.随机验证码(数字+小写字母+大写字母)
                    外层for循环规定验证码的位数
                    内部利用random.choice每次从数字+小写字母+大写字母三个中取一个
                    利用画笔对象往图片上写字(写的位置xy,写的内容,随机颜色数,字体对象)
                4.将生成好的随机验证码保存到session中为了在之后的登录页面中校验用户输入的验证码是否正确
            7.为了页面更加人性化,给展示验证码的图片绑定了点击事件。用户每点一次局部刷新验证码
                利用img标签src属性在放url的时候。一旦url发生变化。会自动出现朝当前url地址请求数据
                

 

 

    3.获取用户输入的用户名 密码 验证码
先校验验证码是否一致(可以不忽略大小写,统一转成小写或大写进行比较)
利用auth模块校验用户名和密码是否正确user_obj = auth.authenticate(username=username,password=password)
利用auth模块记录当前用户登录状态auth.login(request,user_obj)
4.跳转到主页
顶部导航条
右侧根据用户是否登录动态控制展示的内容
当用户登录的情况下展示用户名和更多操作
修改密码
利用auth模块修改密码
request.user.check_password()
request.user.set_password()
request.user.save() # 一定要save()
修改头像
注销
auth.logout(request)
当用户没有登录的情况下展示注册和登录

主页搭建 个人站点 侧边栏 分类展示 标签展示 日期归档 侧边栏筛选功能

文章详情页
文章的点赞点踩

 

django admin后台管理
1.必须是超级用户才可以登录后台管理
createasuperuser
2.需要将模型表注册到对应应用名下的admin.py文件中

 

网站用的静态文件都放在static文件夹下
将用户上传的静态文件单独放在另外一个文件夹(media文件夹下)
media
avater
files
jianli
ziliao

 

第一件事
规定用户上传的文件都统一放到media文件夹下
settings文件中配置用户上传的文件存放位置

第二件事
将media文件夹暴露给外界可以直接访问

media配置
能够制定暴露给用户后端服务器资源文件

MEDIA_ROOT = os.path.join(BASE_DIR,'media') # 用户上传的文件会自动存放到该文件夹并且该文件夹不要你手动创建

手动配置路由
from django.views.static import serve
# 手动配置media文件路径
url(r'^media/(?P<path>.*)',serve,{'document_root':settings.MEDIA_ROOT})

上述配置完,就会将后端media文件夹所有的资源暴露给用户

"""
基于该方法,你可以做到任意暴露后端任何资源给用户
在作死的边缘试探
MEDIA_ROOT = os.path.join(BASE_DIR,'app01') # 用户上传的文件会自动存放到该文件夹并且该文件夹不要你手动创建

url(r'^app01/(?P<path>.*)',serve,{'document_root':settings.MEDIA_ROOT})
上述配置会将后端逻辑代码数据库代码全部暴露给用户,慎重使用
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!FBI warining!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
"""

 

图片防盗链
Referer: https://www.cnblogs.com/ # 标记你上一次是从哪个页面访问过来的

该功能可以再中间件中做
访问频率校验
referer
身份验证

 

日期归档

id       create_time       month
1 2018-06-21       2018-06
2 2019-08-11       2019-08
3 2019-08-21       2019-08
4 2019-03-11       2019-03

-官方提供
from django.db.models.functions import TruncMonth
models.Article.objects
.annotate(month=TruncMonth('create_time')) # Truncate to month and add to select list
.values('month') # Group By month
.annotate(c=Count('id')) # Select the count of the grouping
.values('month', 'c') # (might be redundant, haven't tested) select month and count

 

侧边栏
1.先搭建前端页面
分类
标签
日期归档

如果按照日期归档的时候出错了

 

	2.侧边栏筛选功能
基于已经有了的当前用户所有的文章
进行对应的筛选(利用queryset链式操作)

 内容回顾

    首页搭建
        用户头像展示
            网站使用的静态文件统一都放在static文件夹
            用户上传的静态文件统一放到另外一个文件夹(media)
            # 1.需要在settings文件中配置
                MEDIA_ROOT = os.path.join(BASE_DIR,'media')
                """
                    1.自动创建media文件夹
                    2.用户上传的文件会自动放入其中
                """
            # 2.手动去urls路由层配置
                from django.view.static import serve
                from BBS import settings
                url(r'^media/(?P<path>.*)',serve,{'document_root':settings.MEDIA_ROOT})
                """
                    1.将media文件内所有的资源全部暴露给用户,用户只需要输入具体的文件路径
                    就可以放到文件内容
                """
            # 3.上述配置可以暴露后端任何文件夹的资源
                MEDIA_ROOT = os.path.join(BASE_DIR,'app01')
                from django.view.static import serve
                from BBS import settings
                url(r'^media/(?P<path>.*)',serve,{'document_root':settings.MEDIA_ROOT})
                """
                    1.将media文件内所有的资源全部暴露给用户,用户只需要输入具体的文件路径
                    就可以放到文件内容
                """
        前端头像渲染
            user_obj.avatar  # avatar/111.png
            <img src='/media/{{user_obj.avatar}}/'/>
    个人站点
        url(r'^(?P<username>\w+)/',views.site)
    左侧栏+筛选
        文章分类
            # 统计当前用户每个分类名及分类下的文章数
        文章标签
            # 统计当前用户每个标签名及标签下的文章数
        日期归档
            # 按照年月对文章进行统计
            id       create_time        month
            1          2018-06-21       2018-06
            2          2019-08-11       2019-08
            3          2019-08-21       2019-08
            4          2019-03-11       2019-03
        -官方提供
                from django.db.models.functions import TruncMonth
                models.Article.objects
                .annotate(month=TruncMonth('create_time'))  # Truncate to month and add to select list
                .values('month')  # Group By month
                .annotate(c=Count('id'))  # Select the count of the grouping
                .values('month', 'c')  # (might be redundant, haven't tested) select month and count        
    
    # 1.写三条路由跟分类,标签,日期对应上,让后端能够知道你想按找什么条件进行筛选
    url(r'^(?P<username>\w+)/(?P<condition>category|tag|archive)/(?P<param>.*)/',views.site)
    
    def site(request,username,**kwargs):
        pass
        # 通过判断kwargs是否有值从而决定返回的页面是个人所有文章还是筛选之后的文章

inclusion_tag        
    自定义inclusion_tag完成侧边栏的渲染
        # 1.在对应的应用名下创建一个名为templatetags文件夹
        # 2.在该文件夹内创建一个任意名字的py文件(mytag)
        # 3.在文件中固定先写以下两句
        from django import template
        
        register = template.Library()
        
        @register.inclusion_tag('left_menu.html',name='lm')
        def left_menu(username):
            return {}
    前端页面
        {% load mytag %}
        {% lm xxx %}    

文章详情页
    文章内容其实就是一堆html代码
    文章内容的渲染需要转义
    
点赞点踩
    # 1.先搭建点赞点踩前端样式(直接拷贝博客园样式 把代码和对应的css样式都拷贝过来)
    # 2.给点赞点踩标签(给他们取一个共同的类属性),给这个类属性绑定一个点击事件
    # 3.利用$(this)指代的就是当前被点击对象的特点再通过判断当前被点击点击有没有具体的类属性从而区分是点赞还是点踩
    # 4.发送ajax请求
        """
        后端应该单独开一个专门处理点赞点踩逻辑的视图函数(因为点赞点踩后端逻辑比较复杂)
        """
    后端
    """
        1.先校验当前用户是否登录
        2.当前用户点击的文件是否是自己写的
        3.判断当前用户是否已经点过了
        4.记录的数据一定要在两个地方进行修改,保持数据的一致性
    """
文章评论
    文章的根评论
        1.前端页面渲染(用户评论框)
        2.后端评论逻辑
        3.前端渲染评论列表
            render渲染
            bom渲染
    文章的子评论
        1.前端渲染评论列表
            render渲染
            bom渲染
        1.点击回复按钮发生了几件事
            1.把你想评论的那条评论的人名自动添加到textarea中(@+用户名)
            2.自动换行
            3.textarea自动聚焦
            
        2.注意给回复按钮绑定点击事件的时候,尽量不要用id,因为回复按钮不止一个,而标签id是不能重复的
    
        3.获取评论人名及评论id的时候,可以利用标签可以支持自定义任意的属性来帮你快速的存储及获取数据
        
        4.子评论在存储的时候应该将@人名清除
        
        5.一定要将全局的根评论id清空
昨日内容回顾
    评论
        根评论
            1.渲染前端评论框,让用户可以输入    
                判断用户是否登录从而控制评论框的显影展示
            2.点击提交评论按钮,触发ajax请求需要你做哪些
                将文章id,评论内容,csrfmiddlware携带到后端
                将评论框中的内容清空
            3.后端视图函数
                首先应该先校验当前用户是否登录
                修改评论相关的数据的时候一定要注意是两个地方同时修改
                利用事务进行数据修改,保证数据的一致性
                from django.db import transaction
                with transaction.atomic():
                    # 在该代码块中就是一个事务操作
                ps:由于parent字段可以为空,所以无需考虑子评论
            4.评论的两种渲染方式
                render渲染
                    1.将当前文章所对应的评论全部查询出来,传递给前端页面
                    2.前端利用for循环动态渲染评论楼
                        利用forloop渲染楼层
                bom操作渲染
                    1.获取当前用户的用户名及用户评论的内容
                    2.通过dom操作动态渲染到页面上(临时)
                        动态添加标签可以利用模板字符串      `${}`
                        查找ul标签append子元素
        子评论
            1.点击回复按钮发生的几件事
                1.在评论框中自动添加@+用户名
                2.自动换行(\r\n)
                3.评论框自动聚焦$('input').focus()
    2.根评论与子评论唯一的区别就在于有没有parent这个参数
            回复按钮的绑定事件与提交评论按钮绑定的事件中都需要用到parentId
            所以应该将parentId设置为"全局变量"
            
        3.后端parent字段默认为空,如果你传的参数是空,不影响该字段正常存储数据
            先设置parentId为空
            点击回复按钮需要做的事儿
                需要拿到被回复评论的人名,及被评论的id
                利用标签可以设置任意的自定义属性
                在渲染评论楼的时候给回复按钮添加两个自定义的属性username,comment.pk
                通过属性操作获取当前回复所存储两个值
                    username是用来帮助你bom动态渲染页面
                    comment.pk要发送到后端

4.后端只需要获取parentId参数,在添加数据新增一个parent_id参数即可
至此后端代码无需再做任何改动

 
    5.提交子评论功能优化
            1.将@+人名去除,不要存入数据库中
                由于子评论第一行就是@+人名
                利用indexOf()获取到最后一个\n对应的索引值
                又由于索引切片是顾头不顾尾,所以要在获取到的索引值基础上再加一
                再利用slice切去真正用户输入的内容
            
            2.当用户点击回复按钮评论一条子评论的时候,如果页面不刷新后续的评论都将会是子评论
                在用户点击回复按钮成功提交子评论之后,需要将全局的parentId重新置为空
3.render渲染的时候
                针对子评论需要渲染当前子评论所对应的父评论的人名
                    前端通过comment.parent判断评论是否是子评论
                    通过comment.parent.user.username拿到当前子评论所对应的父评论的人名
后台管理
    对文章的增删改查
        只有登录的用户才够进入用户自己的后台管理页面
            利用login_required装饰器限制用户能否正常访问
        
        后台首页搭建
            
            添加文章
                后台富文本编辑器的使用
            
            xss攻击
            
            文章简介的截取
            
            bs4模块简介
            
            上传图片
            
            修改用户头像
添加文章小bug:    
1.文章简介不能直接截取文本内容,应该先获取到文本内部的文字,然后再截取(?)
    2.xss脚本攻击如何避免(?)
        博客园处理xss
            1.在前端先将你的写的敏感的标签自动添加一些内容
            2.在后端处理的时候直接将敏感的标签直接删除

        我们处理的方式遇到script标签直接删除,这里的script标签是原生的html标签而不是用户输入的文本中的标签
3.如何查找用户提交的文章里面所有的html标签?如何删?如何去除所有标签只拿文本值?

修改头像需要注意的是
不要用queryset取修改
用对象修改即可

bs4的安装 需要注意的是版本问题,不要下载beautifulsoup 要下载beautifulsoup4

posted @ 2021-12-13 16:00  甜甜de微笑  阅读(40)  评论(0编辑  收藏  举报