zoukankan      html  css  js  c++  java
  • python测试开发django-38.多对多(ManyToManyField)查询

    前言

    一个学生可以对应多个老师,一个老师也可以教多个学生,这就是一种多对多的关系

    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='1000@qq.com')
    >>> t1.save()
    >>> t1
    <Teacher: Teacher object (1)>
    >>> t2=Teacher.objects.create(teacher_name='万老师',tel='155300001112',mail='1001@qq.com')
    >>> 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后台显示效果

  • 相关阅读:
    Java的注释,标识符,标识符的命名规范
    Java入门程序(Java的开发流程)
    EasyMock使用总结
    【转载】 Java并发编程:深入剖析ThreadLocal
    java.util.Stack类中的peek()方法
    Jquery和Ajax
    关于HTTP协议及SOCKET通信
    (转载)session token机制
    TCP/IP知识总结(TCP/IP协议族读书笔记四)
    TCP/IP知识总结(TCP/IP协议族读书笔记三)
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/10580253.html
Copyright © 2011-2022 走看看