主键 (pk) 查询快捷方式
pk查询等同于通过模型的 primary key 进行过滤,直接上例子,下面三个语句是等效的。
>>> 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
任何查询条件都可以与 pk 结合使用,pk 查询也可以跨越关联进行。
缓存和 QuerySet
先看一段代码:
>>> print([e.headline for e in Entry.objects.all()])
>>> print([e.pub_date for e in Entry.objects.all()])
上述代码存在2个问题:
- 同样的数据库查询会被执行两次,实际加倍了数据库负载;
- 同时,有可能这两个列表不包含同样的记录,因为在两次请求间,可能有 Entry 被添加或删除了。
因此要学会使用QuerySet缓存。新创建的 QuerySet 缓存是空的。一旦要计算 QuerySet 的值,就会执行数据查询,随后,Django 就会将查询结果保存在 QuerySet 的缓存中,并返回这些显式请求的缓存。因此我们可以优化一下:
>>> queryset = Entry.objects.all()
>>> print([p.headline for p in queryset]) # Evaluate the query set.
>>> print([p.pub_date for p in queryset]) # Reuse the cache from the evaluation.
QuerySet 没有被缓存的情形
查询结果集并不总是缓存结果。使用数组切片或索引方式得到的 限制查询结果集 不会填充缓存。
例如,反复获取查询集对象中的某个索引会每次查询数据库:
>>> queryset = Entry.objects.all()
>>> print(queryset[5]) # Queries the database
>>> print(queryset[5]) # Queries the database again
如果整个查询集已经被评估过,那么会检查缓存而不是查询数据库:
>>> queryset = Entry.objects.all()
>>> [entry for entry in queryset] # Queries the database
>>> print(queryset[5]) # Uses cache
>>> print(queryset[5]) # Uses cache