Django 数据库操作详解(2)

一般的,限制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
例如:

Entry.objects.filter(pub_date__lte='2006-01-01')

转换为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 implied

iexact

忽略大小写

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
前模糊匹配,后模糊匹配
跨关系查询

Entry.objects.filter(blog__name__exact='Beatles Blog')

这个可以跨越你想要的深度。
反向跨关系查询

Blog.objects.filter(entry__headline__contains=’Lennon’)
如果跨越多层关系查询,中间模型没有值,django会作为空对待不会发生异常

Blog.objects.filter(entry__author__name='Lennon' ) Blog.objects.filter(entry__author__name__isnull=True) Blog.objects.filter(entry__author__isnull=False, entry__author__name__isnull=True)

过滤器可参考模型字段

目前给的例子里,我们建立了过滤,比照模型字段值和一个固定的值,但是如果我们想比较同一个模型里的一个指端和另一个字段的值,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__exact

like 语句转义百分号

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()]

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/9607415a0529018a0f6f2981af8fc786.html