def load_related object_list related_qs cache_field None field None Lo

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def load_related(object_list, related_qs, cache_field=None, field=None):
"""Load related objects for a list of objects.
If field for joining is None, method will try to detect it from information about
relation between object_list and relates_qs.
Method requires 1 SQL query instead of len(object_list) queries."""
if not object_list:
return object_list
if not field:
field = object_list[0]._meta.object_name.lower()
field = related_qs.model._meta.get_field(field)
if not cache_field:
cache_field = related_qs.model.__name__.lower() + "_cache"
pks = [field.to_python(obj._get_pk_val()) for obj in object_list]
# we can't use WHERE f >= 5 and f <= 10 instead of WHERE f IN (5,6,7,8,9,10)
# with RelatedField from current ORM because RelatedField does not support
# __lte and __gte lookups for unknown reasons. Waiting for new query.py
related_qs = related_qs.filter(**{"%s__in" % field.name: pks})
for obj in object_list:
setattr(obj, cache_field, []) # even if object don't have related items
for rel_obj in related_qs:
obj_pk = getattr(rel_obj, field.get_attname()) # request key directly without join
obj = object_list[pks.index(obj_pk)]
getattr(obj, cache_field).append(rel_obj)
return object_list