BBS需求分析

# 运营部门,销售部门 =》 业务部门
# 产品经理 => 原型图 => 需求评审:测试人员,产品,开发,前端,后端,主管,技术经理
# 什么时候完成,上线?
# 开发... 提测 => 交给测试人员 => 两轮测试 => dev, test, release, master
# git 1. 用户表(扩展auth_user表)
phone
avatar
create_time
# 一对一站点表
blog = OneToOne
2. 站点表
站点名称
站点标题
站点样式: css代码 => 路径
3. 标签表
标题
# 一对多站点表
4. 分类表
分类名称 # 无限级分类
# 一对多站点表
5. 文章表
标题
简介
内容
create_time # 一对多站点表
blog = ForeignKey # 多对多标签表
tags = manytomany # 一对多分类表
cate = ForeignKey '''优化字段'''
up_num # 点赞数
down_num # 点踩数
comment_num # 评论数 6. 点赞点踩表
# 哪个用户点赞了还是点踩了那篇文章
user
article
is_up 0/1
7. 评论表comment
user
article
content
create_time pid = ForeignKey(to='comment') # 自关联外键
pid = ForeignKey(to='self')
'''
根评论和子评论
1. 哥很帅
1.1 确实很帅
1.2 男神
'''
id user article content pid(parent_id)
1 1 1 aa 0
2 2 1 bb 1
3 3 1 cc 1

数据表设计

from django.db import models
from django.contrib.auth.models import AbstractUser # 1. 用户表
class UserInfo(AbstractUser):
phone = models.CharField(max_length=32, verbose_name='手机号') # 头像
avatar = models.FileField(upload_to='static/img', default='static/img/default.png') # 创建时间
create_time = models.DateTimeField(auto_now_add=True) # 2. 站点表
class Blog(models.Model):
site_name = models.CharField(max_length=64, verbose_name='站点名称')
site_title = models.CharField(max_length=64, verbose_name='站点标题')
site_style = models.CharField(max_length=64, verbose_name='站点样式') # 3. 标签表
class Tag(models.Model):
title = models.CharField(max_length=64, verbose_name='标签名称') # 4. 分类表
class Category(models.Model):
title = models.CharField(max_length=64, verbose_name='分类名称') # 5. 文章表
class Article(models.Model):
title = models.CharField(max_length=128, verbose_name='文章标题')
desc = models.CharField(max_length=512, verbose_name='文章简介')
content = models.TextField(verbose_name='文章内容')
create_time = models.DateTimeField(auto_now_add=True) # 外键关系
blog = models.ForeignKey(to='Blog', on_delete=models.CASCADE)
category = models.ForeignKey(to='Category', on_delete=models.CASCADE) # 多对多
tags = models.ManyToManyField(to='Tag',
through='Article2Tag',
through_fields=('article', 'tag')
) # 优化字段
up_num = models.IntegerField(verbose_name='点赞数')
down_num = models.IntegerField(verbose_name='点踩数')
comment_num = models.IntegerField(verbose_name='评论数') class Article2Tag(models.Model):
article = models.ForeignKey(to='Article', on_delete=models.CASCADE)
tag = models.ForeignKey(to='Tag', on_delete=models.CASCADE) # 6. 点赞点踩表
class UpAndDown(models.Model):
user = models.ForeignKey(to='UserInfo', on_delete=models.CASCADE)
article = models.ForeignKey(to='Article', on_delete=models.CASCADE)
# 布尔值, True/False => 1/0
is_up = models.BooleanField() # 7. 评论表
class Comment(models.Model):
user = models.ForeignKey(to='UserInfo', on_delete=models.CASCADE)
article = models.ForeignKey(to='Article', on_delete=models.CASCADE)
content = models.CharField(max_length=512, verbose_name='评论内容')
create_time = models.DateTimeField(auto_now_add=True) # parent_id = models.ForeignKey(to='Comment')
parent = models.ForeignKey(to='self', on_delete=models.CASCADE)

注册页面前端

前端页面:

用户名、密码、确认密码、邮箱、上传头像

提交按钮:

上传头像



示例:

将img放在label标签内,点击图片即可触发上传文件。

使用display:none将上传文件的input标签隐藏。

用户头像展示:

点击label标签触发的不是click事件,而是change事件。

思路1:文件阅读器

由于readAsDataURL是异步操作,所以我们交给文件阅读器的图片还没读完,就执行下一行代码,attr修改标签的src属性为图片数据,所以此时图片不显示。我们希望把异步操作变成同步操作,等待文件阅读器读取完再执行下一行代码。

添加onload事件,等待文件阅读器读取完再执行:

注意:文件阅读器是临时读取,并没有把用户头像上传至后台。(不消耗后端资源)

