如何緩存分頁的Django查詢集,特別是在ListView中?如何緩存分頁的Django查詢集
我注意到一個查詢需要很長時間才能運行,所以我試圖緩存它。該查詢集是巨大的(超過10萬條記錄),所以我試圖只緩存它的分頁子部分。我無法緩存整個視圖或模板,因爲有些部分是特定於用戶/會話的部分,需要不斷更改。
ListView有幾個檢索查詢集的標準方法,get_queryset()
(返回非分頁數據)和paginate_queryset()
,它們用當前頁面過濾它。
我首先嚐試緩存查詢get_queryset()
,但很快實現調用cache.set(my_query_key, super(MyView, self).get_queryset())
導致整個查詢被序列化。
於是我試圖重寫paginate_queryset()
像:
import time
from functools import partial
from django.core.cache import cache
from django.views.generic import ListView
class MyView(ListView):
...
def paginate_queryset(self, queryset, page_size):
cache_key = 'myview-queryset-%s-%s' % (self.page, page_size)
print 'paginate_queryset.cache_key:',cache_key
t0 = time.time()
ret = cache.get(cache_key)
if ret is None:
print 're-caching'
ret = super(MyView, self).paginate_queryset(queryset, page_size)
cache.set(cache_key, ret, 60*60)
td = time.time() - t0
print 'paginate_queryset.time.seconds:',td
(paginator, page, object_list, other_pages) = ret
print 'total objects:',len(object_list)
return ret
然而,這需要差不多一分鐘的運行,即使被檢索只有10個對象,每個請求顯示「重新緩存」,這意味着沒有什麼是被保存到緩存。
我settings.CACHE
樣子:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
}
}
和service memcached status
顯示memcached的運行和tail -f /var/log/memcached.log
表示絕對沒有。
我在做什麼錯?緩存分頁查詢的正確方法是什麼,以便不檢索整個查詢集?
編輯:我認爲他們可能是memcached或Python包裝中的錯誤。 Django似乎支持兩種不同的memcached後端,一種使用python-memcached,一種使用pylibmc。 python-memcached似乎默默地隱藏了緩存paginate_queryset()
值的錯誤。當我切換到pylibmc後端時,現在我收到一條明確的錯誤消息「error memcached_set:SERVER ERROR 10」,它回溯到第78行中的django/core/cache/backends/memcached.py。
低級高速緩存API是否在django shell中工作?請參閱https://docs.djangoproject.com/en/1.6/topics/cache/#basic-usage – arocks
是的,它似乎適用於簡單的不可變對象,甚至基本的查詢集。它只在緩存'paginate_queryset()'返回的值時纔會失敗。 – Cerin