1. 程式人生 > >python測試開發django-38.多對多(ManyToManyField)查詢

python測試開發django-38.多對多(ManyToManyField)查詢

urn 多對多 play shell hello queryset lte href 技術

前言

一個學生可以對應多個老師,一個老師也可以教多個學生,這就是一種多對多的關系

models建表

新建一個老師表Teacher,和一個學生表Student

class Teacher(models.Model):
    '''老師表'''
    teacher_name = models.CharField(max_length=30, verbose_name="老師", default="")
    tel = models.CharField(max_length=30, verbose_name="電話", default="")
    mail = models.CharField(max_length=30, verbose_name="郵箱", default="")

    class Meta:
        verbose_name = "老師"
        verbose_name_plural = verbose_name
    def __str__(self):
        return self.teacher_name

class Student(models.Model):
    '''學生表'''
    student_id = models.CharField(max_length=30, verbose_name="學號", default="")
    name = models.CharField(max_length=30, verbose_name="姓名", default="")
    age = models.IntegerField(verbose_name="年齡",  default="")
    # 多對多
    teachers = models.ManyToManyField(Teacher, verbose_name="老師")

    class Meta:
        verbose_name = "學生"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

之後執行 makemigrations 和migrate,同步數據

python manage.py makemigrations
python manage.py migrate

同步之後數據庫裏面會新增三張表:student、teacher、student_teachers

技術分享圖片

shell模式新增數據

為了調試方便,可以使用django的shell模式,對表的數據增刪改查操作,打開cmd,cd到manage.py目錄

python manage.py shell

多對多表的增加數據

>>> from hello.models import Teacher, Student
>>> t1=Teacher.objects.create(teacher_name='劉老師',tel='155300001111',mail='[email protected]')
>>> t1.save()
>>> t1
<Teacher: Teacher object (1)>
>>> t2=Teacher.objects.create(teacher_name='萬老師',tel='155300001112',mail='[email protected]')
>>> t2.save()
>>> t2
<Teacher: Teacher object (2)>
>>> s1=Student.objects.create(student_id='11002200',name='張三',age=19)
>>> s1.save()

# 方法一:添加id
# 可以添加Teacher對應的id
>>> s1.teachers.add(1)
# 也可以添加多個id,逗號隔開
>>> s1.teachers.add(1,2)
# 如果添加的是傳一個可叠代對象(list或tupule),可以用*分開傳入這種方法
>>> s1.teachers.add(*[1,2])

# 方法二、直接添加對象
>>> s1.teachers.add(t1)
>>> s1.teachers.add(t2)
>>> s1.teachers.add(t1,t2)

# 也可以先查詢需要添加的對象
>>> ob=Teacher.objects.get(teacher_name='劉老師')
>>> ob
<Teacher: Teacher object (1)>
>>> s2=Student.objects.create(student_id='11002201',name='李四',age=19)
>>> s2.teachers.add(ob)

正向查詢

通過student表對象,查詢到對應的teacher

>>> from hello.models import Teacher, Student
>>> stu=Student.objects.filter(name='李四').first()
>>> stu
<Student: Student object (2)>
>>> stu.student_id
'11002201'

# 正向查詢
>>> stu.teachers.all()
<QuerySet [<Teacher: Teacher object (1)>]>

>>> stu.teachers.all()[0].teacher_name
'劉老師'
>>> stu.teachers.all()[0].tel
'155300001111'

反向查詢_set

通過老師名稱,查詢對應關聯的學生,反向查詢的時候在關聯表名稱後面加_set,如果設置related_name參數,就用related_name參數對應名稱查詢
參考上一篇https://www.cnblogs.com/yoyoketang/p/10573218.html

>>> tea=Teacher.objects.filter(teacher_name='劉老師').first()
>>> tea
<Teacher: Teacher object (1)>
>>> tea.tel
'155300001111'

# 反向查詢
>>> tea.student_set.all()
<QuerySet [<Student: Student object (1)>, <Student: Student object (2)>]>
>>> tea.student_set.all()[0].name
'張三'
>>>

xadmin註冊表

# adminx.py
import xadmin
from .models import Card, CardDetail, Teacher, Student

class ControlTeacher(object):
    # 顯示的字段
    list_display = ["teacher_name", "tel", "mail"]

class ControlStudent(object):
    # 顯示的字段
    list_display = ('student_id', 'name', 'age', '老師')

    # # 定義一個方法,遍歷book的auth,然後用列表返回
    def 老師(self, obj):
        return [x.teacher_name for x in obj.teachers.all()]

xadmin.site.register(Teacher, ControlTeacher)
xadmin.site.register(Student, ControlStudent)

xadmin後臺顯示效果

技術分享圖片

技術分享圖片

python測試開發django-38.多對多(ManyToManyField)查詢