django模型系统(三)--多对多,一对一以及跨表查询

-Many-to-Many
*** 指定了中间表,add,remove,set 都不能用,必须用中间表

两端都可以自动获得另一端的自动API访问。跟一对多的反向访问类似。但是使用的是本字段的字段名

In [112]: Course.objects.create(name=‘python全栈‘)
Out[112]: <Course: python全栈>

In [113]: Course.objects.create(name=‘python全套‘)
Out[113]: <Course: python全套>

In [114]: Course.objects.create(name=‘English‘)
Out[114]: <Course: English>

In [115]: c1,c2,c3= Course.objects.all()                                                                                                                                                                              

In [116]: c1
Out[116]: <Course: python全栈>

In [117]: c2
Out[117]: <Course: python全套>

In [118]: c3
Out[118]: <Course: English>

In [4]: c1,c2,c3= Course.objects.all()

In [5]: s1,s2,s3,s4,s5,s6 = Student.objects.all()

In [6]: c1.students.all()   #正向,students为course的字段,也是一个管理器
Out[6]: <QuerySet [<Student: 1-心蓝-0>]>

In [7]: s1.course_set.all()  #反向查询
Out[7]: <QuerySet [<Course: python全栈>]>

#如果没有中间表下面的正向添加、删除实例可以使用,这里不做演示         #指定了中间表后set,add,remove都不能用

c1.students.add(s1,s2,s3,s4,s5,s6)

c1.students.remove(s3,s4,s5,s6)

#如果没有中间表,下面的反向添加、删除实例可以使用,不做演示了    #只要是反向,就是用模型的小写加_set

s1.course_set.add(c1,c2,c3)

s1.course_set.remove(c1,c2,c3)

#加了中间表以后的操作

e =Enroll()

e.course = c1

e.student = s1

e.save()

或者

e =Enroll()

e.course_id = c1.id

e.student_id = s1.id

e.save()

2.增加

In [13]: Enroll.objects.create(student=s3,course=c3)
Out[13]: <Enroll: Enroll object (3)>

In [14]: Enroll.objects.create(student=s6,course=c2)
Out[14]: <Enroll: Enroll object (4)>

In [15]: Enroll.objects.create(student=s7,course=c1)
Out[15]: <Enroll: Enroll object (5)>

-One-to-One

正向访问:

In [8]: sd = StudentDetail.objects.create(num=‘20190228‘,college=‘家里蹲‘,student=s1)

In [9]: sd.student
Out[9]: <Student: 1-心蓝-0>

In [10]: sd.student.name
Out[10]: ‘心蓝‘

In [11]: sd.student.age
Out[11]: 0
反向(通过模型的小写)
In [12]: s1.studentdetail
Out[12]: <StudentDetail: StudentDetail object (1)>

In [13]: s1.studentdetail.num
Out[13]: ‘20190228‘

In [14]: s1.studentdetail.college
Out[14]: ‘家里蹲‘

3. 跨表查询(跨模型的相关字段的字段名,并且用__链接)

例一:查询男生报名了什么课程

In [19]: res = Course.objects.filter(students__sex =1)  #正向,students为字段

In [20]: print(res.query)
SELECT `teacher_course`.`id`, `teacher_course`.`name` FROM `teacher_course` INNER JOIN `teacher_enroll` ON (`teacher_course`.`id` = `teacher_enroll`.`course_id`) INNER JOIN `teacher_student` ON (`teacher_enroll`.`student_id` = `teacher_student`.`id`) WHERE `teacher_student`.`sex` = 1

In [21]: res
Out[21]: <QuerySet [<Course: python全栈>]>

例二:查询所有报名python课程的学生

反向关系,使用模型的小写course__name__contains

In [24]: res = Student.objects.filter(course__name__contains=‘python‘)  #course为模型的小写

