原文地址:​​​​​​QuerySet API reference | Django documentation | Django

QuerySet有两个属性,ordered和db;

ordered:返回语句是否排序。True or False。

db:返回连接的数据库,默认 "default" 数据库。

可以使用链式调用组成查询语句,返回new QuerySet对象的方法有:

  • filter()
  • exclude()
  • annotate()
  • alias()
  • order_by()
  • reverse()
  • distinct()
  • values()
  • values_list()
  • dates()
  • datetimes()
  • none()
  • all()
  • union()
  • intersection()
  • difference()
  • select_related()
  • prefetch_related()
  • extra()
  • defer()
  • only()
  • using()
  • select_for_update()
  • raw()

filter

filter(**kwargs)

返回满足条件的新的查询集,效果 = WHERE,不同的条件间默认逻辑符号为AND,即

Student.object.filter(hobby="乒乓球", gender="women")

等价于 SELECT * FROM STUDENT WHERE hobby="乒乓球" AND gender="women"


exclude

返回不满足所有条件的行,和filter是相反的结果。

Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='Hello')

排除那些 headline为Hello且发行日期大于2005年1月3日的行。

等价于SQL

SELECT ...
WHERE NOT (pub_date > '2005-1-3' AND headline = 'Hello')

annotate

为查询集的每一项生成聚合,常用于分组统计,返回的查询集对象中添加一项聚合值。

例子1:按学生分组,统计每个学生的爱好数量

student = Student.objects.annotate(Count('hobbies'))

其中 student 增加了一项 hobbies__count 属性,支持自定义聚合字段名

student = Student.objects.annotate(hobby_count_by_student=Count('hobbies'))

其中 student 增加了一项 hobby_count_by_student 属性。

例子2:和filter方法联用

有时我们需要先对数据集先筛选再分组,有时我们还需要先分组再对查询集进行筛选。根据需求不同,我们可以合理地联用annotate方法和filter方法。注意: annotate和filter方法联用时使用顺序很重要。

