一般的,限制QuerySet返回新的QuerySet,不会立即求值查询,除非你使用了”step”参数
Entry.objects.all()[:10:2] Entry.objects.order_by('headline')[0] Entry.objects.order_by('headline')[0:1].get()字段查找
字段查找是指定SQL语句的WHERE条件从句,通过QuerySet 的方法 filter(), exclude() 和get()指定查询关键字
基本查询field__lookuptype=value
例如:
转换为SQL:
SELECT * FROM blog_entry WHERE pub_date <= ‘2006-01-01’;
如果你传了无效的参数会抛异常
数据库API 支持一些查询类型,下面体验一下
exact
Entry.objects.get(headline__exact="Man bites dog")转化为SQL:
Sql代码 收藏代码
SELECT … WHERE headline = ‘Man bites dog’;
如果查询没有提供双下划线,那么会默认 __exact=
Blog.objects.get(id__exact=14) # Explicit form Blog.objects.get(id=14) # __exact is impliediexact
忽略大小写
Blog.objects.get(name__iexact="beatles blog")blog title会匹配 “Beatles Blog”, “beatles blog”, 甚至 “BeAtlES blOG”.
contains
包含查询,区分大小写
Entry.objects.get(headline__contains='Lennon')转化为SQL
SELECT … WHERE headline LIKE ‘%Lennon%’;
icontains 不区分大小写
startswith, endswith,istartswith ,iendswith
前模糊匹配,后模糊匹配
跨关系查询
这个可以跨越你想要的深度。
反向跨关系查询
Blog.objects.filter(entry__headline__contains=’Lennon’)
如果跨越多层关系查询,中间模型没有值,django会作为空对待不会发生异常
过滤器可参考模型字段
目前给的例子里,我们建立了过滤,比照模型字段值和一个固定的值,但是如果我们想比较同一个模型里的一个指端和另一个字段的值,django提供F()
from django.db.models import F Entry.objects.filter(n_pingbacks__lt=F('n_comments'))django支持加减乘除和模计算
Entry.objects.filter(n_pingbacks__lt=F('n_comments') * 2) Entry.objects.filter(rating__lt=F('n_comments') + F('n_pingbacks')) Entry.objects.filter(author__name=F('blog__name'))主键查询捷径
Blog.objects.get(id__exact=14) # Explicit form Blog.objects.get(id=14) # __exact is implied Blog.objects.get(pk=14) # pk implies id__exact不仅限于__exact查询
# Get blogs entries with id 1, 4 and 7 Blog.objects.filter(pk__in=[1,4,7]) # Get all blog entries with id > 14 Blog.objects.filter(pk__gt=14)跨越查询
Entry.objects.filter(blog__id__exact=3) # Explicit form Entry.objects.filter(blog__id=3) # __exact is implied Entry.objects.filter(blog__pk=3) # __pk implies __id__exactlike 语句转义百分号
Entry.objects.filter(headline__contains='%')转义为
SELECT … WHERE headline LIKE ‘%\%%’;
缓存查询集
每个QuerySet都包含一个缓存,以尽量减少对数据库的访问。理解他的工作原理很重要,可以写出最高效的代码。
在最新创建的QuerySet里,缓存是空的。在第一次QuerySet被取值,因此数据库查询发生,django把查询结果放入缓存,并返回给请求,随后的查询取值会复用缓存中的结果。
保持缓存的思想习惯,因为如果你不正确使用查询缓存会有麻烦。例如下面例子会创建两个QuerySet
print [e.headline for e in Entry.objects.all()] print [e.pub_date for e in Entry.objects.all()]