python day-76 django orm 查询链表

一、基于双下划线跨表查询(join查询)

  在上一篇中,我们简单的介绍了基于对象的跨表查询,本章将继续阐述基于双下划线的跨表查询,所用的表格均为上章中所创建的表格。

      ##########################基于双下划线的查询:正向查询,按字段,反向查询,按表名#####################

1、一对多

实例一(正向,用字段):

# 查询红楼梦的出版社名称
#方式1:
ret=Book.objects.filter(title="红楼梦").values("publish__name")
print(ret)                                                          # <QuerySet [{‘publish__name‘: ‘北京出版社‘}]>
# 方式2:
res=Publish.objects.filter(book__title="红楼梦").values("name")
print(res)                                                          #<QuerySet [{‘name‘: ‘北京出版社‘}]>

实例二(反向,用表名):

# 查询沙河出版社出版过的书籍名称
#方式1:
ret=Publish.objects.filter(name="沙河出版社").values("book__title")
print(ret)                                                         #<QuerySet [{‘book__title‘: ‘金品梅2‘}, {‘book__title‘: ‘金品梅3‘}]>
#方式2:
res=Book.objects.filter(publish__name="沙河出版社").values("title")
print(res)                                                         #<QuerySet [{‘title‘: ‘金品梅2‘}, {‘title‘: ‘金品梅3‘}]>

2、多对多

实例一(正向,用字段):

# 查询红楼梦所有作者的名字
ret=Book.objects.filter(title="红楼梦").values("authors__name")
print(ret)                                                        #<QuerySet [{‘authors__name‘: ‘alex‘}, {‘authors__name‘: ‘egon‘}]>

实例二(反向,用表名):

#查询alex出版过的所有书籍
ret=Author.objects.filter(name="alex").values("book__title")
print(ret)                                                        #<QuerySet [{‘book__title‘: ‘金品梅2‘}, {‘book__title‘: ‘红楼梦‘}]>

3、一对一

实例一(正向,用字段):

# 查询地址在沙河并且email是123的作者的名字
ret=AuthorDetail.objects.filter(adrr="沙河",email=123).values("author__name")
print(ret)                                                        #<QuerySet [{‘author__name‘: ‘alex‘}]>

实例二(反向,用表名):

# 查询alex作者的adrr地址
ret = Author.objects.filter(name="alex").values("authordetail__adrr")
print(ret)                                                       #<QuerySet [{‘authordetail__adrr‘: ‘沙河‘}]>

实例三(综合实例):

#email以456开头的作者出版过的所有书籍名称以及出版社名称  ret=Book.objects.filter(authors__authordetail__email__startswith="456").values("title","publish__name")
print(ret)

  总结,在上一章的对象查询中,我们可以总结为所有的查询是基于一个models对象,而本节中双下划线查询均是基于queryset对象进行的!反向查询使用的表名同样必须为小写。

二、聚合函数(aggregate)

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

#查询所有书籍的平均价格
# 实例1:
ret=Book.objects.all().aggregate(Avg("price"))
print(ret)                                                         #{‘price__avg‘: 172.66666666666666}
# 实例2:
res = Book.objects.all().aggregate(avgPrice=Avg("price"))
print(res)                                                         #{‘avgPrice‘: 172.66666666666666}

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

# 查询所有书籍的平均价格、价格最大值、价格最小值
ret = Book.objects.all().aggregate(Avg("price"),Min("price"),Max("price"))
print(ret)                         #{‘price__avg‘: 172.66666666666666, ‘price__min‘: Decimal(‘123.00‘), ‘price__max‘: Decimal(‘230.00‘)}

  以上实例中需要按照如下方式引入相应的模块方法: from django.db.models import Avg, MaxMin

三、分组函数(annotate)

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

  实例1:查询每一个出版社出版过的书籍个数

ret=Publish.objects.all().annotate(num=Count("book__title"))     #可以理解为每一个出版社对象增加一个num字段,该字段值是通过聚合函数联表求得
for pub_obj  in ret:
    print(pub_obj.name,pub_obj.num)

  annotate的返回值是querySet,如果不想遍历对象,可以用上values_list,如下:

ret = Publish.objects.all().annotate(num=Count("book__title")).values_list("name","num")
print(ret)                                                       #<QuerySet [(‘人民出版社‘, 0), (‘沙河出版社‘, 2), (‘北京出版社‘, 1)]>

  实例2:查询每一本书的作者个数

ret=Book.objects.all().annotate(counts=Count("authors__nid")).values("title","counts")
print(ret)        #<QuerySet [{‘title‘: ‘金品梅2‘, ‘counts‘: 2}, {‘title‘: ‘金品梅3‘, ‘counts‘: 2}, {‘title‘: ‘红楼梦‘, ‘counts‘: 2}]>
时间: 2024-11-07 23:22:51

python day-76 django orm 查询链表的相关文章

Django ORM查询总结

Django ORM 中单表查询: querySet 与 model对象 1.all() :调用者:objects管理器,返回queryset 2.filter() : 调用者:objects管理器,返回queryset 3.get() 方法: 调用者:objects管理器,返回查询到的model对象(注意:查询结果有且只有一个才执行) 4.first(),last() 方法:调用者:queryset,返回model对象 5.exclude() : 调用者:objects管理器,返回一个quer

django orm查询方法详解

目录 1.1.1 生成查询 1.1.2 创建对象 1.1.3 保存修改的对象 1.1.4 保存 ForeignKey 和 ManyToManyField 字段 1.1.5 检索对象 1.1.6 检索所有的对象 1.1.7 过滤检索特定对象 1.1.8 链接过滤 1.1.9 过滤结果集是唯一 1.2.1 结果集是延迟的 1.2.2 其他的QuerySet方法 1.2.3 限制 QuerySets 1.2.4 字段查找 1.2.5 跨关系查询 1.2.6 过滤器可参考模型字段 1.2.7 缓存查询集

Django—— ORM查询(sql优化)优化了解,Django(元信息)元类建索引

Django(元信息)元类建索引 索引:索引的一个主要目的就是加快检索表中数据,索引是经过某种算法优化过的,因而查找次数要少的多.可见,索引是用来定位的. class Book(models.Model) name = models.CharField(max_length=64) class Meta: # 自定义表名 db_table = 'table_name' # 联合索引: 索引的一个主要目的就是加快检索表中数据 index_together = ('tag1', 'tag2') #

Python - Django - ORM 查询方法

models.py: from django.db import models class Human(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.IntegerField() birthday = models.DateField(auto_now_add=True) 在数据库中添加几条数据 在 Python 脚本中调用 Dj

Django orm查询操作

基于双下划线查询切记!!!!正向查询按字段,反向查询按表名的小写 正向:在Book表里设置关联Obj表,Book------>Obj就是正向查询 反向:在Book表里设置关联Obj表,Obj------>Book就是反向查询 废话不多说,直接上例子: 数据 class Book(models.Model): nid=models.AutoField(primary_key=True) title=models.CharField(max_length=32) price=models.Deci

【Python】【Django】查询所有学生信息

要做到以下效果: 改代码后效果: 从0开始顺序计数: 倒叙计数到0 原文地址:https://www.cnblogs.com/zhuzhubaoya/p/12375260.html

python 之 Django框架(orm单表查询、orm多表查询、聚合查询、分组查询、F查询、 Q查询、事务、Django ORM执行原生SQL)

12.329 orm单表查询 import os if __name__ == '__main__': # 指定当前py脚本需要加载的Django项目配置信息 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_demo.settings") import django django.setup() # 启动Django项目 from app01 import models #返回QuerySet对象的方法: r

django模型层 、 ORM查询

模型层 ORM查询 单表查询 前期准备工作需求: 如何只单独测试django中的某一个py文件 如何书写测试脚本 如何使用: 在任意一个py文件中书写以下代码 应用下的tests 或者自己新建一个 import os if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day53.settings") import django django.se

Python之路【第二十一篇】Django ORM详解

ORM回顾 关系对象映射(Object Relational Mapping,简称ORM). django中遵循 Code Frist 的原则,即:根据代码中定义的类来自动生成数据库表. 对于ORM框架里: 我们写的类表示数据库的表 如果根据这个类创建的对象是数据库表里的一行数据 对象.id 对象.value 是每一行里的数据 http://www.cnblogs.com/luotianshuai/p/5301343.html 梳理 首先在理解ORM的时候,我们可以把一对多.多对多 分为正向和反