# 先按爱好分组,再统计每组学生数量, 然后筛选出学生数量大于1的爱好。
Hobby.objects.annotate(student_num=Count('student')).filter(student_num__gt=1)# 先按爱好分组,筛选出以'd'开头的爱好,再统计每组学生数量。
Hobby.objects.filter(name__startswith="d").annotate(student_num=Count('student‘))

例子3:和order_by方法联用

可以使用order_by方法对annotate方法返回的数据集进行排序。

# 先按爱好分组,再统计每组学生数量, 然后按每组学生数量大小对爱好排序。
Hobby.objects.annotate(student_num=Count('student')) \.order_by('student_num')# 统计最受学生欢迎的5个爱好。
Hobby.objects.annotate(student_num=Count('student')) \.order_by('-student_num')[:5]

例子4:和values联用

在前例中按学生对象进行分组,我们同样可以按学生姓名name来进行分组。唯一区别是本例中,如果两个学生具有相同名字,那么他们的爱好数量将叠加。

# 按学生名字分组,统计每个学生的爱好数量。Student.objects.values('name').annotate(Count('hobbies'))# 你还可以使用values方法从annotate返回的数据集里提取你所需要的字段,如下所示:# 按学生名字分组,统计每个学生的爱好数量。Student.objects.annotate(hobby_count=Count('hobbies'))\ .values('name', 'hobby_count')

最近我又发现 annotate 一个好使的方面,就是给人为添加字段,比如说由于某种历史原因,查询语句为auth_time__range(日期1,日期2),原来的表字段为 auth_time 后来改名为 time 了,为了兼容,可以添加人为给查询结果添加一个auth_time字段。

ApplyRecord.objects.filter(user_id=self.user_id) \.annotate(auth_time=F("time")) \.filter(auth_time_filter_range) \.values("id", "auth_time")

alias

是3.2版本的新方法,用法和annotate一样,区别是annotate会在员对象上增加一个字段保存聚合结果,而alias则不会在原对象上增加字段。Not selecting the unused value removes redundant work from the database which should result in better performance. 对性能更加友好。


order_by

Django查询默认使用Meta.order指定的字段排序,允许显式调用order_by方法重写排序规则。支持跨表排序。

Entry.objects.filter(blog__name='Beatles Blog')
Blog.objects.filter(entry__authors__name='Lennon')

支持按照外键排序,如果外键没有指定Meta.order规则,则按照外键主键排序

Entry.objects.order_by('blog')
如果Blog.Meta.order = ['name']:等价于 Entry.objects.order_by('blog__name')
否则:等价于 Entry.objects.order_by('blog__id')

支持和聚合函数联合使用

Entry.objects.order_by(Coalesce('summary', 'headline').desc())

多个order_by方法链式调用只会保留最后一个,即后者覆盖前者,

Entry.objects.order_by('headline').order_by('pub_date')
# 按照pub_date排序而不是headline

注意:排序需要耗费性能,越多的排序字段,排序逻辑越复杂,对性能影响越大。同时,表中每个外键也会默认按照对应表默认排序一次,应当减少物理外键,使用逻辑外键。


reverse

reverse方法对查询出的结果取倒序,Django不支持从尾部切片,如不支持使用[-5:]取结果集最后5个,可以使用 quertset.reverse()[:5]

另外使用reverse操作前需要对查询进行排序,否则不起作用。


distinct

去重操作。作用和 SELECT DISTINCT 一样。

注意,去重需要和排序字段保持一致,如果BLOG指定了排序方式为name,那么下列去重不会生效:

Entry.objects.order_by('blog').distinct('blog')

因为 order_by=blog__name,而distinct=blog__id


values

values(*fields)
返回一个ValuesQuerySet —— QuerySet 的一个子类,迭代时返回字典而不是模型实例对象。

每个字典表示一个对象,键对应于模型对象的属性名称。

# This list contains a Blog object.
>>> Blog.objects.filter(name__startswith='Beatles')
[<Blog: Beatles Blog>]# This list contains a dictionary.
>>> Blog.objects.filter(name__startswith='Beatles').values()
[{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]

values() 接收可选的位置参数*fields,它指定SELECT 应该限制哪些字段。如果指定字段,每个字典将只包含指定的字段键/值。如果没有指定字段,每个字典将包含数据库表中所有字段键和值。

>>> Blog.objects.values()
[{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}],
>>> Blog.objects.values('id', 'name')
[{'id': 1, 'name': 'Beatles Blog'}]

values还可以接受键值对参数,相当于隐式调用annotate。

>>> from django.db.models.functions import Lower
>>> Blog.objects.values(lower_name=Lower('name'))
<QuerySet [{'lower_name': 'beatles blog'}]>

values可以使用内置或lookups自定义方法

>>> from django.db.models import CharField
>>> from django.db.models.functions import Lower
>>> CharField.register_lookup(Lower)
>>> Blog.objects.values('name__lower')
<QuerySet [{'name__lower': 'beatles blog'}]>

values内会优先应用内聚方法, 如果你想要分组统计,则需要统计前先分组。

>>> Blog.objects.values('entry__authors', entries=Count('entry'))
<QuerySet [{'entry__authors': 1, 'entries': 20}, {'entry__authors': 1, 'entries': 13}]>>>> Blog.objects.values('entry__authors').annotate(entries=Count('entry'))
<QuerySet [{'entry__authors': 1, 'entries': 33}]>

values获取外键默认为主键ID值

>>> Entry.objects.values()
<QuerySet [{'blog_id': 1, 'headline': 'First Entry', ...}, ...]>>>> Entry.objects.values('blog')
<QuerySet [{'blog': 1}, ...]>>>> Entry.objects.values('blog_id')
<QuerySet [{'blog_id': 1}, ...]>

values_list

values_list(*fieldsflat=Falsenamed=False)

返回指定*fields的参数元组列表

>>> Entry.objects.values_list('id', 'headline')
<QuerySet [(1, 'First entry'), ...]>

filed允许使用表达式

>>> from django.db.models.functions import Lower
>>> Entry.objects.values_list('id', Lower('headline'))
<QuerySet [(1, 'first entry'), ...]>

当只有一个参数时,允许使用flat参数

>>> Entry.objects.values_list('id').order_by('id')
<QuerySet[(1,), (2,), (3,), ...]>>>> Entry.objects.values_list('id', flat=True).order_by('id')
<QuerySet [1, 2, 3, ...]>

使用named=True参数将会把元组转换为命名空间对象,增加可读性,但是会损耗性能

# You can pass named=True to get results as a namedtuple():
>>> Entry.objects.values_list('id', 'headline', named=True)
<QuerySet [Row(id=1, headline='First entry'), ...]>

values 和 values_list 都旨在对检索性能优化:只查询具体的子集而不需要映射为模型对象,节省开销。特别的是在处理多对多和其他多值关系(例如反向外键的一对多关系)时,一个对象会返回多行:

>>> Author.objects.values_list('name', 'entry__headline')
<QuerySet [('Noam Chomsky', 'Impressions of Gaza'),('George Orwell', 'Why Socialists Do Not Believe in Fun'),('George Orwell', 'In Defence of English Cooking'),('Don Quixote', None)]>

dates

dates(fieldkindorder='ASC')

返回满足条件field的日期结果集,

field必须是 DateField 类型;

kind可以是 year | month | day | week;

        order 值可以是 ASC | DESC

比如查询总共有多少个发行日

examples
>>> Entry.objects.dates('pub_date', 'year')
[datetime.date(2005, 1, 1)]
>>> Entry.objects.dates('pub_date', 'month')
[datetime.date(2005, 2, 1), datetime.date(2005, 3, 1)]
>>> Entry.objects.dates('pub_date', 'week')
[datetime.date(2005, 2, 14), datetime.date(2005, 3, 14)]
>>> Entry.objects.dates('pub_date', 'day')
[datetime.date(2005, 2, 20), datetime.date(2005, 3, 20)]
>>> Entry.objects.dates('pub_date', 'day', order='DESC')
[datetime.date(2005, 3, 20), datetime.date(2005, 2, 20)]
>>> Entry.objects.filter(headline__contains='Lennon').dates('pub_date', 'day')
[datetime.date(2005, 3, 20)]

datetimes

datetimes(field_namekindorder='ASC'tzinfo=Noneis_dst=None)

功能和dates类似只不过类型为datetime

field_name 必须是 DatetimeField

kind 可以是 "year""month""week""day""hour""minute", or "second"

tzinfo 可以转换为指定时区,如果不传就是当前时区

tzinfo 时区名


none

none()

返回空的 QuerySet

>>> Entry.objects.none()
<QuerySet []>
>>> from django.db.models.query import EmptyQuerySet
>>> isinstance(Entry.objects.none(), EmptyQuerySet)
True

all

all()

返回所有查询结果,小心内存爆炸哦

Django QuerySet API 文档阅读(3):QuerySet定义(一)相关推荐

  1. ExtJS4 API文档阅读(四)——Data

    2019独角兽企业重金招聘Python工程师标准>>> ExtJS4 API文档阅读(四)--Data 数据 Data包负责加载和保存你应用程序中的所有数据,由41个类构成,其中有三 ...

  2. 聚合API文档阅读帮助

    聚合API文档阅读帮助 该文基于聚合云数据开放平台的API文档,目的使得开发者能够方便的快速了解我们这个API文档的结构,从而能够经行高效的开发. 该API文档总共有6个大类:国外API.国内API. ...

  3. 【Python】Django生成API 文档

    全局配置 # DRF 全局配置 REST_FRAMEWORK = {'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema ...

  4. Django QuerySet API文档

    在查询时发生了什么(When QuerySets are evaluated) QuerySet 可以被构造,过滤,切片,做为参数传递,这些行为都不会对数据库进行操作.只要你查询的时候才真正的操作数据 ...

  5. Zeal —— API文档离线阅读器

    背景 在软件开发的过程中,常常需要查阅多个API文档,但网络环境等因素常常导致在线文档查看用户体验并不佳.为此,介绍一款离线的API文档阅读器,Zeal.Zeal中自配了多种API文档可供查阅,如El ...

  6. java smart算法_Java Restful API 文档生成工具 smart-doc

    谁说生成api文档就必须要定义注解? 谁说生成接口请求和返回示例必须要在线? 用代码去探路,不断尝试更多文档交付的可能性. 如果代码有生命,为什么不换种方式和它对话! 一.背景 没有背景.就自己做自己 ...

  7. wordpress rest api 登录_Python构建RESTful网络服务[Django篇:生成API文档]

    链接:https://pan.baidu.com/s/15Mo9adr4Iw2W-um7WK68jA 提取码:ux79 系列文章介绍 本系列文章将详细介绍将Django官方引导教程中的投票项目改写为R ...

  8. 【接口文档】Django restful framework中自动生成API文档

    Django restful framework中自动生成API文档 一.Swagger概述 1.引言 当接口开发完成,紧接着需要编写接口文档.传统的接口文档使用Word编写,or一些接口文档管理平台 ...

  9. Django系列(1)-自动化生成API文档

    PS: 个人深感python开发者社区氛围比安卓/ios/java差多了.不过,这也许是个机会- 前提: 本人开发环境是mac10.14.4,Python3.7.2 django-rest-swagg ...

最新文章

  1. 客户端与服务器的数据交互
  2. c语言编程中tem代表什么意思,“CTEM”是“Conventional Transmission Electron Microscopy”的缩写,意思是“常规透射电子显微镜”...
  3. python杂记(一)
  4. VS2010开发ribbon风格的程序
  5. m40型工业机器人_工业机器人在汽车生产中有的应用范围
  6. HBTS(HBOI) 2019 真实退役记
  7. 在我的心目中freeeim
  8. 去除序号(正则表达式with sublime text)
  9. SAP License:CO-第四夜-产品成本核算
  10. 自己动手实现STL:前言
  11. Visual C# .NET2003语言的改变
  12. Forking AfterBurn into Maya
  13. 【渝粤教育】国家开放大学2018年春季 0702-22T当代中国政治制度 参考试题
  14. 第九次作业(杨辉三角)
  15. 小小恋歌(小さな恋のうた)
  16. Microsoft Productivity Hub 2010 安装部署配置(三)
  17. Git来回切换版本的时候,pom文件变黄,每次都需要重新添加到maven以及修改后文件不生效的解决方法
  18. 科海思除镍树脂CH-90Na
  19. Django(一)简单的个人博客搭建实战
  20. NoticeBar 通知栏组件,封装好的可直接使用

热门文章

  1. 【开发工具】IDEA生成序列号serialVersionUID快捷键
  2. “闪送模式”定义即时配送市场,C端为何独爱“一对一”?
  3. Python 安装及运行方式
  4. 微信小程序跳一跳java代码_安卓版微信小程序跳一跳辅助
  5. 打开软件出现应用程序无法正常启动(0xc0000006)的解决方法
  6. 其实苹果手机辨别真假这么简单!查看桌面1个图标,就能轻松分辨
  7. 兄弟mfc 7340 加墨粉
  8. Win10网络102错误代码该怎么办?360浏览器网络连接错误 错误代码 102的解决方法
  9. Math.round(); 四舍五入下取整
  10. 【STM32调试(三)】采集bmp图像保存在SD卡