关联对象操作及多表查询

关联表的数据操作:

一对多:

正向:如果一个模型有外键字段,通过这个模型对外键进行操作叫做正向。

更新:

  通过属性赋值

In [1]: from teacher.models import Student                                                                                                          

In [2]: from teacher.models import Grade                                                                                                            

In [3]: g=Grade.objects.create(name='django框架',num='7')                                                                                           

In [4]: g
Out[4]: <Grade: Grade object (1)> In [5]: g=Grade.objects.first() In [6]: s=Student.objects.first() In [7]: s.grade=g In [8]: s.save()

  通过主键的方式

In [9]: s2=Student.objects.last()                                       

In [10]: s2.grade_id=g.id                                               

In [11]: s2.save()

  总结:Foreignkey字段的更新,跟普通字段没什么区别。

删:只有外键设置了null=True,你就可以通过赋值None来删除关系

In [15]: s.grade=None                                                   

In [16]: s.save()

查:

In [18]: res=Student.objects.filter(grade__name='django框架')           

In [19]: print(res.query)
SELECT `teacher_student`.`id`, `teacher_student`.`name`, `teacher_student`.`age`, `teacher_student`.`sex`, `teacher_student`.`qq`, `teacher_student`.`phone`, `teacher_student`.`c_time`, `teacher_student`.`grade_id` FROM `teacher_student` INNER JOIN `teacher_grade` ON (`teacher_student`.`grade_id` = `teacher_grade`.`id`) WHERE `teacher_grade`.`name` = django框架

过滤Foreignkey字段模型的字段

 反向:一个模型如果被另外一个模型外键关联,通过这个模型对关联它的模型进行操作叫做反向。

  查:通过管理器,默认管理器是有外键的模型名称的小写加上_set(foo_set,foo是模型名称小写),通过这个管理器可以查询模型的实例,在定义外键的时候,通过related_name可以覆盖这个名称。

grade=models.ForeignKey('Grade',on_delete=models.SET_NULL,null=True,related_name='students1')

In [2]: from teacher.models import Grade,Student                                                            

In [3]: g=Grade.objects.first()                                                                             

In [4]: g
Out[4]: <Grade: django框架> In [6]: g.students1.all()
Out[6]: <QuerySet [<Student: 赵柳>]>

  增:

    通过add方法,可以添加多个

In [11]: new_s=Student.objects.first()   
In [13]: g.students1.add(new_s)   
In [17]: s1=Student.objects.get(pk=2)
In [18]: s2=Student.objects.get(pk=3)
In [19]: g.students1.add(s1,s2)

  

    通过create方法

In [22]: g.students1.create(name='郭富城')
Out[22]: <Student: 郭富城>

  删:删掉关系

    remove(obj1,obj2,obj3)

In [23]: gfc=Student.objects.last()                                                                         

In [24]: g.students1.remove(gfc)

    clear() 清空

In [25]: g.students1.clear()

  

  add,remove,clear直接操作数据库

  改:替换对象集

  set([s1,s2])

In [25]: s1
Out[25]: <Student: 李四> In [26]: s2
Out[26]: <Student: 王五> In [27]: g.students1.set([s1,s2])

多对多:

如果因为有额外字段,自定义了中间模型,我们就需要通过中间模型的管理器进行manytomany关系的创建和删除

默认情况跟一对多中的add,create,remove,clear用法一致

唯一的区别是多对多正向的时候,多对多字段就是一个管理器。

反向的时候,跟一对多的方向一致,也是在模型小写后面加上_set,和一对多类似,一样可以通过定义related_name可以覆盖这个名称。

In [1]: from teacher.models import Course,Enroll                                                                                                    

In [2]: c1=Course.objects.create(name='python全栈')   

In [4]: c2=Course.objects.create(name='python全套')   

In [10]: from teacher.models import Course,Enroll,Student                                                                                           

In [11]: s1=Student.objects.create(name='范冰冰')                                                                                                   

In [12]: s2=Student.objects.create(name='李冰冰')                                                                                                   

In [13]: s1
Out[13]: <Student: 范冰冰> In [14]: s2
Out[14]: <Student: 李冰冰> In [15]: e=Enroll() In [16]: e.student=s1 In [17]: e.course=c1 In [18]: e.paid=6680 In [19]: e.save() In [20]: c1
Out[20]: <Course: python全栈> In [21]: c1.students.all()
Out[21]: <QuerySet [<Student: 范冰冰>]> In [22]: c1.students.filter(name='范冰冰')
Out[22]: <QuerySet [<Student: 范冰冰>]> In [23]: c1.students.get(name='范冰冰')
、Out[23]: <Student: 范冰冰> In [24]: s1
Out[24]: <Student: 范冰冰> In [25]: s1.course_set.filter(name__startswith='python')
Out[25]: <QuerySet [<Course: python全栈>]>

一对一:

非常类似一对多字段,增删改查和普通字段没有什么区别

反向的时候,使用模型的小写,也可以给related_name覆盖,这个就不是管理器,就是一个普通属性。

注意:一个被一对一管理的模型,他的实例如果没有被分配关系。举个例子:学生对象,没有分配一个学生详情对象。如果去取,全抛出异常DoseNotExist。

跨表查询: 要跨越关系,只需使用跨越模型的相关字段名,以下划线分隔,直到达到你想要的字段为止。 

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

