R / Richie全部文章 ↑

Python · 4 分钟阅读

Model 概念与字段

Model = 表结构 + 元数据 + 行为方法。理解它就理解了 Django ORM 的一半。

Model 的组成

class MyModel(models.Model):
    # 1. 字段 → 列
    # 2. Meta → 元数据
    # 3. __str__ → 字符串表示
    pass

继承 Model 后自动获得:

  • id — 自增主键(未显式声明时)
  • objects — Manager 实例,查询入口

常用 Meta 选项

选项 作用
abstract 抽象基类,不创建表
proxy 代理模型,复用存储
db_table 自定义表名
ordering 默认排序
indexes 索引列表
unique_together 联合唯一(已不推荐)
constraints 约束列表(推荐)
verbose_name 单数可读名
verbose_name_plural 复数可读名
permissions 自定义权限

示例:

class Meta:
    ordering = ["-created_time"]
    indexes = [models.Index(fields=["title"])]
    constraints = [
        models.UniqueConstraint(fields=["title", "is_online"], name="uniq_title_status"),
    ]

通用字段选项

选项 作用 备注
blank 允许为空 仅影响表单校验
null 允许 NULL 影响数据库列
unique 唯一约束 隐式创建索引
db_index 单列索引
default 默认值 不可为 lambda
primary_key 主键 整表只能有一个
choices 限定取值 Admin 自动渲染下拉
help_text 提示文本 Admin 与表单展示
verbose_name 字段可读名 Admin 与表单展示

字符串字段(CharField / TextField)的 null 推荐为 False,用空串表达"无值"。

基础字段类型

字段 用途
CharField 短文本,需指定 max_length
TextField 长文本
IntegerField / BigIntegerField / SmallIntegerField 整数
PositiveIntegerField 非负整数
BooleanField 布尔
DateField / DateTimeField 日期 / 时间
EmailField 邮箱
URLField URL
GenericIPAddressField IP
JSONField JSON(5.0+ 内置)
UUIDField UUID

DateTimeField 三选一:

  • auto_now_add=True — 创建时写入
  • auto_now=True — 每次保存更新
  • default=... — 自定义默认值

三者互斥。

三种关系字段

# 多对一:作者 → 多本书
class Book(models.Model):
    author = models.ForeignKey(Author, on_delete=models.CASCADE)

# 一对一:用户 → 资料
class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)

# 多对多:标签 ↔ 文章
class Article(models.Model):
    tags = models.ManyToManyField(Tag)

on_delete 选项:

值 行为
CASCADE 级联删除(最常用)
PROTECT 阻止删除
SET_NULL 设为 NULL(需 null=True)
SET_DEFAULT 设为默认值
SET(value) 设为指定值
DO_NOTHING 不处理(不推荐)

Model 继承

抽象基类

只复用字段,不创建表。

class BaseModel(models.Model):
    created_time = models.DateTimeField(auto_now_add=True)
    class Meta:
        abstract = True

多表继承

父、子都建表,子表通过隐式 OneToOneField 关联父表。

代理模型

不建新表,只新增方法或修改 Meta。

class OrderedTopic(Topic):
    class Meta:
        proxy = True
        ordering = ["id"]