主键 (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