res=Course.objects.filter(students__sex=1).distinct()

  这个关系要多深就有多深

例:查询所有报名了python课的学员

res=Student.objects.filter(course__name__contains='python')

例:查询所有报名python全栈课程,在django框架第七期班级的学员

res=Student.objects.filter(course__name='python全栈',grade__name='django框架',grade__num='7')

例:学员报名了python课程的班级有哪些

res=Grade.objects.filter(students1__course__name__contains='python').distinct()

  

Django模型三的更多相关文章

  1. {django模型层(二)多表操作}一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询、分组查询、F查询和Q查询

    Django基础五之django模型层(二)多表操作 本节目录 一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询.分组查询.F查询和Q查询 六 xxx 七 ...

  2. django模型

    用django时,只要用到数据库就得用到模型. 一.数据库的MTV开发模式 从MVC到MTV 所谓软件架构的MVC模式将数据的存取逻辑(Module),表现逻辑(View)和业务逻辑(Controll ...

  3. 【Python】django模型models的外键关联使用

    Python 2.7.10,django 1.8.6 外键关联:http://www.bubuko.com/infodetail-618303.html 字段属性:http://www.cnblogs ...

  4. django 模型层(2)

    Django 模型层(2) 多表操作---模型之间的关系 1 一对一:作者----作者详细信息 2 一对多:书籍----出版社 3 多对多:书籍----作者 一  创建模型(主键(id)自动创建) 没 ...

  5. django模型系统(二)

    django模型系统(二) 常用查询 每一个django模型类,都有一个默认的管理器,objects QuerySet表示数据库中对象的列表.他可以有0到国歌过滤器.过滤器通过给定参数,缩小查询范围( ...

  6. Django(三)框架之第二篇

    https://www.cnblogs.com/haiyan123/p/7717788.html 一.知识点回顾 1.MTV模型 model:模型,和数据库相关的 template:模板,存放html ...

  7. Django 学习第六天——Django模型基础第一节

    一.Django 的 ORM 简介: Django的ORM系统的分析: 1.ORM 概念:对象关系映射(Object Relational Mapping,简称ORM) 2.ORM的优势:不用直接编写 ...

  8. Django模型层(2)

    <!DOCTYPE html><html lang="zh-cn"><head><meta charset="utf-8&quo ...

  9. django模型中的关系对应

    显然,关系数据库的力量在于将表相互关联.Django提供了定义三种最常见的数据库关系类型的方法:多对一,多对多和一对一. 在说明之前,首先来理解一下这三个概念: 多对一: 两个集合a,b;集合a中的多 ...

随机推荐

  1. SPFA的小优化

    标签:闲扯 SPFA的小优化 1. 向队尾加入元素时,如果它比对首还优,就把把它直接和队首交换. 拿一个双端队列来实现 (手写 , head ,tail   STLdeque亲测及其慢) 这个小优化其 ...

  2. 记intel杯比赛中各种bug与debug【其五】:朴素贝叶斯分类器的实现和针对性的优化

    咱这个项目最主要的就是这个了 贝叶斯分类器用于做可以统计概率的二元分类 典型的例子就是垃圾邮件过滤 理论基础 对于贝叶斯算法,这里附上两个链接,便于理解: 朴素贝叶斯分类器的应用-阮一峰的网络日志 基 ...

  3. java 基于 bootstrap_datagrid 分页

    1.首先引入datagrid  js ,css $("#datagrid").bootstrap_datagrid({ url : "<%=path%>/us ...

  4. who---显示目前登录系统的用户信息

    who命令是显示目前登录系统的用户信息.执行who命令可得知目前有那些用户登入系统,单独执行who命令会列出登入帐号,使用的终端机,登入时间以及从何处登入或正在使用哪个X显示器. 语法 who(选项) ...

  5. ArcGIS api for javascript——动态创建图层列表

    描述 本例循环地图服务里的所有图层并增加每个图层到一个带checkbox的列表,checkbox能设置图层的显示或隐藏.动态创建列表的优势是所有的图层都会包含在列表中,即使服务器管理员删除或增加了图层 ...

  6. Hadoop2 伪分布式部署

    一.简单介绍 二.安装部署 三.执行hadoop样例并測试部署环境 四.注意的地方 一.简单介绍 Hadoop是一个由Apache基金会所开发的分布式系统基础架构,Hadoop的框架最核心的设计就是: ...

  7. ubuntu 下安装eclipse &amp;java环境配置

    前面有一篇的博客写的是ubuntu下安装eclipse和java环境的配置.当时是安装网上的攻略进行的 ,当然也是能够成功的. 近期把那台电脑送人了 ,仅仅好在自己的这台电脑上又一次安装一次了 ,唯一 ...

  8. google浏览器修改网页字符编码

    google浏览器修改网页字符编码 直接在google浏览器的应用拓展程序里面搜 Charset,第一个就是 于是就有了

  9. 关于commJS 和 es6 的一些区别

    CommonJS模块与ES6模块的区别 本文转自 https://www.cnblogs.com/unclekeith/archive/2017/10/17/7679503.html CommonJS ...

  10. Sql Server通用分页存储过程

    Sql Server2005通用分页存储过程 CREATE PROCEDURE [dbo].[Common_GetPagedList] ( @TableName nvarchar(100), --表名 ...