Django 模型关系:从一对多到多对多全解析
一、一对多关系: ForeignKey
一对多是最常见的模型关系,例如 "作者 - 书籍" 场景:假设一个作者可以写多本书,但每本书只能属于一个作者。
定义关系
核心参数说明:
on_delete=models.CASCADE
:当作者被删除时,关联的书籍也会被自动删除related_name='books'
:定义反向查询名称,可通过author.books.all()
获取作者的所有书籍
数据操作示例
创建数据
查询操作
高级配置
禁用外键约束:当需要灵活管理关联关系(如允许删除存在关联数据的主表记录)时,可关闭数据库级约束
自定义数据库列名:默认会生成<ClassName>_id
列,可通过db_column
修改
二、多对多关系: ManyToManyField
多对多关系适用于 "作者 - 书籍" 的另一种场景:假设一个作者可以写多本书,一本书也可以有多个作者。
定义关系
Django 会自动创建中间表(默认名为appname_book_authors
)存储关联关系,无需手动定义。
数据操作示例
添加 / 移除关联
查询操作
自定义中间表
当需要存储关联关系的额外信息(如邀请原因、加入时间)时,可自定义中间表
三、性能优化技巧
select_related:用于一对多关系,提前加载关联对象,减少数据库查询
批量操作:利用 update()进行批量更新,避免循环操作
四、关于是否使用外键约束
在实际项目中,是否使用数据库外键约束需要权衡利弊
使用外键的优势
数据完整性:数据库级别的约束保证关联数据一致性
开发效率:ORM 自动处理关联查询和级联操作
查询便捷:支持
select_related
等优化方法,简化多表查询
禁用外键的场景
高并发系统:外键会增加数据库锁竞争,影响写入性能
分布式架构:分库分表环境下,跨库外键无法生效
复杂迁移:避免循环依赖导致的迁移失败问题
折中方案:使用db_constraint=False
参数
数据库层面:无外键约束,数据库不会强制校验关联数据的存在性
Django ORM 层面:保留逻辑关联,ORM 仍将字段视为外键关系(逻辑关联),支持 ORM 查询、操作语法

五、多对多关系实战
实战场景:在一个后台管理系统中,用户与角色往往是多对多关系。一个用户可以分配多个角色,一个角色也可以属于多个用户。

模型定义:点击查看完整代码
system_user_role
数据库生成的中间表

文章转载自:小王子1024
评论