Django 数据模型多对多关系查询方法
本文详解在 Django 框架中如何通过 ManyToManyField 定义并查询多对多数据关系,涵盖正向获取关联实例、反向追溯源数据以及条件过滤的操作方法,帮助开发者快速掌握 Django ORM 的核心检索技巧。
配置多对多模型与基础结构
在 Django 中处理一对多或一对一外键时通常使用 ForeignKey,而当需要表示书籍与作者之间“一本书有多个作者、一个作者参与多本书”的多对多关系时,应使用 models.ManyToManyField。首先确保应用目录下的 models.py 已正确导入依赖库,并定义相关模型类。注意:现代 Django 版本推荐使用 __str__ 替代已废弃的 __unicode__ 用于对象字符串表示,以保持 Python 3 兼容性。
from django.db import models
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
def __str__(self):
return self.name
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField()
def __str__(self):
return f'{self.first_name} {self.last_name}'
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
publication_date = models.DateField()
def __str__(self):
return self.title
正向查询:通过主模型获取关联对象
多对多字段会动态附加一个管理器(Manager),其返回值类型为 QuerySet。通过主模型实例调用该字段名,即可发起关联数据的检索请求。
第1步:执行全量提取与条件过滤
目的为获取某本书籍绑定的全部作者或筛选特定名字的关联记录。入口为 Django Shell 或业务视图代码。动作是通过主实例调用管理器:b.authors.all() 读取全集,或使用 .filter(first_name='Adrian') 传入精确字段参数。可观察的完成状态是终端返回包含 <Author> 对象的列表,未匹配条件时将稳定返回空列表 []。
>>> b = Book.objects.get(id=50)
>>> b.authors.all()
[, ]
>>> b.authors.filter(first_name='Adrian')
[]
>>> b.authors.filter(first_name='Adam')
[]
第2步:链式调用与排序优化
目的为在获取关联集合后进一步调整展示顺序或排除干扰数据。入口同上一步的返回结果。动作是直接接续 .order_by('-id') 或 .exclude(email__contains='spam') 等标准 QuerySet 方法。可观察的完成状态是输出列表严格按指定字段降序排列,且剔除不符合排除条件的冗余实例。
反向查询:从关联端追溯源数据
Django 默认根据多对多定义自动创建反向引用路径。当需要从子表或关联端查找所有绑定本模型的记录时,可使用小写模型名拼接 _set 后缀的属性访问器。
第3步:定位关联实例并调用反向管理器
目的为从作者维度反查其参与的所有作品清单。入口为任意已实例化的 Author 对象。动作是调用 a.book_set.all()。需注意属性名严格遵循 “模型小写名称 + _set” 的命名规范。可观察的完成状态是控制台打印出对应图书的 <Book> 实例数组,核对书名列表与预期一致即代表反向关联链路畅通。
>>> a = Author.objects.get(first_name='Adrian', last_name='Holovaty')
>>> a.book_set.all()
[, ]
完成状态判断与注意事项
验证查询正常完成的标志是:接口或终端稳定输出非异常的 QuerySet 结果集,且数据库实际产生了对应的 JOIN 查询语句。若在生产环境扩展更多模型,建议在外键定义中显式补充 on_delete=models.CASCADE 以规避旧版迁移警告。示例源码中的 __unicode__ 属早期 Python 2 语法,当前标准运行环境请直接替换为 __str__ 以避免编码冲突。
以上就是 Django 数据模型访问多对多字段的详细内容,更多关于 Python 后端开发与数据库 ORM 查询的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













