久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Django的ManyToManyField(多對(duì)多)講解

 曲鳥(niǎo) 2022-01-10

一,、前言

下面的講解都基于三張表:student(學(xué)生表),、course(課程表)student_course(學(xué)生課程中間表)

功能描述:有多個(gè)學(xué)生和多門(mén)課程,一個(gè)學(xué)生可以選修多門(mén)課程,。


它們的表結(jié)構(gòu)如下:

student 學(xué)生表
字段說(shuō)明
id學(xué)生id
student_name學(xué)生的姓名
course學(xué)生選修的課程(多對(duì)多)
course 課程表
字段說(shuō)明
id課程id
course_name課程名

student_course 學(xué)生課程中間表
字段說(shuō)明
id中間表id
student_id學(xué)生id
course_id課程id

文章目錄


二,、創(chuàng)建多對(duì)多關(guān)系表

1. 自動(dòng)創(chuàng)建

1)通過(guò)django的ORM遷移功能可以方便自動(dòng)的建立多對(duì)多關(guān)系:

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)在項(xiàng)目目錄下,依次執(zhí)行如下遷移命令:

python manage.py makemigrations
python manage.py migrate

3)遷移成功的話,就可以在數(shù)據(jù)庫(kù)中看到這三張表了:
在這里插入圖片描述


2. 手動(dòng)創(chuàng)建

刪除student表的manyTomany字段,然后手動(dòng)創(chuàng)建中間表的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'

三、多對(duì)多的使用

1. 前期準(zhǔn)備

我們先為學(xué)生表創(chuàng)建一個(gè)學(xué)生,姓名為:曲鳥(niǎo) ,學(xué)生ID為:1
在這里插入圖片描述


2. 添加多對(duì)多數(shù)據(jù)及關(guān)系

1)創(chuàng)建單個(gè)新數(shù)據(jù)并建立關(guān)系

添加一個(gè)名為語(yǔ)文的課程并與曲鳥(niǎo)建立多對(duì)多的關(guān)系:

student=Student.objects.get(id=1)  # 先通過(guò)學(xué)生id找到曲鳥(niǎo)這個(gè)學(xué)生
student.course.create(course_name="語(yǔ)文")  # 創(chuàng)建名為語(yǔ)文的課程并建立關(guān)系

通過(guò)上面的代碼可以看出,只要student是模型的Student對(duì)象,就可以直接創(chuàng)建數(shù)據(jù)并建立關(guān)系,所以將之前查詢學(xué)生的代碼:

student=Student.objects.get(id=1)  # 先通過(guò)學(xué)生id找到曲鳥(niǎo)這個(gè)學(xué)生

改為下面這樣也是可以的:

student=Student.objects.filter(id=1).first()  # 先通過(guò)學(xué)生id找到曲鳥(niǎo)這個(gè)學(xué)生

當(dāng)然,新創(chuàng)建一個(gè)學(xué)生再新建課程進(jìn)行關(guān)聯(lián)也是可以的:

student=Student.objects.create(student_name="張三")  # 創(chuàng)建名為張三的學(xué)生
student.course.create(course_name="數(shù)學(xué)")  # 創(chuàng)建名為數(shù)學(xué)的課程并建立關(guān)系

2)創(chuàng)建多個(gè)新數(shù)據(jù)并建立關(guān)系

如果直接使用批量添加數(shù)據(jù)(bulk_create)方法,是無(wú)法建立多對(duì)多的關(guān)系的,。

如果非要批量創(chuàng)建并建立關(guān)系的話,可以再批量創(chuàng)建數(shù)據(jù)的時(shí)候指定主鍵值,然后通過(guò)set方法進(jìn)行關(guān)聯(lián):

student = Student.objects.filter(id=1).first()
set_list = []
a = 7
for name in ['體育', '美術(shù)']:
    set_list.append(Course(course_name=name, id=a))  # 手動(dòng)指定id
    a += 1
