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