In [25]: print(res.query)
SELECT `teacher_student`.`id`, `teacher_student`.`name`, `teacher_student`.`age`, `teacher_student`.`sex`, `teacher_student`.`qq`, `teacher_student`.`phone`, `teacher_student`.`grade_id`, `teacher_student`.`c_time`, `teacher_student`.`e_time` FROM `teacher_student` INNER JOIN `teacher_enroll` ON (`teacher_student`.`id` = `teacher_enroll`.`student_id`) INNER JOIN `teacher_course` ON (`teacher_enroll`.`course_id` = `teacher_course`.`id`) WHERE `teacher_course`.`name` LIKE BINARY %python%

In [26]: res
Out[26]: <QuerySet [<Student: 1-心蓝-0>]>

例三:查询所有报名了python课程的33期的学员

In [28]: res = Student.objects.filter(course__name__contains= ‘python‘,grade__num__contains=‘33‘)  #course为反向,grade为正向

In [29]: print(res.query)
SELECT `teacher_student`.`id`, `teacher_student`.`name`, `teacher_student`.`age`, `teacher_student`.`sex`, `teacher_student`.`qq`, `teacher_student`.`phone`, `teacher_student`.`grade_id`, `teacher_student`.`c_time`, `teacher_student`.`e_time` FROM `teacher_student` INNER JOIN `teacher_enroll` ON (`teacher_student`.`id` = `teacher_enroll`.`student_id`) INNER JOIN `teacher_course` ON (`teacher_enroll`.`course_id` = `teacher_course`.`id`) INNER JOIN `teacher_grade` ON (`teacher_student`.`grade_id` = `teacher_grade`.`id`) WHERE (`teacher_course`.`name` LIKE BINARY %python% AND `teacher_grade`.`num` LIKE BINARY %33%)

In [30]: res
Out[30]: <QuerySet []>

例四:查询缴费小于3000的学员

In [31]: res = Student.objects.filter(enroll__pay__lt=3000)

In [32]: print(res.query)
SELECT `teacher_student`.`id`, `teacher_student`.`name`, `teacher_student`.`age`, `teacher_student`.`sex`, `teacher_student`.`qq`, `teacher_student`.`phone`, `teacher_student`.`grade_id`, `teacher_student`.`c_time`, `teacher_student`.`e_time` FROM `teacher_student` INNER JOIN `teacher_enroll` ON (`teacher_student`.`id` = `teacher_enroll`.`student_id`) WHERE `teacher_enroll`.`pay` < 3000.0

In [33]: res
Out[33]: <QuerySet [<Student: 1-心蓝-0>]>

例五:查询报名了python课程所在的班级

In [35]: res = Grade.objects.filter(student__course__name__contains= ‘python‘)

In [36]: print(res.query)
SELECT `teacher_grade`.`id`, `teacher_grade`.`name`, `teacher_grade`.`num` FROM `teacher_grade` INNER JOIN `teacher_student` ON (`teacher_grade`.`id` = `teacher_student`.`grade_id`) INNER JOIN `teacher_enroll` ON (`teacher_student`.`id` = `teacher_enroll`.`student_id`) INNER JOIN `teacher_course` ON (`teacher_enroll`.`course_id` = `teacher_course`.`id`) WHERE `teacher_course`.`name` LIKE BINARY %python%

In [37]: res
Out[37]: <QuerySet [<Grade: 40期 - 进阶>]>

value 与only的区别
value返回字典
only返回对象

In [40]: res=Student.objects.values(‘name‘)

In [41]: res
Out[41]: <QuerySet [{‘name‘: ‘心蓝‘}, {‘name‘: ‘litao‘}, {‘name‘: ‘梦洁‘}, {‘name‘: ‘魏明凯‘}, {‘name‘: ‘litao‘}, {‘name‘: ‘刘洋‘}]>

In [42]: type(res[0])
Out[42]: dict

In [43]: res[0]
Out[43]: {‘name‘: ‘心蓝‘}

In [44]: res=Student.objects.only(‘name‘)

