【后端】【Djagno】【ORM】models.ManyToManyField 多对多字段类型全解

devtools/2025/3/23 14:46:31/

一、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 modelsclass 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

文章来源:https://blog.csdn.net/qq_59344127/article/details/146286697
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ppmy.cn/devtools/168826.html

相关文章

c#-单例模式

单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点来获取该实例。以下是详细介绍单例模式的各种实现方式。 1. 饿汉式单例模式 代码示例 using System;// 饿汉式单例类 public sealed class EagerSingleton {// 静态只读字段…

MySQL InnoDB大表DDL时出现唯一键冲突

一、深层次原因分析 1. Online DDL机制 MySQL 5.6及以上版本支持Online DDL操作,允许在执行DDL时对表进行并发的DML操作。在Online DDL过程中,会记录并发执行的DML操作到row log中,并在DDL操作的最后阶段应用这些DML操作。如果这些DML操作中…

VNA操作使用学习-01 界面说明

以我手里面的liteVNA为例。也可以参考其他的nanoVNA的操作说明。我先了解一下具体的菜单意思。 今天我想做一个天调,居然发现我连一颗基本的50欧姆插件电阻和50欧姆的smt电阻的幅频特性都没有去测试过,那买来这个nva有什么用途呢,束之高阁求…

桌子(table、desk)以及其他常见物体的urdf模型,用于搭建机器人环境如pybullet、Gazebo

一、背景 我们在搭建仿自己的仿真环境时,需要添加一些物品,如桌子,托盘等,使得我们的场景更丰富并贴合我们的任务。但手写这些常见物品的urdf是不现实的,所以下面给出了github上开源的模型,感谢开源。 我…

阿里云平台服务器操作以及发布静态项目

目录: 1、云服务器介绍2、云服务器界面3、发布静态项目1、启动nginx2、ngixn访问3、外网访问测试4、拷贝静态资源到nginx目录下并重启nginx 1、云服务器介绍 2、云服务器界面 实例详情:里面主要显示云服务的内外网地址以及一些启动/停止的操作。监控&…

基于视觉的核桃分级与套膜装置研究(大纲)

基于视觉的核桃分级与套膜装置研究:从设计到实现的完整指南 (SolidWorks、OpenCV、STM32开发实践) 🌟 项目背景与目标 1.1 为什么选择视觉分级与套膜? 产业痛点: 中国核桃年产量全球第一,但…

【Pandas】pandas Series plot.area

Pandas2.2 Series Plotting 方法描述Series.plot([kind, ax, figsize, …])用于绘制 Series 对象的数据可视化图表Series.plot.area([x, y, stacked])用于绘制堆叠面积图(Stacked Area Plot) pandas.Series.plot.area([x, y, stacked]) pandas.Serie…

Workerman5.0如何实现一对一聊天

文章精选推荐 1 JetBrains Ai assistant 编程工具让你的工作效率翻倍 2 Extra Icons:JetBrains IDE的图标增强神器 3 IDEA插件推荐-SequenceDiagram,自动生成时序图 4 BashSupport Pro 这个ides插件主要是用来干嘛的 ? 5 IDEA必装的插件&…