【引入】BBS_2.0表设计

发布时间 2023-07-24 20:29:32作者: Chimengmeng

【引入】BBS表设计

  • 一个项目最最最重要的不是业务逻辑的书写
  • 而是前期的表设计,只要将表设计好,后续的功能就会相对顺利一些

【1】用户表(User)

  • 继承 AbstractUser
    • 拓展字段
字段名 类型 注释
phone BigIntegerField 电话
avatar FileField 头像链接
create_time DateField 创建时间
update_time DateTimeField 信息更新时间
is_deleted DateTimeField 是够被删除(注销)
blog OneToOneField 外键字段,一对一,个人站点表

【2】个人站点表(Blog)

字段名 类型 注释
site_name CharField 站点名称
site_title CharField 站点标题
site_theme CharField 站点样式
create_time DateField 创建时间
update_time DateTimeField 信息更新时间

【3】广告信息表(Adv)

字段名 类型 注释
title CharField 广告标题
content CharField 广告详细内容
mobile CharField 广告联系手机号
create_time DateField 创建时间
update_time DateTimeField 信息更新时间
img ImageField 广告投放图片

【4】文章分类表(CategoryCls)

字段名 类型 注释
name CharField 分类名
blog ForeignKey 外键字段,一对多,分类关联站点

【4】文章标签表(CategoryTag)

字段名 类型 注释
tag_name CharField 标签名
blog ForeignKey 标签关联博客

【5】文章表(Article)

字段名 类型 注释
title CharField 文章标题
desc CharField 文章摘要/文章简介
content TextField 文章内容
create_time DateField 发布时间
update_time DateField 更新时间
up_num BigIntegerField 点赞数
down_num BigIntegerField 点踩数
comment_num BigIntegerField 评论数
blog ForeignKey 外键字段,一对多,文章关联站点
category ForeignKey 外键字段,多对多,文章关联标签
tags ManyToManyField 外键字段,一对多,文章关联分类
  • 数据库字段设计优化

    • 虽然点赞数、点踩数和评论数都能从单独的表中查询得出
    • 但是频繁地跨表查询效率很低
  • 在上表内增加普通字段记录相关的数据

    • 在下述变动的时候同步更改

【6】点赞点踩表(UpAndDown)

  • 用来记录哪个用户对哪篇文章点了赞还是点了踩
字段名 类型 注释
user ForeignKey 互动关联个人
article ForeignKey 互动关联文章
up_or_down BooleanField() 点赞/点踩,1为点赞
create_time DateField 创建时间
update_time DateTimeField 信息更新时间

【7】文章评论表(Comment)

  • 用来记录哪个用户给哪篇文章写了哪些评论内容
字段名 类型 注释
user ForeignKey 评论关联个人
article ForeignKey 评论关联文章
content CharField 评论详细内容
parent ForeignKey 自关联
create_time DateField 创建时间
update_time DateTimeField 信息更新时间
is_deleted BooleanField 评论是否被删除,1为存在
  • 根评论
    • 直接评论当前文章内容
  • 子评论
    • 评论别人的评论
  • 跟评论可以有多个子评论(一对多关系)
# ORM 自带的自关联 写法
ForeignKey(to="self",null=True)

【8】表结构图解

表结构图解

【9】数据库建表

版本选择

# Django版本 - Django4.x+ 不支持低版本数据库
django			  3.2
# 链接数据库
mysqlclient       2.2.0
# 兼容 ImageField 字段
Pillow            10.0.0
# mysql数据库
PyMySQL           1.1.0

配置文件

  • 修改指定 User
# 指定默认用户模型表
AUTH_USER_MODEL = 'user.User'

数据库配置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'bbs_sys_2.0',
        'HOST': "127.0.0.1",
        "PORT": 3306,
        "USER": "root",
        "PASSWORD": "1314521",
        "CHARSET": "utf8",
    }
}

模型类创建

用户表

from django.db import models

# Create your models here.
# Django中自带的用户认证模型
from django.contrib.auth.models import AbstractUser


# 定义用户信息表
class User(AbstractUser):
    '''
    用户表
    继承基础模型:创建时间/更新时间/用户删除标记
    '''
    mobile = models.CharField(verbose_name="手机号", help_text="手机号", max_length=11,
                              default="", blank=True)
    avatar = models.ImageField(verbose_name="用户头像", help_text="用户头像",
                               upload_to="avatar/", default="static/img/default.png")
    create_time = models.DateTimeField(verbose_name="创建时间", help_text="创建时间", auto_now=True)
    update_time = models.DateTimeField(verbose_name="更新时间", help_text="更新时间", auto_now_add=True)
    is_deleted = models.BooleanField(verbose_name="删除标记", help_text="删除标记", default=False)

    # 用户的个人站点展示
    blog = models.OneToOneField(verbose_name="用户关联个人站点", to="blog.Blog", on_delete=models.CASCADE, null=True)

    class Meta:
        db_table = 'user'
        verbose_name = '用户表'
        verbose_name_plural = verbose_name

个人站点表

# 个人站点表
class Blog(models.Model):
    site_name = models.CharField(verbose_name="个人站点名称", help_text="个人站点名称", max_length=32)
    site_title = models.CharField(verbose_name="个人站点标题", help_text="个人站点标题", max_length=32)
    create_time = models.DateTimeField(verbose_name="创建时间", help_text="创建时间", auto_now=True)
    update_time = models.DateTimeField(verbose_name="更新时间", help_text="更新时间", auto_now_add=True)
    # css/js 文件的存储路径
    site_theme = models.CharField(verbose_name="个人站点样式", help_text="个人站点样式", max_length=64)

    class Meta:
        db_table = 'blog'
        verbose_name = '个人站点表'
        verbose_name_plural = verbose_name

