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

Django ORM多对多关系实战指南

一、Django 多对多关系的原理

在关系型数据库中,多对多关系通常需要 第三张中间表 来维护两张表之间的对应关系。
在 Django 中,你只需要定义 ManyToManyField,Django 会自动帮你创建这张中间表。

特点:

  • 可以双向查询(正向 + 反向)
  • 支持添加、删除、清空操作(add()remove()clear()
  • 可以通过 through 参数自定义中间表,添加额外字段(例如时间戳、角色等)

二、实战案例:学生和课程系统

假设我们有一个 学生(Student)课程(Course) 的关系:

  • 一个学生可以选多门课程
  • 一门课程可以被多个学生选

1. 定义模型

# models.py
from django.db import modelsclass Course(models.Model):name = models.CharField(max_length=100)  # 课程名称teacher = models.CharField(max_length=100)  # 授课老师def __str__(self):return self.nameclass Student(models.Model):name = models.CharField(max_length=100)  # 学生姓名age = models.IntegerField()# 多对多关系courses = models.ManyToManyField(Course, related_name="students")def __str__(self):return self.name

执行 python manage.py makemigrations && python manage.py migrate 后,Django 会自动生成一张中间表:

appname_student_courses  # student_id, course_id

在这里插入图片描述


2. 数据操作示例

创建数据
# 创建课程
math = Course.objects.create(name="数学", teacher="张老师")
english = Course.objects.create(name="英语", teacher="李老师")# 创建学生
s1 = Student.objects.create(name="小明", age=18)
s2 = Student.objects.create(name="小红", age=19)# 关联课程
s1.courses.add(math, english)   # 小明选了数学、英语
s2.courses.add(math)            # 小红只选了数学

查询操作
# 查询小明选了哪些课程
student = Student.objects.get(name="小明")
student.courses.all()  # <QuerySet [<Course: 数学>, <Course: 英语>]># 查询选了数学的学生
math = Course.objects.get(name="数学")
math.students.all()  # <QuerySet [<Student: 小明>, <Student: 小红>]>

删除和清空
# 小明退选英语
student.courses.remove(english)# 小红退选所有课程
s2.courses.clear()

3. 自定义中间表(through)

在这里插入图片描述

如果我们希望记录 学生选课的时间,就需要手动定义中间表:

class StudentCourse(models.Model):student = models.ForeignKey(Student, on_delete=models.CASCADE)course = models.ForeignKey(Course, on_delete=models.CASCADE)selected_at = models.DateTimeField(auto_now_add=True)  # 选课时间class Meta:unique_together = ("student", "course")  # 防止重复选课class Student(models.Model):name = models.CharField(max_length=100)age = models.IntegerField()courses = models.ManyToManyField(Course, through="StudentCourse", related_name="students")

使用时:

# 小明选数学,并记录时间
StudentCourse.objects.create(student=s1, course=math)# 查询小明所有选课记录(带时间)
StudentCourse.objects.filter(student=s1)

三、总结

  • ManyToManyField 简化了多对多关系的操作,不需要手动建中间表。
  • 可以使用 add()remove()clear() 来维护关系。
  • 如果需要额外字段,可以通过 through 自定义中间表。

文章转载自:

http://tpgE9LbV.qxgmp.cn
http://JZ0bi3Up.qxgmp.cn
http://kjrYkxC6.qxgmp.cn
http://58C9Qjs0.qxgmp.cn
http://V31LRrbW.qxgmp.cn
http://XOmp2GbB.qxgmp.cn
http://Z07gEXMO.qxgmp.cn
http://k4oPQCkP.qxgmp.cn
http://bgAtDuC9.qxgmp.cn
http://ktJ1WNvX.qxgmp.cn
http://FR5gQhRz.qxgmp.cn
http://0wz4ht8N.qxgmp.cn
http://xSHLJdSD.qxgmp.cn
http://6sYQ7qSV.qxgmp.cn
http://q8EmPjNX.qxgmp.cn
http://LiX6YrRG.qxgmp.cn
http://I4BAyznX.qxgmp.cn
http://d3bgiOq9.qxgmp.cn
http://y6EzOOCV.qxgmp.cn
http://J07yNb64.qxgmp.cn
http://V8WR9wxP.qxgmp.cn
http://FrUzy1kW.qxgmp.cn
http://UsB6uk5X.qxgmp.cn
http://7swfy04e.qxgmp.cn
http://8zNDRI0f.qxgmp.cn
http://BqPMZm7d.qxgmp.cn
http://YRIBKFny.qxgmp.cn
http://eqydWIQV.qxgmp.cn
http://uVrnVdb6.qxgmp.cn
http://6pPlStFQ.qxgmp.cn
http://www.dtcms.com/a/386419.html

相关文章:

  • 【从零开始java学习|第十七篇】面向对象进阶
  • Three.js 开发实战教程(一):环境搭建与第一个 3D 场景
  • 旅游小程序的功能优势
  • LeetCode:7.接雨水
  • Android 安卓 问题解决记录 腾讯IM和厂商离线推送问题 点击离线推送无法唤醒APP启动页但某些Service服务和Application被启动
  • 动态规划解决系列子序列问题
  • SCADE One vs Scade 6 - 标量积建模比较
  • Next.js 身份验证与授权:使用 NextAuth.js 保护你的应用
  • Spring MVC 的案例小练习
  • 贪心算法与动态规划
  • 香港期权市场的主要参与者有哪些?
  • 系统中间件与云虚拟化-serverless-基于阿里云函数计算的简单邮件发送服务设计与体验
  • 【LLM】GPT-OSS架构变化详解
  • 【开题答辩全过程】以 “寄情绿苑”绿色殡葬服务小程序的设计和实现为例,包含答辩的问题和答案
  • 容器化部署之dockerfile07
  • 一篇读懂Pormise!!【前端ES6】
  • spring-kafka的消息过滤器RecordFilterStrategy
  • gin中sse流式服务
  • 论文笔记(九十一)GWM: Towards Scalable Gaussian World Models for Robotic Manipulation
  • Simulink(MATLAB)与 LabVIEW应用对比
  • [BX]和loop指令,debug和masm汇编编译器对指令的不同处理,循环,大小寄存器的包含关系,操作数据长度与寄存器的关系,段前缀
  • Django RBAC权限实战全流程
  • 智启燃气新未来丨众智鸿图精彩亮相2025燃气运营与安全研讨会
  • Docker Push 常见报错及解决方案汇总
  • OCR 后结构化处理最佳实践
  • 软考 系统架构设计师系列知识点之杂项集萃(148)
  • P1425 小鱼的游泳时间
  • 弧焊机器人氩气焊接节能方法
  • 机器人导论 第六章 动力学(2)——拉格朗日动力学推导与详述
  • 在uniapp中调用虚拟机调试vue项目