Django QuerySet API 整理
(译自官方文档)
以下操作会真正操作数据库:
- Iteration:在遍历对象时就会执行数据库操作
- Slicing:对与一个未查询的 QuerySet 切片就会返回另一个未查询的 QuerySet 。使用参数
step
参数时会执行数据库操作 - Picking/Caching:参见 Picking QuerySet
- repr():调用该方法时查询会被运行,并可以立即看到查询结果(命令行常用)
- len():返回查询结果列表的长度。运行时执行数据库操作,使用
count()
会更加高效 - list():再转化为列表时会执行数据库操作,且占用大量内存。而遍历 QuerySet 时仅使用某个对象时才加载至内存中
Picking QuerySet
import pickle |
QuerySet API
- filter(**kwargs):根据筛选条件返回相匹配的对象。参见 Filed lookups
- exclued(**kwargs):根据筛选条件返回不匹配的对象。
Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='Hello') |
SELECT ... |
- annotate(*args,**kwargs):为 QuerySet 中的每个对象添加注解(可以理解为辅助计算列),具体的函数参见 Aggregation Functions
'entry')) q = Blog.objects.annotate(number_of_entries=Count( |
- order_by(*fileds):默认情况下,QuerySet 返回的查询结果以 Model 类的 Meta 设置所提供的
ordering
项中定义的排序元组来排序。可以使用order_by
进行覆盖。通过设置 QuerySet.ordered 属性,可以决定某个查询是否可排序
# 🌰:以 pub_date 升序,再以 headline 倒序,默认倒序 |
- reverse():对查询结果进行反向排序
# 得到查询结果中最后五个对象 |
- distinct():返回一个新的 QuerySet ,在执行查询时使用 select distinct. 默认情况下,QuerySet 会自动剔除重复的记录,但是在多表查询时,可能会用到 Distinct(慎用)
- values(*fields):返回一个 ValuesQuerySet ,运行后得到的不是 Model 的实例话对象,而是一个可迭代的字典序列
# This list contains a Blog object. |
- values_list(*fields):与 values() 类似,不过返回的是元组序列
'id', 'headline') Entry.objects.values_list( |
- dates(field , kind , order=’ASC’):返回一个DateQuerySet,提取 QuerySet 查询中所包含的日期,组成一个新的 datetime.date 对象列表
'pub_date', 'year') Entry.objects.dates( |
- datetimes(field , kind , order=’ASC’):返回一个 DateTimeQuerySet ,组成一个新的 datetime.datetime 对象列表
- none():返回一个 EmptyQuerySet ,在运行时只返回一个空列表。适用于你要返回一个空列表,但调用者却需要接收一个 QuerySet 对象。
Entry.objects.none() |
- all():返回当前 QuerySet 但一份拷贝。当 QuerySet 运行后,会缓存查询结果,如果数据库发生了改变,调用 all() 可以更新查询
- select_related():返回一个 QuerySet ,在执行查询时进口可能深入的遍历外键关系,再查询后再使用外键关系获取关联对象时不会再读取数据库(通过库内 Join 进行查询)
- prefetch_related():与 select_related() 类似,但是是分别查询每个表,然后用 Python 处理他们之间的关系
from django.db import models |
- extra(select=None,where=None,params=None,tables=None,order_by=None,select_params=None)
extra() 可以修改 QuerySet ,能在生成的SQL语句中注入新的子句。但应尽量避免写 extra ,因为违背了 DRY 原则 - defer(*field):将不想载入但字段传给 defer() 方法,可以做到延后载入
Entry.objects.defer("lede", "body") |
- only(*field):和 defer() 作用相反,立即载入可以使用 only()
Person.objects.defer("age", "biography") |
- using(alias):切换数据库,参数是数据库的alias
# queries the database with the 'default' alias. |
- select_for_update(nowait=False):返回queryset,并将需要更新的行锁定,类似于SELECT … FOR UPDATE的操作
entries = Entry.objects.select_for_update().filter(author=request.user) |
- raw(raw_query, params=None, translations=None):执行 Raw SQL 查询
不返回查询的方法
这些方法不使用缓存,他们在运行时是直接读取数据库的。
- get(**kwargs):返回与筛选条件相匹配的对象。返回对象超过一个,抛出 MultipleObjectsReturned 异常,没有返回对象返回 DoesNotExist 异常
# DoesNotExist 异常继承自 django.core.exceptions.ObjectDoesNotExist,可以直接截获 DoesNotExist 异常 |
- create(**kwargs):创建对象并保存
# 以下操作等效 |
- get_or_create(default=None,**kwargs):根据筛选条件查询对象,若不存在就创建一个
# 以下代码效果相同,知识第一种过于臃肿 |
- update_or_create(defaults=None,**kwargs):与 get_or_create() 类似
try: |
- bulk_create(objs,batch_size=None):批量创建
Entry.objects.bulk_create([ |
- count():返回数据库中匹配查询的对象数量,不会抛出任何异常
- in_bulk(id_list):接收一个主键值列表,然后根据每个主键值所其对应的对象,返回一个主键值与对象的映射字典
1]) Blog.objects.in_bulk([ |
- iterator():运行查询,根据结果返回一个迭代器。分多次对数据实例化,用到时才会实例化。使用迭代器效率更高,节省内存
- latest(field_name=None):根据时间字段 field_name 得到最新的对象
Entry.objects.latest('pub_date') |
earliest(field_name=None):根据时间字段 field_name 得到最旧(早)的对象
first():排序后对第一个对象
p = Article.objects.order_by('title', 'pub_date').first()
last():类似于 first()
aggregate(*args, **kwargs):通过对 QuerySet 进行计算,返回一个聚合值的字典。 aggregate() 中每个参数都指定一个包含在字典中的返回值。
from django.db.models import Count |
- exists():查询是否有值,返回布尔值
- update():更新
- delete():删除
字段筛选条件(Field Lookups)
字段筛选条件决定了你如何构造 SQL 语句中的 WHERE 从句。它们被指定为 QuerySet 中 filter(),exclude() 和 get() 方法的关键字参数。
- exact():精确匹配,指定为 None 值会翻译为 SQL 中对 Null
Entry.objects.get(id__exact=14) |
- iexact():忽略大小写的匹配,SQLite 对 Unicode 字符串,无法做忽略大小写的匹配。
Blog.objects.get(name__iexact='beatles blog') |
- contains():大小写敏感的包含匹配
Entry.objects.get(headline__contains='Lennon') |
- icontains():忽略大小写敏感的包含匹配
Entry.objects.get(headline__icontains='Lennon') |
- in:是否在给定的列表中
Entry.objects.filter(id__in=[1, 3, 4]) |
- gt:大于
- gte:大于等于
- lt:小于
- lte:小于等于
- startswith:大小写敏感的以**开头
- istartswith:忽略大小写的以**开头
- endswith:大小写敏感的以**结尾
- iendswith:忽略大小写的以**结尾
- range:包含的范围,类似 SQL 中的 BETWEEN
import datetime |
- year:对日期/时间字段精确匹配年份,年份用四位数字表示
Entry.objects.filter(pub_date__year=2005) |
等价于SQL:
SELECT ... WHERE EXTRACT('year' FROM pub_date) = '2005'; |
- month:对日期/时间字段精确匹配月份
- day:对日期/时间字段精确匹配日期
- week_day:对日期/时间字段精确匹配周数
- hour:对日期/时间字段精确匹配小时
- minute:对日期/时间字段精确匹配分钟
- second:对日期/时间字段精确匹配秒
- isnull:根据字段是否为空筛选数据
Entry.objects.filter(pub_date__isnull=True) |
SELECT ... WHERE pub_date IS NULL; |
- search:利用全文索引做全文搜索,与 contains 类似,但使用全文索引会更快
Entry.objects.filter(headline__search="+Django -jazz Python") |
- regex:大小写敏感的正则表达式匹配
Entry.objects.get(title__regex=r'^(An?|The) +') |
- iregex:忽略大小写的正则表达式匹配
聚合函式
- avg:
__avg ,返回所给字段的平均值 - count:
__count ,返回所给关联字段的 model 数量 - max:
__max ,返回所给字段数据的最大值 - min:
__min , 返回所给字段数据的最小值 - strdev:
__stddev ,返回所给字段的标准差,sample=True 返回一个样本偏差值 - sum:
__sum ,计算所给字段的和 - variance:
__variance ,计算所给字段的标准方差,sample=True 返回样本方差