4.1 构建POST应用需要的数据集
2025-02-17
4.1.1 post应用的Models定义
本项目中post的功能
- 用户在BBS站内发表话题,称为:Topic
- 可以针对每一个Topic发表评论,称为:Comment
- 可以对每一个Comment支持或者反对
由于每一个数据表对应一个Model定义,每一个Model都是一个Python类,所以Model之间是可以继承的
Django规定:所有的Model都必须继承自django.db.models.Model.
可以直接继承,或者间接及成果
Model中的所有字段都是
django.db.models.Field的子类Django会根据Field的类型确定数据库表的字段类型
Django内置了数十种Field字段类型,不同的类型支持的参数不一定相同
- 但名字,帮助文本,唯一性等参数都是通用的
在post应用的models.py文件中定义抽象的Model基类:
from django.db import models # Create your models here. class BaseModel(models.Model): """ post 应用中的Model 基类 """ class Meta: abstract = True ordering = ['-created_time'] created_time = models.DateTimeField(auto_now_add=True,help_text=u'创建时间') last_modified = models.DateTimeField(auto_now=True,help_text=u'修改时间') def __str__(self): raise NotImplementedError- 代码解析
- 定义了两个类属性create_time和last_modified,都是DateTimeField类型,继承自BaseModel的类自动拥有这两个属性
- 定义的两个类属性用到了三个Field参数:
- auto_now_add: 用于将首次创建对象时间设置为当前时间
- auto_now:用于将每次保存对象时间设置为当前时间
- help_text:解释性的帮助文本
- 定义了抽象方法__str__,继承自BaseModel的类必须实现这个方法,作用是:能够优化打印Model实例的样式
- 内部类Meta
- abstract:声明了这个是抽象类,不能是实例化,表现为BaseModel不会创建数据表
- ordering:声明了排序的规则
- created_time:代表按照创建时间正序排列,负号标识按照创建时间逆序排序
- BaseModel定义了两个DateTimeField类型的相关字段,会根据不同的数据存储后端选择对应的数据库字段类型
BaseModel直接继承自django.db.models.Model,所以,Topic和Comment可以继承自BaseModel,从而实现间接继承
Topic
class Topic(BaseModel): """ BBS论坛发布的话题 """ title = models.CharField(max_length=255, unique=True, help_text='话题标题') content = models.TextField(help_text='话题内容') is_online = models.BooleanField(default=True,help_text='话题是否在线') user = models.ForeignKey(to=User, to_field='id', on_delete=models.CASCADE, help_text='关联用户表') def __str__(self): return '%s: %s' % (self.id, self.title[0:20])- 外键引用的User字段:ForeignKey
- ForeignKey:是Django内置的应用 django.contrib.auth中定义的Model,之前创建超级用户也是直接使用的这个类型
Comment
class Comment(BaseModel): """ BBS 话题评论 """ content = models.CharField(max_length=255, help_text='话题评论') topic = models.ForeignKey(to=Topic,to_field='id',on_delete='models.CASCADE', help_text='关联话题表') up = models.IntegerField(default=0, help_text='支持') down = models.IntegerField(default=0, help_text='反对') def __str__(self): return '%d: %s' % (self.id, self.content[0:20])
4.1.2 post应用完成数据库迁移
- 编写了post应用的Model定义,为实现这些Models对象的操作,需要使用manage.py提供的数据库迁移工具将Models对象映射为数据库中的表
- 在执行迁移命令前,需要把post应用加载到my_bbs项目中,在
INSTALLED_APPS的第一行加入:post.apps.PostConfig - 然后对post应用执行
makemigrations命令,会在post/migrations包下面生成迁移文件,命令:python manage.py makemigrations post - 迁移文件也是Python文件,可以利用
manage.py提供的sqlmigrate命令打印迁移文件执行的SQL语句:python manage.py sqlmigrate post 0001- sqlmigrate命令后面跟随应用名称和迁移文件的名称
- manage.py提供了更为简单的命令帮助用户检查项目中的问题,可以在manage.py所在的目录下执行
python manage.py check- check命令也不会影响数据库
- 没有问题,会看到控制台上打印输出:
System checkidentified no issues(0 silenced)
- 查看了SQL语句,验证了项目的正确性,就可以执行migrate命令将Models映射为数据库的表了
python manage.py migrate
- 由于在刚才的定义中,Topic和Comment没有显示指定表名,默认使用Django的规则:
应用名_小写类名