Django的ManyToManyField(多对多)讲解

简介: Django的ManyToManyField(多对多)讲解

一、前言


下面的讲解都基于三张表:student(学生表)course(课程表)student_course(学生课程中间表)

功能描述:有多个学生和多门课程,一个学生可以选修多门课程。


它们的表结构如下:


student 学生表

字段 说明
id 学生id
student_name 学生的姓名
course 学生选修的课程(多对多)


course 课程表

字段 说明
id 课程id
course_name 课程名


student_course 学生课程中间表

字段 说明
id 中间表id
student_id 学生id
course_id 课程id


二、创建多对多关系表


1. 自动创建


1)通过django的ORM迁移功能可以方便自动的建立多对多关系:


class Course(models.Model):
    id = models.AutoField(primary_key=True)
    course_name = models.CharField(max_length=100)
    class Meta:
        db_table = 'course'
class Student(models.Model):
    id = models.AutoField(primary_key=True)
    student_name = models.CharField(max_length=100)
    course = models.ManyToManyField(to=Course)


2)在项目目录下,依次执行如下迁移命令:


python manage.py makemigrations
python manage.py migrate


3)迁移成功的话,就可以在数据库中看到这三张表了:


efbc98d372094cccaa8dc5d89a7fb046.png


2. 手动创建


删除student表的manyTomany字段,然后手动创建中间表的orm模型即可:

class Course(models.Model):
    id = models.AutoField(primary_key=True)
    course_name = models.CharField(max_length=100)
    class Meta:
        db_table = 'course'
class Student(models.Model):
    id = models.AutoField(primary_key=True)
    student_name = models.CharField(max_length=100)
    class Meta:
        db_table = 'student'
class StudentAndCourse(models.Model):
    id = models.AutoField(primary_key=True)
    student = models.ForeignKey(to=Student, on_delete=models.DO_NOTHING)
    course = models.ForeignKey(to=Course, on_delete=models.DO_NOTHING)
    class Meta:
        db_table = 'student_and_course'

三、多对多的使用


1. 前期准备


我们先为学生表创建一个学生,姓名为:曲鸟 ,学生ID为:1

fa1ab33e79454549a8951a8a563074f5.png

2. 添加多对多数据及关系

1)创建单个新数据并建立关系


添加一个名为语文的课程并与曲鸟建立多对多的关系:


student=Student.objects.get(id=1)  # 先通过学生id找到曲鸟这个学生
student.course.create(course_name="语文")  # 创建名为语文的课程并建立关系


通过上面的代码可以看出,只要student是模型的Student对象,就可以直接创建数据并建立关系,所以将之前查询学生的代码:


student=Student.objects.get(id=1)  # 先通过学生id找到曲鸟这个学生


改为下面这样也是可以的:


student=Student.objects.filter(id=1).first()  # 先通过学生id找到曲鸟这个学生


当然,新创建一个学生再新建课程进行关联也是可以的:

student=Student.objects.create(student_name="张三")  # 创建名为张三的学生
student.course.create(course_name="数学")  # 创建名为数学的课程并建立关系

2)创建多个新数据并建立关系

student = Student.objects.filter(id=1).first()
set_list = []
a = 7
for name in ['体育', '美术']:
    set_list.append(Course(course_name=name, id=a))  # 手动指定id
    a += 1
aa = student.course.bulk_create(set_list)  # 返回给aa的是一个列表,里面的元素为Course对象
student.course.set(aa)  # 通过set方法进行关联关系的建立

3)多对多建立关系add和set的区别

3.1 add

add接收一个Model对象,用于在原来存在的关系上进行单条多对多关系的建立 (如果add的多对多关系原来已经存在了,则保持不变)

student = Student.objects.get(id=1)  # 先通过学生id找到曲鸟这个学生
course = Course.objects.get(id=7)  # 查询id=7的课程
student.course.add(course)


如果想基于原来存在的关系,批量增加新的多对多关系,则可以这样写:


student = Student.objects.get(id=1)  # 先通过学生id找到曲鸟这个学生
course = Course.objects.all()  # 查询所有课程
student.course.add(*course)


