Я нашел отличный учебник по кешированию подсчета наборов запросов модели ( Blog Blog ).В большинстве случаев он работает, но в случае моделей Proxy выдает странную ошибку.
class CachedCountProxy(object):
''' This allows us to monkey-patch count() on QuerySets so we can cache it and speed things up.
'''
def __init__(self, queryset, expires=600):
self._queryset = queryset
self._queryset._original_count = self._queryset.count
self._sql = self._queryset.query.get_compiler(self._queryset.db).as_sql()
self._sql = self._sql[0] % self._sql[1]
self.expires = expires
def __call__(self):
''' 1. Check cache
2. Return cache if it's set
3. If it's not set, call super and get the count
4. Cache that for X minutes
'''
key = "count_%s" % hashlib.sha224(self._sql).hexdigest()
count = cache.get(key)
if count is None:
count = self._queryset._original_count()
model_name = self._queryset.model._meta.app_label
expiration = self.expires
cache.set(key, count, expiration)
model_cache_list = cache.get(model_name) or []
model_cache_list.append(key)
cache.set(model_name, model_cache_list, expiration)
return count
Затем я выделил класс Django Queryset и добавил вышеупомянутый класс в качестве метода следующим образом.
class GenericQuerySet(QuerySet):
def get_cached_count(self, time=None):
cached_count = CachedCountProxy(self, expires=time)
return cached_count()
Теперь, когда я пытаюсь вызвать get_cached_count для всех наборов запросов не-прокси-модели, это происходит успешно.Однако когда я вызываю его в наборе запросов модели Proxy, он выдает следующий SQL;
{'time': '0.000', 'sql': u'SELECT COUNT(*) FROM WHERE NOT (`table`.`city_id` IS NULL)'}
Обратите внимание на отсутствие таблицы в предложении FROM?Это так странно, тем более что оригинальный метод count () в той же модели Proxy выдает правильный SQL.Что-то странное происходит в процессе привязки метода _original_count () или привязки набора запросов в целом к _queryset.
Есть мысли?