In [45]: res
Out[45]: <QuerySet [<Student: 1-心蓝-0>, <Student: 2-litao-0>, <Student: 3-梦洁-0>, <Student: 4-魏明凯-0>, <Student: 5-litao-0>, <Student: 6-刘洋-0>]>

In [46]: res[0].id
Out[46]: 1

In [47]: res[0]
Out[47]: <Student: 1-心蓝-0>

原文地址:https://www.cnblogs.com/taoge188/p/10506760.html

时间: 2024-10-19 19:40:24

django模型系统(三)--多对多,一对一以及跨表查询的相关文章

Django Mysql数据库-基于双下划线的跨表查询

一.基于双下划线的跨表查询 Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系.要做跨关系查询,就使用两个下划线来链接模型(model)间关联字段的名称,直到最终链接到你想要的 model 为止.(相当于用sql语句用join连接的方式,可以在settings里面设置,可查看sql语句) 数据库模型: class Book(models.Model): nid = models.AutoField(primary_key=Tru

django模型系统(二)

django模型系统(二) 常用查询 每一个django模型类,都有一个默认的管理器,objects QuerySet表示数据库中对象的列表.他可以有0到国歌过滤器.过滤器通过给定参数,缩小查询范围(filter). QuerySet等同与select语句,过滤器等同于一个限制字句,比如where.limit 使用.query可查看对应的SQL语句 all()获取所有 name.objects.all()queryset 获取第一条 name.objects.first()返回的是对象 获取最后

Django 模型系统(model)&amp;ORM--基础

ORM 映射关系: 类 ---> 表 属性 ---> 字段 对象 --->一条数据 创建表(建立模型) 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是一对一的关系(one-to-one) 出版商模型:出版商有名称,所在城市以及email. 书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系

Django模型系统(一)

装饰器补充 django模型系统 一,数据库的链接配置 二,Django的ORM简介 三,模型的创建与激活 四,数据的增删改查 一,数据库的链接配置 django  链接mysql的配置流程: -安装pymysql --   pip  install  pymysql -创建数据库用户 -有创建数据库权限的用户 -创建数据库 create database mysite; (创建需要的数据库) -修改配置 -修改项目文件(和settings.py文件所在的目录)下 __init__.py文件 -

django(3) 一对多跨表查询、多对多

1.一对多跨表查询获取数据的三种形式:对象.字典.元组 例:有host与business两张表,host与business的id字段关联,business在host表中的对象名是b,  通过查询host表获取的querySet中的b来查询business表. 以下两种方式都是操作host表: a.以对象的形式跨表查询,查询business表的数据:row.b.caption,row.b.id b.以字典和元组的形式跨表查询,查询business表的数据,跨表查询的时候要用双下划线  'b__id

Django之跨表查询及添加记录

一:创建表 书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);     一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many). 创建一对一的关系:OneToOne("要绑定关系的表名") 创建一对多的关系:ForeignKey("要绑定关系的表名") 创建多对多的关系:ManyToMany("要绑定关系的表名"

Django 【补充】ORM跨表查询补充

models.Book.objects.filter(**kwargs): querySet [obj1,obj2]models.Book.objects.filter(**kwargs).values(*args) : querySet [{},{},{}]models.Book.objects.filter(**kwargs).values_list(title) : querySet [(),(),()] 跨表查询总结: 1.创建表 class Book(models.Model): ti

Django 跨表查询--神奇的双下划线和点

我在django的moles中创建了两个calss,如下: class Project(models.Model):     name = models.CharField(u'项目名称',max_length=32,blank=True)     id = models.CharField(u'项目ID',max_length=32,unique=True,primary_key=True,blank=True)     create_date = models.DateTimeField(u

B django模型系统(后续1)

1.数据库的链接配置 django里mysql的连接流程 安装--pip install  pymysql 创建数据库用户 有创建数据库的权限的用户 创建数据库 crm 修改配置  setings DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'crm', 'USER':'root', 'PASSWORD':'qwe123', 'HOST':'127.0.0.1', 'PORT':'3306',