BBS项目表结构设计
BBS项目涉及的表
# 用户表 (用户信息:用户名、密码、头像等)
# 站点表 (博客名、标题、主题等)
# 文章表 (标题、简介、内容、点赞数评论数等)
# 标签表 (文章标签)
# 分类表 (文章分类)
# 点赞表 (哪个用户给哪篇文章点赞还是点踩)
# 评论表 (哪个用户给哪篇评论的内容、时间、是否是子评论等)
表设计
用户表
- 为了使用auth模块的功能和auth_user表的已存在字段,需要扩展auth_user表
- 同时用户表和站点表一对一关联
标签表&分类表
- 这两个表记录用户站点的博客需要的标签和分类,它俩和站点表都是一对多的关系,即一个站点有多个标签或者分类
点赞表
- 点赞表用于记录用户该文章点赞还是点踩,因此该表有个三个字段
- 外键关联用户表的字段、外键关联文章表的字段、布尔型的字段(是否点赞)
评论表
- 评论表用于记录用户该文章的评论内容,因此该表至少有个四个字段
- 外键关联用户表的字段、外键关联文章表的字段、评论内容和评论时间
- 此外,设计子评论(评论的评论)时,需要再加一个根评论字段关联自己(该字段可以为空),即自关联
文章表
- 文章表需要的字段比较多:普通字段就有文章标题、简介、发布时间、内容等
- 文章需要绑定个人站点、和站点表是一对多的关系,即一个站点有多篇文章(站点用户也就是文章作者)
- 文章需要分类和标签、我们自定义文章和分类是一对多的关系,文章和标签是多对多的关系
- 文章和标签是多对多的关系,这里使用半自动的方式创建第三张关系表,方便日后扩展。
- 另外创建三个普通字段分别记录文章点赞数、点踩数、评论数(虽然可以通过跨表查询获得这三个数字,但频繁的跨表查询效率较低,这是优化数据库查询的一种方式;不过此时注意:需要手动同步更新文章表和点赞表或评论表)
补充:表结构设计时先考虑普通字段再考虑外键关联字段
表结构
代码实现
- 扩展
auth_user
表需要在配置文件配置参数且只能新增额外的字段,不能修改auth_user
表中已经存在的字段。
from django.db import models
from django.contrib.auth.models import AbstractUser
class UserInfo(AbstractUser):
# 扩展auth_user表
phone = models.BigIntegerField(verbose_name='手机号', null=True)
avatar = models.FileField(upload_to='avatar/', default='avatar/default.png')
register_time = models.DateTimeField(auto_now_add=True, verbose_name='注册时间')
blog = models.OneToOneField(to='Blog', null=True) # 此处null为了方便项目初期数据的添加
def __str__(self):
return self.username
class Meta:
verbose_name_plural = '用户表' # 该参数用于设置admin后台管理系统中表名称
class Blog(models.Model):
blog_name = models.CharField(max_length=32, verbose_name='个人站点名')
blog_title = models.CharField(max_length=128, verbose_name='站点标题')
blog_theme = models.CharField(max_length=64, verbose_name='站点样式')
def __str__(self):
return self.blog_name
class Tag(models.Model):
name = models.CharField(max_length=32, verbose_name='标签名')
blog = models.ForeignKey(to='Blog', null=True)
def __str__(self):
return self.name
class Category(models.Model):
name = models.CharField(max_length=32, verbose_name='分类名')
blog = models.ForeignKey(to='Blog', null=True)
def __str__(self):
return self.name
class Article(models.Model):
title = models.CharField(max_length=64, verbose_name='标题')
desc = models.CharField(max_length=256, verbose_name='摘要')
content = models.TextField(verbose_name='文章内容')
publish_time = models.DateTimeField(auto_now_add=True)
# 数据库优化三个字段
up_counts = models.BigIntegerField(verbose_name='点赞数', default=0)
down_counts = models.BigIntegerField(verbose_name='点踩数', default=0)
comment_counts = 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') # 字段顺序:'先自己后别人';这两个字段是表Article2Tag中的两个外键字段
)
def __str__(self):
return self.title
class Article2Tag(models.Model):
article = models.ForeignKey(to='Article')
tag = models.ForeignKey(to='Tag')
class UpDown(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=256, verbose_name='评论内容')
comment_time = models.DateTimeField(auto_now_add=True, null=True, verbose_name='评论时间')
parent = models.ForeignKey(to='self', null=True) # 此处自关联,推荐使用'self'