提交数据 FormData

给按钮绑定点击事件。借助于FormData():

验证数据和追加数据:

追加数据:把获取到的数据放入FormData对象中。

提交ajax:

两行参数:

注意:这两个参数不加ajax请求都没有反应。第二需要把crsf校验给关了。

前端校验layer框:

注意这个layer框需要引入layer前端组件:

注意:layer前端组件需要Jquery的支持。

下载地址:https://layui.gitee.io/v2/docs/

效果:

注册后端逻辑

forms组件尽量不要用,封装好的功能出了故障不好排查。

接受参数

给前端返回的json数据:

导入JsonResponse。

验证参数

后端发现没有用户名时,修改给前端返回的json数据的键值对。修改状态码为1000起步。用JsonResponse返回给前端。

业务状态码:标识某一个错误信息

响应状态码:200响应成功 404找不到文件

示例:

由前缀和业务码组成:

10表示财务相关、20表示用户相关、30表示订单相关。

验证两次密码输入是否一致:

邮箱格式验证:

处理正常的业务逻辑:

将获取的前端数据存放于数据字典中。

验证用户名是否存在:

数据入库

双星号解包字典,变成关键字实参传入create方法。

这里如果业务复杂还需要加事务操作,利用事务原子性,保证数据不会出现添加一半的情况。

还有一个问题,就是使用create方法数据入库时,密码还是明文的,需要处理密码:

如果使用create_user则无法控制加密的方式,也不知道django是怎么加密的。读取的时候,也需要使用auth模块去比对密码。建议:不要使用auth模块,不太方便。

密码加盐操作

导入from django.core import settings

使用的是配置文件中的固定盐:

这个盐也可以自己修改。

返回数据

前端页面ajax回调函数:

如果后端返回的状态码为200,则跳转到登录页面。其他情况则弹出提示信息。通过给location.href赋值,跳转到login页面。

登录页面前端

生成验证码

效果:

验证码前端示例:

随机验证码生成:

到网上下载代码。也可以引入ttf字体文件(修改字体样式)。

安装pillow模块:

导入from PIL import Image,ImageDraw, ImageFont

代码示例:

字体下载:

参数含义:

get_random:生成随机数

img_font:使用我们导入的字体

tmp:随机生成的一个字符

(i * 60 + 60,-2):两个验证码字母之间的距离

存储到session:

开启路由接口:

修改前端页面:

这里的Img标签就可以显示get_code视图函数用Httpresponse返回的验证码图片。

效果:

前端提交数据

前端按钮绑定点击事件:

前端验证:

提交ajax请求:

登录成功之后跳转到首页:

登录后端逻辑

接受参数

验证参数

验证验证码是否正确:

cookies session除了可以记录用户信息,也可以记录验证码信息。之前我们生成的验证码保存在了session表,现在我们拿出来进行比对。

验证码应该是不区分大小写的:

验证用户是否存在:

登录逻辑

获取用户输入的密码,此时密码是明文,需要加密之后再比对:

不要这样写两个校验(不要提供多余的信息,防范恶意破解密码):

不要告知用户到底是用户名不存在,还是用户名与密码匹配不上。

写一个校验就行了:

(企业中的登录不是这么简单,示例:一个登录功能3000行代码)

session表记录用户信息:

id是用户对象在session表中的id值。

session表中数据的过期时间到了之后也不会立即删除。

封装加密函数

加密函数:

使用函数:

BBS项目(一):BBS需求分析 数据表设计 注册登录功能实现的更多相关文章

  1. SpringBoot + Vue + ElementUI 实现后台管理系统模板 -- 后端篇(五): 数据表设计、使用 jwt、redis、sms 工具类完善注册登录逻辑

    (1) 相关博文地址: SpringBoot + Vue + ElementUI 实现后台管理系统模板 -- 前端篇(一):搭建基本环境:https://www.cnblogs.com/l-y-h/p ...

  2. 【原创】C#搭建足球赛事资料库与预测平台(3) 基础数据表设计

            本博客所有文章分类的总目录:http://www.cnblogs.com/asxinyu/p/4288836.html 开源C#彩票数据资料库系列文章总目录:http://www.cn ...

  3. 【原创】C#搭建足球赛事资料库与预测平台(5) 赔率数据表设计1

            本博客所有文章分类的总目录:http://www.cnblogs.com/asxinyu/p/4288836.html 开源C#彩票数据资料库系列文章总目录:http://www.cn ...

  4. 数据表设计之主键自增、UUID或联合主键

    最近在做数据库设计的时候(以MySQL为主),遇到不少困惑,因为之前做数据库表设计,基本上主键都是使用自增的形式,最近因为这种做法,被领导指出存在一些不足,于是我想搞明白哪里不足. 一.MySQL为什 ...

  5. 【原创】C#搭建足球赛事资料库与预测平台(6) 赔率数据表设计2

            本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 开源C#彩票数据资料库系列文章总目录:[目录]C#搭建足球赛事资料库与预测平台与彩票数据分析目录 本篇文章开始将逐步介 ...

  6. 【原创】C#搭建足球赛事资料库与预测平台(4) 比赛信息数据表设计

            本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 开源C#彩票数据资料库系列文章总目录:[目录]C#搭建足球赛事资料库与预测平台与彩票数据分析目录 本篇文章开始将逐步介 ...

  7. PHP 开发 APP 接口 学习笔记与总结 - APP 接口实例 [5] 版本设计分析及数据表设计

    APP 版本升级以及 APP 演示 ① 版本升级分析以及数据表设计 ② 版本升级接口开发以及 APP 演示 /** * version_upgrade 版本升级信息表 */ CREATE TABLE ...

  8. mysql status关键字 数据表设计中慎重使用

    mysql status关键字  数据表设计中慎重使用

  9. 中小型WEB系统权限日志数据表设计

    中小型WEB系统权限日志数据表设计 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjc1MDU3OA==/font/5a6L5L2T/fontsi ...

  10. MySql数据表设计,索引优化,SQL优化,其他数据库

    MySql数据表设计,索引优化,SQL优化,其他数据库 1.数据表设计 1.1数据类型 1.2避免空值 1.3text类型优化 2.索引优化 2.1索引分类 2.2索引优化 3.SQL优化 3.1分批 ...

随机推荐

  1. 自定义Graph Component:1.2-其它Tokenizer具体实现

      本文主要介绍了Rasa中相关Tokenizer的具体实现,包括默认Tokenizer和第三方Tokenizer.前者包括JiebaTokenizer.MitieTokenizer.SpacyTok ...

  2. [编程]UML语言:理论之光与实践之惑

    UML介绍及现状 UML(统一建模语言)是软件工程领域中具有悠久历史的一种模型化语言工具.它通过标准化的图形符号体系,使得软件系统的蓝图能够被更直观地表达出来.UML诞生于20世纪90年代,经过多年积 ...

  3. GPTs大受欢迎但问题多,企服软件厂商的AI Agent更被B端客户器重

    GPTs大受欢迎但问题多,企服软件厂商的AI Agent更被B端客户器重 比尔盖茨预言智能体是下个平台,超自动化平台的AI Agent更靠谱? 以GPTs为代表的AI Agent只是玩具?揭秘真实可用 ...

  4. 3C智能移动周边产品龙头企业如何集成企业内部所有异构系统数据

    全面并自动集成品胜集团全域业务系统中的各类业务数据:结构化.标准化.自动化集团全部异构系统数据,提升全公司整体项目管理水平:梳理与简化跨部门.跨系统流程,清晰定义流程节点及业务边界,打通部门间信息流通 ...

  5. React Hooks 钩子特性

    人在身处逆境时,适应环境的能力实在惊人.人可以忍受不幸,也可以战胜不幸,因为人有着惊人的潜力,只要立志发挥它,就一定能渡过难关. Hooks 是 React 16.8 的新增特性.它可以让你在不编写 ...

  6. springMvc报错

    这个报错困扰了我大概一天,主要是刚开始没抓到主要原因,是因为自己的项目结构出现了问题, 导致找不到应有的东西,另一方面就是maven的问题,将maven解决后这个就能用了. 具体解决在https:// ...

  7. 如何生成core文件进行项目调试

    由于项目前期的调试错误比较多,或者有某些隐藏危险:例如内存泄漏:偶尔才出现一次,如果没有捕捉错误的手段可能好不容易出现的机会就溜走了,所以生成core文件是必要的,发生段错误会生成相应的core文件, ...

  8. 算法那么多,AI量化交易策略如何选择最佳算法?

    常见算法优劣比较 算法没有最好,只有更好. 这个问题的答案取决于许多因素,例如股票市场的条件,数据集的质量和特征工程的有效等.接下来,我们来看看这些算法的优势和劣势: 神经网络:适用于复杂的非线性问题 ...

  9. NetSuite Tips —— 发送邮件未被接收或被退回

    Background: NS 发送的邮件过于频繁被邮箱系统识别为垃圾邮件,被拒收或被拦截 Solution: 添加以下邮箱地址到白名单 system@sent-via.netsuite.com nlm ...

  10. java方法的定义与执行

    java中的方法在类中定义. 定义方法格式: 访问修饰符    返回值类型    方法名(参数列表){   ...  执行内容  ...   return 返回值; } 访问修饰符:表示方法在哪里能被 ...