广告信息表

# 广告信息表
class Adv(models.Model):
    title = models.CharField(verbose_name="广告标题", help_text="广告标题", max_length=64)
    content = models.TextField(verbose_name="广告详细内容", help_text="广告详细内容")
    create_time = models.DateTimeField(verbose_name="创建时间", help_text="创建时间", auto_now=True)
    update_time = models.DateTimeField(verbose_name="更新时间", help_text="更新时间", auto_now_add=True)
    mobile = models.CharField(verbose_name="手机号", help_text="手机号", max_length=11,
                              default="", blank=True)
    img = models.ImageField(verbose_name="广告图片", help_text="广告图片",
                            upload_to="advImg/", default="")

文章分类表

# 文章分类表
class CategoryCls(models.Model):
    name = models.CharField(verbose_name="文章分类名称", max_length=32)

    # 文章的分类关联博客
    blog = models.ForeignKey(verbose_name="分类关联博客", help_text="分类关联博客",
                             to="blog.Blog", on_delete=models.CASCADE,
                             null=True)

    class Meta:
        verbose_name = '文章分类表'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

文章标签表

# 文章标签表
class CategoryTag(models.Model):
    tag_name = models.CharField(verbose_name="文章标签名称", max_length=32)

    # 文章的分类关联博客
    blog = models.ForeignKey(verbose_name="标签关联博客", help_text="分类关联博客",
                             to="blog.Blog", on_delete=models.CASCADE,
                             null=True)

    class Meta:
        verbose_name = '文章标签表'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.tag_name

文章表

# 文章表
class Article(models.Model):
    title = models.CharField(verbose_name="文章标题", help_text="文章标题", max_length=64)
    create_time = models.DateTimeField(verbose_name="创建时间", help_text="创建时间", auto_now=True)
    update_time = models.DateTimeField(verbose_name="更新时间", help_text="更新时间", auto_now_add=True)
    desc = models.CharField(verbose_name="文章简介", help_text="文章简介", max_length=255)
    content = models.TextField(verbose_name="文章详细内容", help_text="文章详细内容")
    up_num = models.BigIntegerField(verbose_name="点赞数", help_text="点赞数", default=0)
    # 文章创建时间 - create_time - BaseModel
    # 文章修改更新时间 - update_time - BaseModel
    # 文章是否删除 - is_deleted - BaseModel
    down_num = models.BigIntegerField(verbose_name="点踩数", help_text="点踩数", default=0)
    comment_num = models.BigIntegerField(verbose_name="评论数", help_text="评论数", default=0)

    # 文章关联个人站点
    blog = models.ForeignKey(verbose_name="文章关联个人", help_text="文章关联个人", to="blog.Blog",
                             on_delete=models.CASCADE, null=True)
    # 文章关联文章标签
    category = models.ForeignKey(verbose_name="文章关联标签", help_text="文章关联标签", to="CategoryTag",
                                 on_delete=models.CASCADE, null=True)
    # 文章关联文章分类
    tags = models.ForeignKey(verbose_name="文章关联分类", help_text="文章关联分类", to="CategoryCls",
                             on_delete=models.CASCADE, null=True)

    class Meta:
        verbose_name = "文章表"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.title

点赞点踩表

# 点赞点踩表
class UpAndDown(models.Model):
    # 互动关联个人
    user = models.ForeignKey(verbose_name="互动关联个人", help_text="互动关联个人", to="user.User",
                             on_delete=models.CASCADE)
    # 互动关联文章
    article = models.ForeignKey(verbose_name="互动关联文章", help_text="互动关联文章", to="Article",
                                on_delete=models.CASCADE)
    # 互动创建时间 - create_time - BaseModel
    create_time = models.DateTimeField(verbose_name="创建时间", help_text="创建时间", auto_now=True)
    update_time = models.DateTimeField(verbose_name="更新时间", help_text="更新时间", auto_now_add=True)
    # 点赞还是点踩
    up_or_down = models.BooleanField(verbose_name="点赞或点踩", help_text="点赞或点踩,1为赞0为踩")

    class Meta:
        verbose_name = "互动表"
        verbose_name_plural = verbose_name

评论表

# 评论表
class Comment(models.Model):
    user = models.ForeignKey(verbose_name="评论绑定个人", help_text="评论绑定个人", to="user.User",
                             on_delete=models.CASCADE)
    article = models.ForeignKey(verbose_name="评论关联文章", help_text="评论关联文章", to="Article", on_delete=models.CASCADE)
    content = models.CharField(verbose_name="评论内容", help_text="评论内容", max_length=255)
    # 评论创建时间 - create_time - BaseModel
    # 评论是否删除 - is_deleted - BaseModel
    create_time = models.DateTimeField(verbose_name="创建时间", help_text="创建时间", auto_now=True)
    update_time = models.DateTimeField(verbose_name="更新时间", help_text="更新时间", auto_now_add=True)
    is_deleted = models.BooleanField(verbose_name="删除标记", help_text="删除标记", default=False)
    # 子评论关联自己 - 允许为空
    parent = models.ForeignKey(verbose_name="子评论", help_text="子评论", to="self", on_delete=models.CASCADE,
                               null=True)

    class Meta:
        verbose_name = "评论表"
        verbose_name_plural = verbose_name