项目需求分析:
项目需求分析 项目需求(产品经理,架构师,开发组组长) 项目设计(框架的选择,数据库的选择,主要功能模块) 报价(工期,开发人员工资) 任务分发(开发组长>>>小弟开发) 测试(本地测试+测试人员测试) 交付上线
BBS项目分析
表设计
用户表(UserInfo) 用户电话phone 用户头像avatar 用户创建时间create_time blog 》》》site 一对一个人站点表 个人站点表(Blog) 站点名称site_name 站点标题site_title 站点样式site_theme 文章标签表(Tag) 标签名称name blog >>> Blog 一对多个人站点表 文章分类表 分类名称name blog >>> Blog 一对多个人站点表 文章表 文章标题title 文章简介desc 文章详情content 文章发布时间create_time # 数据库查询优化 文章评论数comment_num 文章点赞数up_num 文章点踩数down_num blog >>> Blog 一对多个人站点表 tags >>> Tag 多对多标签表 category >>> Category 一对多分类表 点赞点踩表 用户名字段user 一对多 个人站点/用户 文章字段article 一对多 文章表 点赞点踩is_up 0/1 文章评论表 用户名字段user 一对多 个人站点/用户 文章字段article 一对多 文章表 评论内容content 父评论parent(自己跟自己关联) 一对多自身
第一步:models.py(我们先创建好表格)
注意:UserInfo继承的是auth模块中的表,然后又新增了自己的字段,需要在settings里配置:AUTH_USER_MODEL = 'app01.UserInfo'
from django.db import models from django.contrib.auth.models import AbstractUser
# UserInfo继承的是auth模块中的表,然后又新增了自己的字段,需要在settings里配置:AUTH_USER_MODEL = 'app01.UserInfo' class UserInfo(AbstractUser): phone = models.BigIntegerField(null=True) 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=64) # 个人站点的样式文件,存该样式文件的路径 theme = models.CharField(max_length=64) class Category(models.Model): name = models.CharField(max_length=32) blog = models.ForeignKey(to='Blog', null=True) class Tag(models.Model): name = models.CharField(max_length=32) 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='Article2Tags', through_fields=('article', 'tag')) class Article2Tags(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)
第二步:创建表之后,我们需要利用forms组件进行数据校验,在应用名下新建myforms.py文件
from django import forms from django.forms import widgets from app01 import models class MyForm(forms.Form): username = forms.CharField(max_length=8, min_length=3, label='用户名', error_messages={ 'required': '用户名不能为空', 'max_length': '用户名最大8位', 'min_length': '用户名最小3位', }, widget=widgets.TextInput(attrs={'class': 'form-control'})) password = forms.CharField(max_length=8, min_length=3, label='密码', error_messages={ 'required': '密码不能为空', 'max_length': '密码最大8位', 'min_length': '密码最小3位', }, widget=widgets.PasswordInput(attrs={'class': 'form-control'})) re_password = forms.CharField(max_length=8, min_length=3, label='确认密码', error_messages={ 'required': '确认密码不能为空', 'max_length': '确认密码最大8位', 'min_length': '确认密码最小3位', }, widget=widgets.PasswordInput(attrs={'class': 'form-control'})) email = forms.CharField(label='邮箱', error_messages={ 'required': '邮箱不能为空', 'invalid': '邮箱格式不正确', }, widget=widgets.EmailInput(attrs={'class': 'form-control'})) # 局部钩子校验用户名是否存在 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 not password == re_password: self.add_error('re_password', '两次密码不一致') return self.cleaned_data