一基于双划线的跨表查询

  Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系。要做跨关系查询,就使用两个下划线来链接模型(model)间关联字段的名称,直到最终链接到你想要的model 为止。

'''正向查询按字段,反向查询按表名小写用来告诉ORM引擎join哪张表
'''

一对多查询

# 练习:  查询苹果出版社出版过的所有书籍的名字与价格(一对多)# 正向查询 按字段:publishqueryResult=Book.objects.filter(publish__name="苹果出版社").values_list("title","price")# 反向查询 按表名:bookqueryResult=Publish.objects.filter(name="苹果出版社").values_list("book__title","book__price")

多对多查询  

# 练习: 查询alex出过的所有书籍的名字(多对多)# 正向查询 按字段:authors:queryResult=Book.objects.filter(authors__name="yuan").values_list("title")# 反向查询 按表名:bookqueryResult=Author.objects.filter(name="yuan").values_list("book__title","book__price")

一对一查询

    # 查询alex的手机号# 正向查询ret=Author.objects.filter(name="alex").values("authordetail__telephone")# 反向查询ret=AuthorDetail.objects.filter(author__name="alex").values("telephone")

进阶练习(连续跨表)

# 练习: 查询人民出版社出版过的所有书籍的名字以及作者的姓名# 正向查询queryResult=Book.objects.filter(publish__name="人民出版社").values_list("title","authors__name")# 反向查询queryResult=Publish.objects.filter(name="人民出版社").values_list("book__title","book__authors__age","book__authors__name")# 练习: 手机号以151开头的作者出版过的所有书籍名称以及出版社名称

# 方式1:queryResult=Book.objects.filter(authors__authorDetail__telephone__regex="151").values_list("title","publish__name")# 方式2:    ret=Author.objects.filter(authordetail__telephone__startswith="151").values("book__title","book__publish__name")

related_name

反向查询时,如果定义了related_name ,则用related_name替换表名,例如:

1
publish = ForeignKey(Blog, related_name='bookList')
# 练习: 查询人民出版社出版过的所有书籍的名字与价格(一对多)

# 反向查询 不再按表名:book,而是related_name:bookList

queryResult=Publish.objects.filter(name="人民出版社").values_list("bookList__title","bookList__price") 

二.聚合查询和分组查询

1.聚合

    aggregate(*args, **kwargs)

  aggregate()QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。如果你想要为聚合值指定一个名称,可以向聚合子句提供它。

# 计算所有图书的平均价格>>> from django.db.models import Avg>>> Book.objects.all().aggregate(Avg('price')){'price__avg': 34.35}

如果希望生成不止一个聚合,你可以向aggregate()子句中添加另一个参数。所以,如果你也想知道所有图书价格的最大值和最小值,可以这样查询:

>>> from django.db.models import Avg, Max, Min
>>> Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))
{'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}

 # 查询所有书籍的平均价格from django.db.models import Avg,Max,Sum,Min,Countret=Book.objects.all().aggregate(priceAvg=Avg("price"))print(ret) # {'priceAvg': 142.0}
# 查询所有书籍的个数
ret=Book.objects.all().aggregate(c=Count(1))
print(ret) # {'c': 4}

2.分组

  annotate()为调用的QuerySet中每一个对象都生成一个独立的统计值(统计方法用聚合函数)。

  单表分组查询

查询每一个部门名称以及对应的员工数emp:id  name age   salary    dep
1   alex  12   2000     销售部
2   egon  22   3000     人事部
3   wen   22   5000     人事部sql语句:
select dep,Count(*) from emp group by dep;ORM:
emp.objects.values("dep").annotate(c=Count("id")

#查询书籍表每一个出版社id以及对应的书籍个数
 key: annotate()前values哪一个字段就按哪一个字段group by
ret=Book.objects.values("publish_id").annotate(c=Count(1))
print(ret)# 查询每一个部门的名称以及对应员工的平均薪水ret=Emp.objects.values("dep").annotate(avg_salary=Avg("salary"))print(ret) # [{'dep': '教学部', 'avg_salary': 2500.0}, {'dep': '保洁部', 'avg_salary': 3500.0}, {'dep': '保安部', 'avg_salary': 4000.0}]># 查询每一个省份的名称以及对应的员工最大年龄

ret=Emp.objects.values("pro").annotate(max_age=Max("age"))
print(ret) # <QuerySet [{'pro': '山东省', 'max_age': 123}, {'pro': '河南省', 'max_age': 23}, {'pro': '河北省', 'max_age': 56}]>

  跨表的分组查询

查询每一个部门名称以及对应的员工数emp:id  name age   salary   dep_id
1   alex  12   2000       1
2   egon  22   3000       2
3   wen   22   5000       2depid   name
1    销售部
2    人事部emp-dep:id  name age   salary   dep_id   id   name
1   alex  12   2000       1      1    销售部
2   egon  22   3000       2      2    人事部
3   wen   22   5000       2      2    人事部sql语句:
select dep.name,Count(*) from emp left join dep on emp.dep_id=dep.id group by dep.idORM:
dep.objetcs.values("id").annotate(c=Count("emp")).values("name","c")

class Emp(models.Model):name=models.CharField(max_length=32)age=models.IntegerField()salary=models.DecimalField(max_digits=8,decimal_places=2)dep=models.CharField(max_length=32)province=models.CharField(max_length=32)

创建Emp表

总结 :跨表分组查询本质就是将关联表join成一张表,再按单表的思路进行分组查询。

# 查询每一个出版社的名称以及对应的书籍平均价格
ret=Publish.objects.values("name","email").annotate(avg_price=Avg("book__price"))
print(ret) # <QuerySet [{'name': '苹果出版社', 'avg_price': 117.0}, {'name': '橙子出版社', 'avg_price': 112.0}, {'name': '西瓜出版社', 'avg_price': 222.0}]># 查询每一个作者的名字以及出版的书籍的最高价格ret=Author.objects.values("pk","name").annotate(max_price=Max("book__price"))print(ret)# 查询每一个书籍的名称以及对应的作者的个数
ret=Book.objects.values("title").annotate(c=Count("authors"))
print(ret) # <QuerySet [{'title': 'python', 'authors__count': 2}, {'title': 'linux', 'authors__count': 1}, {'title': 'go', 'authors__count': 1}, {'title': 'java', 'authors__count': 0}]>

三.F查询与Q查询

F查询

在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较。如果我们要对两个字段的值做比较,那该怎么做呢?

Django 提供 F() 来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。

1
2
3
4
# 查询评论数大于收藏数的书籍
   from django.db.models import F
   Book.objects.filter(commnetNum__lt=F('keepNum'))

Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。

1
2
# 查询评论数大于收藏数2倍的书籍
    Book.objects.filter(commnetNum__lt=F('keepNum')*2)

修改操作也可以使用F函数,比如将每一本书的价格提高30元:

1
Book.objects.all().update(price=F("price")+30) 

Q查询

filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 如果你需要执行更复杂的查询(例如OR 语句),你可以使用Q 对象

1
2
from django.db.models import Q
Q(title__startswith='Py')

Q 对象可以使用& 和| 操作符组合起来。当一个操作符在两个Q 对象上使用时,它产生一个新的Q 对象。

1
bookList=Book.objects.filter(Q(authors__name="yuan")|Q(authors__name="egon"))

等同于下面的SQL WHERE 子句:

1
WHERE name ="yuan" OR name ="egon"

你可以组合& 和|  操作符以及使用括号进行分组来编写任意复杂的Q 对象。同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询:

1
bookList=Book.objects.filter(Q(authors__name="yuan") & ~Q(publishDate__year=2017)).values_list("title")

查询函数可以混合使用Q 对象和关键字参数。所有提供给查询函数的参数(关键字参数或Q 对象)都将"AND”在一起。但是,如果出现Q 对象,它必须位于所有关键字参数的前面。例如:

1
2
3
bookList=Book.objects.filter(Q(publishDate__year=2016) | Q(publishDate__year=2017),
                              title__icontains="python"
                             )

转载于:https://www.cnblogs.com/chenxi67/p/9856968.html

Django模型层的多表操作(2)相关推荐

  1. Django基础五之Django模型层(二)多表操作

    Django基础五之Django模型层(二)多表操作 一 创建模型 表和表之间的关系 一对一.多对一.多对多 # 作者表 比较常用的信息放在这个表中 class Author(models.Model ...

  2. python代码函数字符查询宝典书籍_Django基础五之django模型层(一)单表操作

    二 单表操作 一.创建表 创建模型 创建名为book的app,在book下的models.py中创建模型: from django.db importmodels#Create your models ...

  3. day55 django 模型层,orm连表操作

    设计表 django之orm详解: https://www.cnblogs.com/komorebi/p/11551089.html 在django中设计表 1.先在navicat中建好一个库 2.更 ...

  4. Django模型层之单表操作

    MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库.ORM是"对象-关系-映射 ...

  5. Django框架的模型层之多表操作

    目录 一 创建模型 二 表记录的增删改 一对多 多对多 三.基于对象的跨表查询 一对一查询(Author 与 AuthorDetail) 一对多查询(publish与book) 多对多查询 (Auth ...

  6. Django基础5.1,模型层(二)多表操作

    Django5.1 创建模型 建立下列模型 # 作者表 class Author(models.Model):name=models.CharField( max_length=32)age=mode ...

  7. Web开发-Django模型层

    Django模型层 简述 Django框架处理业务的逻辑一般如下(省略图,源于网络,侵删) 可以看到,Django自带了一套ORM机制,这也是Django框架的核心-"全面",将一 ...

  8. Django 模型层(models) 复杂查询详解

    Django 模型层(models) 复杂查询详解 一般Django orm 和原生sql混合使用 1.测试文件 只单独测试django中的某一个py文件 不一定是tests.py 1.配置 在任意一 ...

  9. Django–模型层orm查询

    文章目录 Django–模型层orm查询 一.单表查询(增.删.改.查) 基本查询 下划线查询 二.外键字段(增.删.改.查) 一对多 多对多 三.多表查询 多表查询的方式 正反向的概念 基于对象的跨 ...

最新文章

  1. 经常使用的npm命令
  2. 聊一聊 Spring 中的线程安全性
  3. 我的CCIE实验考试
  4. hdu--Number Sequence
  5. 央行放水点燃房价,普通家庭如何理财?
  6. socket与socketServer通信
  7. anroid 内存溢出 Bitmap OutOfMemoryError
  8. Gray Code(格雷码) C++多方法实现
  9. python基础--局部变量与全局变量
  10. 普通话转粤语_语音转文字评测:几款语音转文字app,你了解多少?
  11. C语言 gcc 动态库
  12. cfar matlab,雷达无线电系列(二)经典CFAR算法图文解析与实现(matlab)
  13. 人脸美化随笔1——研究方向总结
  14. 配置cfree 5 支持C++11
  15. LTE相关协议2——下行峰值速率计算
  16. 0528班宋ww:回顾刚来的那一天还历历在目,不禁感概一番
  17. 程序员漫学英语单词——resume
  18. 一招教你快速取消Mac系统开机密码的方法
  19. 图灵1951年报告Intelligent Machinery,A Heretical Theory中英文,公号回复“图灵1951报告”下载PDF双语典藏版
  20. 西门子1200 总线控制V90伺服程序模板 两种控制模式 1.基于111报文自己编写的PN通讯控制V90伺服程序

热门文章

  1. 如何关闭SAP Fiori的病毒扫描设
  2. 一个SAP顾问的回忆:我过去很胖!
  3. 把日志文件从Linux服务器拷贝到Windows上
  4. 如何使用SAP CRM中间件下载customer material数据
  5. 用条件运算符编写java程序,使用条件运算符的奇怪java行为。这是一个错误吗?...
  6. percona mysql.cnf_Percona MySQL5.6 半同步复制
  7. 机器狗背上枪成了杀手,已经与美澳军队合作!
  8. LCD也可以模拟?这款模拟器别错过了!
  9. 适合STM32的三大嵌入式操作系统
  10. windows下的库文件在linux的使用,Windows、Linux之间传输文件的几种方式