(六)模型类、字段与约束
# 项目文件:reading_project/src/library/models.py
from django.conf import settings
from django.db import models
class Tag(models.Model):
name = models.CharField("标签", max_length=30, unique=True)
class Meta:
ordering = ["name"]
verbose_name = verbose_name_plural = "标签"
def __str__(self):
return self.name
class Book(models.Model):
# 外键保存用户编号;反向名称让 user.books 可以取得该用户的书。
owner = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="books"
)
title = models.CharField("书名", max_length=100)
finished = models.BooleanField("已经读完", default=False)
tags = models.ManyToManyField(
Tag, blank=True, related_name="books", verbose_name="标签"
)
notes = models.TextField("阅读备注", max_length=2000, blank=True, default="")
updated_at = models.DateTimeField("更新时间", auto_now=True)
class Meta:
ordering = ["pk"]
# 同一用户的书名唯一,不同用户可以分别保存同名书。
constraints = [
models.UniqueConstraint(
fields=["owner", "title"], name="unique_owner_book_title"
)
]
permissions = [("export_book", "可导出自己的书架")]
verbose_name = verbose_name_plural = "书籍"
def __str__(self):
return self.titlemodels.Model 为类提供 ORM 能力,字段对象描述数据库列和表单规则。CharField 保存短文本,BooleanField 保存已读状态,TextField 保存备注,DateTimeField(auto_now=True) 在保存时记录更新时间。没有显式写主键时,应用配置生成大整数主键,pk 是主键的通用访问名。
blank=True 表示表单和模型校验允许留空,default="" 给未提供的备注一个空字符串;它们与数据库是否存 NULL 分别表达不同内容。备注采用空字符串,标签通过关联表保存,不把空标签写成一条分类。
Meta 中的排序、组合唯一约束和权限分别交给对应功能使用。__str__ 决定后台或调试中怎样显示对象。settings.AUTH_USER_MODEL 指向项目用户模型,关系通过它关联,而不在每个模型里固定导入用户类。