【后端】【Djagno】【ORM】models.ManyToManyField 多对多字段类型全解
一、models.ManyToManyField
介绍
ManyToManyField
是 Django ORM 提供的一个字段类型,用于定义 多对多(Many-to-Many) 的关系。
在 Django 的模型(models.Model
)中,它用于表示 两个模型之间的多对多关系,即:
- 一个对象可以关联多个对象
- 另一个对象也可以关联多个对象
Django 会自动创建 中间表(关联表)来存储多对多的关系数据。
二、ManyToManyField
主要参数
to
(必须):指定关联的模型,可以使用 模型类 或 字符串app.ModelName
related_name
:反向关联的名称,默认模型名_set
,可自定义related_query_name
:用于反向查询的名称through
:指定自定义的中间表(默认 Django 自动创建)through_fields
:如果through
需要手动定义,必须指定关联的字段symmetrical
(默认True
):仅对自身关联的模型有效,表示是否对称(仅限无related_name
)db_table
:设置数据库表名blank
:是否允许为空help_text
:帮助文本,显示在 Django Adminverbose_name
:字段的人类可读名称limit_choices_to
:限制可选项的筛选条件
三、示例
1. 基本用法
from django.db import models
class Student(models.Model):
name = models.CharField(max_length=100)
class Course(models.Model):
name = models.CharField(max_length=100)
students = models.ManyToManyField(Student) # 课程和学生多对多
数据库表结构
-
student
(学生表) -
course
(课程表) -
Django 自动创建
course_students
作为中间表:
CREATE TABLE course_students ( id INTEGER PRIMARY KEY AUTOINCREMENT, course_id INTEGER REFERENCES course(id), student_id INTEGER REFERENCES student(id) );
使用示例
# 创建对象
s1 = Student.objects.create(name="张三")
s2 = Student.objects.create(name="李四")
c1 = Course.objects.create(name="数学")
c2 = Course.objects.create(name="英语")
# 关联学生和课程
c1.students.add(s1, s2) # 数学课有 张三、李四
c2.students.add(s1) # 英语课只有 张三
# 查询某课程的学生
c1.students.all() # 查询数学课程的所有学生
# 查询某学生的课程
s1.course_set.all() # 查询张三参加的所有课程
2. 使用 related_name
自定义反向查询
class Course(models.Model):
name = models.CharField(max_length=100)
students = models.ManyToManyField(Student, related_name="courses")
这样,查询张三的课程可以用:
s1.courses.all() # 代替 s1.course_set.all()
3. 使用 through
自定义中间表
如果需要额外的信息,比如 选课时间,可以自定义中间表:
class Enrollment(models.Model):
student = models.ForeignKey(Student, on_delete=models.CASCADE)
course = models.ForeignKey(Course, on_delete=models.CASCADE)
enrolled_date = models.DateField(auto_now_add=True) # 选课时间
class Course(models.Model):
name = models.CharField(max_length=100)
students = models.ManyToManyField(Student, through="Enrollment") # 使用自定义中间表
操作示例
# 学生选课
Enrollment.objects.create(student=s1, course=c1)
# 查询张三的课程
Course.objects.filter(enrollment__student=s1)
# 查询数学课的学生
Student.objects.filter(enrollment__course=c1)
四、总结
ManyToManyField
用于创建 多对多关系,Django 默认创建中间表- 主要参数包括
related_name
(反向查询)、through
(自定义中间表) - 可以使用
add()
、remove()
、clear()
来操作多对多关系 - 如果需要存储额外信息,使用
through
指定自定义中间表
你想在哪种场景下使用 ManyToManyField
?