3.2 set

set接收一个List,List里面的元素为Model对象,用于多条记录的多对多关系建立 (如果已经存在了多对多关系,则会删除原来的关系,重新进行建立)


student = Student.objects.get(id=1)  # 先通过学生id找到曲鸟这个学生
course = Course.objects.all()  # 查询所有课程
student.course.set(course)

3. 删除多对多数据及关系

1)仅删除关系

1.1 删除单个关系

student = Student.objects.get(id=1)  # 先通过学生id找到曲鸟这个学生
course=student.course.get(id=7)
student.course.remove(course)

1.2 删除部分关系

student = Student.objects.get(id=1)  # 先通过学生id找到曲鸟这个学生
course = student.course.filter(id__in=[6, 7])
student.course.remove(*course)


1.3 删除所有关系

student = Student.objects.get(id=1)  # 先通过学生id找到曲鸟这个学生
student.course.clear()


2)删除关系并删除数据

2.1 删除单个


    student = Student.objects.get(id=1)  # 先通过学生id找到曲鸟这个学生
    student.course.filter(id=6).delete()


2.2 删除部分

student.course.filter(id__in=[6, 7]).delete()


2.3 删除所有

student.course.all().delete()


4. 修改多对多数据及关系

可以通过上面讲的新增关系和删除关系相结合进行修改的操作。


5. 查询多对多数据及关系

1. 正向查询

查询所有


student.course.all()


因为它就是model对象,所以所有model使用的ORM关键字都可以使用例如:filter、values等,这里不再举例。


2. 反向查询

例如想通过课程去查有哪些学生选修了,在查询时加入set关键字即可:


course=Course.objects.get(id=1)
data=course.student_set.all()  #加入set关键字
print(data)


输出结果

<QuerySet [<Student: Student object (1)>]>


注:对于上面讲的增加、修改、删除中,也同样可以使用反向查询进行操作

目录
相关文章
|
6月前
|
存储 安全 数据库
Django ORM深度游:探索多对一、一对一与多对多数据关系的奥秘与实践
Django ORM深度游:探索多对一、一对一与多对多数据关系的奥秘与实践
|
7月前
|
数据采集 自然语言处理 Python
在 Django 中设计爬虫系统的数据模型与多对多关系
在构建爬虫系统时,设计合理的数据模型和多对多关系对系统的性能和可维护性至关重要。本文将探讨如何使用 Django 来设计爬虫系统的数据模型。
|
7月前
|
Python
使用Django时,如何设计模型关系(一对一、一对多、多对多)?
Django支持三种模型关联:ForeignKey(一对多),OneToOneField(一对一)和ManyToManyField(多对多)。ForeignKey示例:`Article`有一个指向`Author`的外键。OneToOneField示例:`UserProfile`与`User`一对一关联。ManyToManyField示例:`Student`和`Course`之间多对多关系。这些关联字段便于反向查询,如`article.author`获取作者,`author.article_set.all()`获取作者所有文章。
93 1
【Django实战】创建多对多关系表的三种模式及优缺点分析
【Django实战】创建多对多关系表的三种模式及优缺点分析
|
数据库 Python
Django的多对多实现删除和修改
python manage.py makemigrations 应用名 python manage.py migrate 应用名 这两个命名是生成迁移文件和迁移数据库
123 0
|
数据库 Python
Django的多对多实现添加
python manage.py makemigrations 应用名 python manage.py migrate 应用名 这两个命名是生成迁移文件和迁移数据库
|
数据库 Python
Django的多对多如何获取到数据并实现搜索分页
python manage.py makemigrations 应用名 python manage.py migrate 应用名 这两个命名是生成迁移文件和迁移数据库
102 0
|
Shell 数据库 Python
【Django学习笔记 - 13】:关联查询(日期查询、一对一查询、一对多查询、多对多查询)
【Django学习笔记 - 13】:关联查询(日期查询、一对一查询、一对多查询、多对多查询)
474 0
【Django学习笔记 - 13】:关联查询(日期查询、一对一查询、一对多查询、多对多查询)
|
Python 项目管理 网络安全