【一】BBS项目设计

文章介绍了Django环境下构建BBS系统时的数据库表设计,包括用户、个人站点、文章分类、文章标签、文章、点赞点踩和评论等表的详细字段结构,以及ORM模型的创建,强调了表设计在项目中的重要性并考虑了性能优化。
摘要由CSDN通过智能技术生成

【引入】BBS表设计

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

【1】用户表(UserInfo)

  • 继承 AbstractUser
    • 拓展字段
字段名类型注释
phoneBigIntegerField电话
avatarFileField头像链接
create_timeDateField创建时间
blogOneToOneField(to="Blog")外键字段,一对一,个人站点表

【2】个人站点表(Blog)

字段名类型注释
site_nameCharField站点名称
site_titleCharField站点标题
site_themeCharField站点样式

【3】文章分类表(Category)

字段名类型注释
nameCharField分类名
blogForeignKey(to="Blog")外键字段,一对多,个人站点

【4】文章标签表(CategoryTag)

字段名类型注释
nameCharField标签名

【5】文章表(Article)

字段名类型注释
titleCharField文章标题
descCharField文章摘要/文章简介
contentTextField文章内容
create_timeDateField发布时间
up_numBigIntegerField点赞数
down_numBigIntegerField点踩数
comment_numBigIntegerField评论数
blogForeignKey(to="Blog")外键字段,一对多,个人站点
categoryForeignKey(to="Category")外键字段,多对多,文章标签
tagsManyToManyField(to="CategoryTag")外键字段,一对多,文章分类
  • 虚拟出第三张表作为多对多字段(ArticleToTag)
字段名类型注释
articleForeignKey(to="Article")外键字段,一对多,文章
tagForeignKey(to="CategoryTag")外键字段,一对多,标签
  • 数据库字段设计优化
    • 虽然点赞数、点踩数和评论数都能从单独的表中查询得出
    • 但是频繁地跨表查询效率很低
  • 在上表内增加普通字段记录相关的数据
    • 在下述变动的时候同步更改

【6】点赞点踩表(UpAndDown)

  • 用来记录哪个用户对哪篇文章点了赞还是点了踩
字段名类型注释
userForeignKey(to="UserInfo")用户主键值
articleForeignKey(to="Article")文章主键值
is_upBooleanField()是否点赞

【7】文章评论表(Comment)

  • 用来记录哪个用户给哪篇文章写了哪些评论内容
字段名类型注释
userForeignKey(to='UserInfo')用户主键值
articleForeignKey(to="Article")文章主键值
contentCharField()评论内容
comment_timeDateTimeField评论时间
parentForeignKey(to="self",null=True)自关联
  • 根评论
    • 直接评论当前文章内容
  • 子评论
    • 评论别人的评论
  • 跟评论可以有多个子评论(一对多关系)
# ORM 自带的自关联 写法
ForeignKey(to="self",null=True)

【8】表结构图解

【9】数据库建表

  • 配置文件
    • 修改指定 User
# 默认用户模型指定
AUTH_USER_MODEL = 'book.UserInfo'
  • 数据库配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'bbs_sys', # 需提前创建数据库名
        'USER': 'root', # 自己的用户名
        'PASSWORD': '1314521', # 自己的数据库密码
        'HOST': '127.0.0.1', # 自己的IP
        'PORT': 3306,# 自己的端口
        'CHARSET': 'utf8',
    }
}
  • app下的__init__文件
import pymysql

pymysql.install_as_MySQLdb()
  • 模型类创建
from django.db import models

# Create your models here.
'''
先写普通字段
再写外键字段
'''

from django.contrib.auth.models import AbstractUser, User


# 用户表
class UserInfo(AbstractUser):
    phone = models.BigIntegerField(verbose_name="手机号", help_text="手机号", null=True, blank=True)
    '''
    null=True   数据库该字段可以为空
    blank=True  admin后台管理可以为空
    '''
    avatar = models.FileField(verbose_name="用户头像",
                              help_text="用户头像",
                              upload_to='avatar/',
                              default='book/static/img/default.png')
    # 给avatar字段传文件对象,该文件会自动存储到 avatar 文件夹下,然后avatar字段只保存文件路径  例如 avatar/default.png(不上传文件的默认头像文件)
    create_time = models.DateField(verbose_name="创建时间", help_text="创建时间", auto_now_add=True)

    blog = models.OneToOneField(verbose_name="关联博客", to="Blog", on_delete=models.CASCADE, null=True)

    class Meta:
        verbose_name = "用户表"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.username


# 个人站点表
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)
    site_theme = models.CharField(verbose_name="站点样式", help_text="站点样式", max_length=64)  # css/js的文件路径

    class Meta:
        verbose_name = "个人站点表"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.site_name


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

    blog = models.ForeignKey(verbose_name="关联博客", to="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):
    name = models.CharField(verbose_name="文章标签", max_length=32)
    blog = models.ForeignKey(verbose_name="文章标签关联个人站点mi", to="Blog", null=True, blank=True,
                             on_delete=models.CASCADE)

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

    def __str__(self):
        return self.name


# 文章表
class Article(models.Model):
    title = models.CharField(verbose_name="文章标题", max_length=64)
    desc = models.CharField(verbose_name="文章简介", max_length=255)
    content = models.TextField(verbose_name="文章内容")
    create_time = models.DateField(verbose_name="文章创建时间", auto_now_add=True)
    # 数据库字段设计优化
    up_num = models.BigIntegerField(verbose_name="点赞数", default=0)
    down_num = models.BigIntegerField(verbose_name="点踩数", default=0)
    comment_num = models.BigIntegerField(verbose_name="评论数", default=0)

    blog = models.ForeignKey(verbose_name="关联博客", to="Blog", on_delete=models.CASCADE, null=True)
    category = models.ForeignKey(verbose_name="关联分类", to="Category", on_delete=models.CASCADE, null=True)
    tags = models.ManyToManyField(verbose_name="关联文章和标签",
                                  to="CategoryTag",
                                  through='ArticleToTag',
                                  through_fields=("article", "tag")
                                  )

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

    def __str__(self):
        return self.title


class ArticleToTag(models.Model):
    article = models.ForeignKey(verbose_name="关联文章", to="Article", on_delete=models.CASCADE, null=True)
    tag = models.ForeignKey(verbose_name="关联标签", to="CategoryTag", on_delete=models.CASCADE, null=True)

    class Meta:
        verbose_name = "文章关联标签"
        verbose_name_plural = verbose_name


# 点赞点踩表
class UpAndDown(models.Model):
    user = models.ForeignKey(verbose_name="关联用户", to='UserInfo', on_delete=models.CASCADE)
    article = models.ForeignKey(verbose_name="关联文章", to='Article', on_delete=models.CASCADE)
    is_up = models.BooleanField(verbose_name="是否点赞点踩")

    class Meta:
        verbose_name = "点赞点踩表"
        verbose_name_plural = verbose_name


# 评论表
class Comment(models.Model):
    user = models.ForeignKey(verbose_name="关联用户", to='UserInfo', on_delete=models.CASCADE)
    article = models.ForeignKey(verbose_name="关联文章", to='Article', on_delete=models.CASCADE)
    content = models.CharField(verbose_name="评论内容", max_length=255)
    comment_time = models.DateTimeField(verbose_name="评论时间", auto_now_add=True)
    parent = models.ForeignKey(verbose_name="自关联主评论", to="self", on_delete=models.CASCADE, null=True)  # 有些评论就是根评论

    class Meta:
        verbose_name = "用户评论表"
        verbose_name_plural = verbose_name
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值