cache wrapped multi-level-lookup subqueries

This commit is contained in:
Laura Klünder 2017-12-24 14:29:34 +01:00
parent 6cdcf70127
commit db2f99c774

View file

@ -4,6 +4,7 @@ from collections import OrderedDict
from functools import reduce, wraps
from itertools import chain
from django.core.cache import cache
from django.core.exceptions import ObjectDoesNotExist
from django.db import models
from django.db.models import FieldDoesNotExist, Manager, ManyToManyRel, Prefetch, Q
@ -506,7 +507,18 @@ class BaseQueryWrapper(BaseWrapper):
# multi-level-lookup
# todo: cache here or avoid too much subqueries
subkwargs = {'__'.join([filter_type] + segments): filter_value}
pk_values = self._changeset.wrap_model(rel_model).objects.filter(**subkwargs).values_list('pk', flat=True)
cache_key = '%s:multilevellookup:%s:%s:%s' % (
self._changeset.cache_key_by_changes,
rel_model.__name__,
next(iter(subkwargs.keys())),
repr(filter_value)
)
pk_values = cache.get(cache_key, None)
if pk_values is None:
pk_values = self._changeset.wrap_model(rel_model).objects.filter(
**subkwargs
).values_list('pk', flat=True)
cache.set(cache_key, pk_values, 300)
q = Q(**{field_name + '__pk__in': tuple(pk for pk in pk_values if not is_created_pk(pk))})
pk_values = set(str(pk) for pk in pk_values)
return self._filter_values(q, field_name, lambda val: str(val) in pk_values)