aa = student.course.bulk_create(set_list)  # 返回給aa的是一個(gè)列表,里面的元素為Course對(duì)象
student.course.set(aa)  # 通過(guò)set方法進(jìn)行關(guān)聯(lián)關(guān)系的建立

3)多對(duì)多建立關(guān)系add和set的區(qū)別

3.1 add

add接收一個(gè)Model對(duì)象,用于在原來(lái)存在的關(guān)系上進(jìn)行單條多對(duì)多關(guān)系的建立 (如果add的多對(duì)多關(guān)系原來(lái)已經(jīng)存在了,則保持不變)

student = Student.objects.get(id=1)  # 先通過(guò)學(xué)生id找到曲鳥(niǎo)這個(gè)學(xué)生
course = Course.objects.get(id=7)  # 查詢id=7的課程
student.course.add(course)

如果想基于原來(lái)存在的關(guān)系,批量增加新的多對(duì)多關(guān)系,則可以這樣寫(xiě):

student = Student.objects.get(id=1)  # 先通過(guò)學(xué)生id找到曲鳥(niǎo)這個(gè)學(xué)生
course = Course.objects.all()  # 查詢所有課程
student.course.add(*course)

3.2 set

set接收一個(gè)List,List里面的元素為Model對(duì)象,用于多條記錄的多對(duì)多關(guān)系建立 (如果已經(jīng)存在了多對(duì)多關(guān)系,則會(huì)刪除原來(lái)的關(guān)系,重新進(jìn)行建立)

student = Student.objects.get(id=1)  # 先通過(guò)學(xué)生id找到曲鳥(niǎo)這個(gè)學(xué)生
course = Course.objects.all()  # 查詢所有課程
student.course.set(course)

3. 刪除多對(duì)多數(shù)據(jù)及關(guān)系

1)僅刪除關(guān)系

1.1 刪除單個(gè)關(guān)系

student = Student.objects.get(id=1)  # 先通過(guò)學(xué)生id找到曲鳥(niǎo)這個(gè)學(xué)生
course=student.course.get(id=7)
student.course.remove(course)

1.2 刪除部分關(guān)系

student = Student.objects.get(id=1)  # 先通過(guò)學(xué)生id找到曲鳥(niǎo)這個(gè)學(xué)生
course = student.course.filter(id__in=[6, 7])
student.course.remove(*course)

1.3 刪除所有關(guān)系

student = Student.objects.get(id=1)  # 先通過(guò)學(xué)生id找到曲鳥(niǎo)這個(gè)學(xué)生
student.course.clear()

2)刪除關(guān)系并刪除數(shù)據(jù)

2.1 刪除單個(gè)

    student = Student.objects.get(id=1)  # 先通過(guò)學(xué)生id找到曲鳥(niǎo)這個(gè)學(xué)生
    student.course.filter(id=6).delete()

2.2 刪除部分

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

2.3 刪除所有

student.course.all().delete()

4. 修改多對(duì)多數(shù)據(jù)及關(guān)系

可以通過(guò)上面講的新增關(guān)系和刪除關(guān)系相結(jié)合進(jìn)行修改的操作,。


5. 查詢多對(duì)多數(shù)據(jù)及關(guān)系

1. 正向查詢

查詢所有

student.course.all()

因?yàn)樗褪莔odel對(duì)象,所以所有model使用的ORM關(guān)鍵字都可以使用例如:filter、values等,這里不再舉例,。


2. 反向查詢

例如想通過(guò)課程去查有哪些學(xué)生選修了,在查詢時(shí)加入set關(guān)鍵字即可:

course=Course.objects.get(id=1)
data=course.student_set.all()  #加入set關(guān)鍵字
print(data)

輸出結(jié)果

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

注:對(duì)于上面講的增加,、修改,、刪除中,也同樣可以使用反向查詢進(jìn)行操作


    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多