Skip to content

Commit 206f044

Browse files
committed
refactor filter caching
1 parent c75b593 commit 206f044

File tree

1 file changed

+29
-17
lines changed

1 file changed

+29
-17
lines changed

django_declarative_apis/machinery/filtering.py

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import logging
1111
import types
1212

13-
import django.db.models
1413
from django.conf import settings
1514
from django.core.exceptions import FieldDoesNotExist
1615
from django.db import models
@@ -77,26 +76,36 @@ def _is_reverse_relation(field):
7776
return isinstance(field, ForeignObjectRel)
7877

7978

80-
def _cache_related_instance(inst, field_name, model_cache):
79+
def _get_callable_field_value_with_cache(inst, field_name, model_cache, field_type):
80+
cache_relation = True
81+
8182
try:
8283
field_meta = inst._meta.get_field(field_name)
84+
if not _is_relation(field_meta) or _is_reverse_relation(field_meta):
85+
# no `attname` in reverse relations
86+
cache_relation = False
8387
except (AttributeError, FieldDoesNotExist):
84-
return
85-
if not _is_relation(field_meta) or _is_reverse_relation(field_meta):
86-
return # no `attname` in reverse relations
87-
val_pk = getattr(inst, field_meta.attname)
88-
val_cls = field_meta.related_model
89-
cache_key = _make_model_cache_key(val_cls, val_pk)
88+
cache_relation = False
89+
90+
if cache_relation:
91+
val_pk = getattr(inst, field_meta.attname)
92+
val_cls = field_meta.related_model
93+
cache_key = _make_model_cache_key(val_cls, val_pk)
94+
else:
95+
cache_key = (inst, field_name)
96+
9097
if cache_key in model_cache:
9198
logger.debug("ev=model_cache, status=hit, key=%s", cache_key)
92-
related_instance = model_cache[cache_key]
99+
result = model_cache[cache_key]
93100
else:
94101
logger.debug("ev=model_cache, status=miss, key=%s", cache_key)
95-
related_instance = getattr(inst, field_name)
96-
if not isinstance(related_instance, val_cls):
97-
return
98-
model_cache[cache_key] = related_instance
99-
setattr(inst, field_name, related_instance)
102+
result = field_type(inst)
103+
104+
if isinstance(result, models.Manager):
105+
# need to get an iterable to proceed
106+
result = result.all()
107+
model_cache[cache_key] = result
108+
return result
100109

101110

102111
def _get_filtered_field_value( # noqa: C901
@@ -114,9 +123,12 @@ def _get_filtered_field_value( # noqa: C901
114123
return None
115124

116125
if isinstance(field_type, types.FunctionType):
117-
val = field_type(inst)
118-
if is_caching_enabled() and isinstance(val, django.db.models.Model):
119-
_cache_related_instance(inst, field_name, model_cache)
126+
if is_caching_enabled():
127+
val = _get_callable_field_value_with_cache(
128+
inst, field_name, model_cache, field_type
129+
)
130+
else:
131+
val = field_type(inst)
120132
elif isinstance(field_type, _ExpandableForeignKey):
121133
if expand_this:
122134
inst_field_name = field_type.inst_field_name or field_name

0 commit comments

Comments
 (0)