模型设计
- 模型的涉及:相当于Web应用程序的数据库设计
- 论坛项目:
(1)创建Board板块模型,Topic主题模型,Post帖子模型
(2)User用户模型已经内置于Django中:Django.db.contrib.auth
- 所有的模型都是将 Djano.db.models.Model 类的子类
- 每个类都将被转化为数据库表:完成了数据库的设计
- 每个字段(属性)都由 Django.db.models.Field 类的实例表示,并转化为数据库的列
模型 ——> 数据库的表(类)
字段 ——> 数据库的列(属性),通过外键实现关联
- 模型之间的关系使用 ForeignKey 外键
它将在模型之间建立一个连接,并在数据库级别创建适当的关系
论坛项目模型
- 根据类图,理清项目逻辑,模型之间的关联
【1】User用户模型
from django.contrib.auth.models import User
导入Django内置的User用户模型
【2】Board板块模型
class Board(models.Model):
"""板块模型:
1. name字段(属性)
2. description字段(属性)"""
name = models.CharField(
max_length=30, unique=True) # max_length最大长度字符,unique唯一性
description = models.CharField(max_length=100)
def __str__(self):
"""告诉Django用字符串形式显示,不然在输出的时候不会返回能看懂的字符"""
return self.name
(1)两个字段即两个属性(参考类图)
(2)name字段:采用CharField字符子类,max_length告诉数据库多大空间,unique=True表明唯一性
(3)description字段(属性):采用CharField子类
【3】Topic主题模型
class Topic(models.Model):
"""主题模型:
1. subject字段(属性):主题内容
2. last_updated字段(属性)
3. board(外键关联):创建主题和板块之间的关联
4. starter(外键关联):创建主题和用户之间的关联
故已经创建了Topic和Board、User的关联"""
subject = models.CharField(max_length=255)
last_updated = models.DateTimeField(auto_now_add=True) # 当前时间
# board字段是Board模型的外键,告诉Django一个Topic只对应一个Board板块。related_name用于创建反向关系,board实例通过‘topics’访问这个板块下的Topic列表
board = models.ForeignKey(
Board, on_delete=models.CASCADE, related_name='topics')
starter = models.ForeignKey(
User, on_delete=models.CASCADE, related_name='topics')
(1)四个字段(属性)
(2)subject字段:主题内容
(3)last_updated字段:最新更新的时间
(4)board字段(外键实现):Board模型的一个外键,将Board和Topic模型进行关联,因为一个主题肯定属于一个板块,在Board实例那边可以通过 .topics 访问板块下的topic列表
(5)starter字段(外键实现): User模型的一个外键,将User模型与Topic模型关联起来,因为主题肯定是用户创建的,在用户那边可以通过用户的实例 .topics 访问主题列表
- 外键 :
board = models.ForeignKey(
Board, on_delete=models.CASCADE, related_name='topics')
(1)第一个参数:要关联的模块
(2)on_delete=models.CASCADE:级联删除,当板块删除时,主题也会一起删除。Django2.0之后一定要写
(3)related_name:位置参数,创建反向关联,通过board.topics可以反向访问所属板块的所有主题
【4】Post帖子模型
class Post(models.Model):
"""帖子模型:
1. message字段(属性):内容
2. topic外键:创建帖子和主题之间的关联
3. created_by外键:创建帖子和用户之间的关联
4. updated_by外键:创建帖子和用户之间的关联,可以为空值,因为可能没有更新
5. updated_at字段:内容更新的时间,可以为空值,因为可能没有更新
6. created_at字段:创建的时间"""
message = models.TextField(max_length=4000)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(null=True)
topic = models.ForeignKey(
Topic, on_delete=models.CASCADE, related_name='posts')
created_by = models.ForeignKey(
User, on_delete=models.CASCADE, related_name='posts')
updated_by = models.ForeignKey(
User, on_delete=models.CASCADE, null=True, related_name='+') # related_name='+'不需要反向关系
(1)6个字段(属性)
(2)message字段:存储帖子内容
(3)topic字段(外键实现):Topic模型的一个外键,将Topic模型与Post模型关联,因为帖子一定属于一个主题,Topic模型的实例通过 .posts访问帖子
(4)created_at字段:创建的时间
(5)updated_at字段:更新时间,可以为空,因为可能没有更新
(6)created-by字段(外键实现):User的一个外键,将Post与User关联,用户模型的实例通过 .posts 访问发起的帖子
(7)update_by字段(外键实现):User的一个外键,将Post与User关联,这里不产生反向关系
- models.py
from django.db import models
# Create your models here.
from django.contrib.auth.models import User
class Board(models.Model):
"""板块模型:
1. name字段(属性)
2. description字段(属性)"""
name = models.CharField(
max_length=30, unique=True) # max_length最大长度字符,unique唯一性
description = models.CharField(max_length=100)
def __str__(self):
"""告诉Django用字符串形式显示,不然在输出的时候不会返回能看懂的字符"""
return self.name
class Topic(models.Model):
"""主题模型:
1. subject字段(属性):主题内容
2. last_updated字段(属性)
3. board(外键关联):创建主题和板块之间的关联
4. starter(外键关联):创建主题和用户之间的关联
故已经创建了Topic和Board、User的关联"""
subject = models.CharField(max_length=255)
last_updated = models.DateTimeField(auto_now_add=True) # 当前时间
# board字段是Board模型的外键,告诉Django一个Topic只对应一个Board板块。related_name用于创建反向关系,Board实例通过‘topics’访问这个板块下的Topic列表
board = models.ForeignKey(
Board, on_delete=models.CASCADE, related_name='topics')
starter = models.ForeignKey(
User, on_delete=models.CASCADE, related_name='topics')
class Post(models.Model):
"""帖子模型:
1. message字段(属性):内容
2. topic外键:创建帖子和主题之间的关联
3. created_by外键:创建帖子和用户之间的关联
4. updated_by外键:创建帖子和用户之间的关联,可以为空值,因为可能没有更新
5. updated_at字段:内容更新的时间,可以为空值,因为可能没有更新
6. created_at字段:创建的时间"""
message = models.TextField(max_length=4000)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(null=True)
topic = models.ForeignKey(
Topic, on_delete=models.CASCADE, related_name='posts')
created_by = models.ForeignKey(
User, on_delete=models.CASCADE, related_name='posts')
updated_by = models.ForeignKey(
User, on_delete=models.CASCADE, null=True, related_name='+') # related_name='+'不需要反向关系
【5】迁移模型
- python manage.y makemigrations
告诉Django创建迁移数据库
Django会创建一个0001_initial.py文件——迁移文件,Django会使用这个文件创建数据库的列和表
- python manage.py migrate
将生成的迁移文件应用到数据库
由于是第一次迁移数据库,内置的apps也会执行迁移文件
- Python自带了一种SQLite产品级数据库,适合简单开发,不适合生产
【6】外键
- 当前模型下创建一个其他模型的外键,这样其他模型通过此外键可以访问当前模型
- 这是主题模型下板块模型的一个外键
board = models.ForeignKey(
Board, on_delete=models.CASCADE, related_name='topics')
当创建了一个板块的实例:board_test板块
通过:board_test.topics就可以从板块进入主题列表,实现了板块和主题的关联
创建了一个主题实例:topic_test主题
通过:topic_test.board就可以访问包含该主题的板块