当前位置: 首页 > news >正文

【后端】【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 Admin
  • verbose_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

相关文章:

  • 【设计模式】策略模式
  • EasyExcel--导入和导出Excel的方法
  • 面向机器人领域 | AKM Delta-Sigma数字输出无磁芯电流传感器
  • turnjs图册翻书效果
  • 数据仓库是什么,跟数据集成有什么关系
  • Web3 时代数据保护的关键挑战与应对策略
  • PostgreSQL 触发器
  • 电机控制常见面试问题(十四)
  • gralloc1_perform具体在干什么
  • 从两指到三指:Robotiq机器人自适应夹持器技术解析
  • MySQL InnoDB 事务隔离级别和锁
  • git 命令回退版本
  • nodejs - 基础知识
  • Plant Simulation中怎么更改机器人3D模型
  • 精挑20题:MySQL 8.0高频面试题深度解析——掌握核心知识点、新特性和优化技巧
  • WPF 布局中的共性尺寸组(Shared Size Group)
  • Git远程拉取和推送配置
  • Docker Compose部署MantisBT
  • 在本地跑通spark环境
  • 网络防火墙(Firewall)、Web防火墙(WAF)、入侵检测系统(IDS)、入侵防御系统(IPS)对比总结
  • 著名文学评论家、原伊犁师范学院院长吴孝成逝世
  • 意德首脑会谈,梅洛尼警告欧盟绿色政策面临“工业荒漠化”
  • 见微知沪|科学既要勇攀高峰,又要放低身段
  • 湃书单|澎湃新闻编辑们在读的14本书:后工作时代
  • 普京批准俄方与乌克兰谈判代表团人员名单
  • 持续8年仍难终了的纠纷:败诉方因拒执罪被立案,胜诉方银行账户遭冻结