Source code for dynamic_rest.patches

"""This module contains patches for Django issues.

These patches are meant to be short-lived and are
extracted from Django code changes.
"""


[docs]def patch_prefetch_one_level(): """ This patch address Django bug https://code.djangoproject.com/ticket/24873, which was merged into Django master in commit 025c6553771a09b80563baedb5b8300a8b01312f into django.db.models.query. The code that follows is identical to the code in the above commit, with all comments stripped out. """ import copy def prefetch_one_level(instances, prefetcher, lookup, level): rel_qs, rel_obj_attr, instance_attr, single, cache_name = ( prefetcher.get_prefetch_queryset( instances, lookup.get_current_queryset(level))) additional_lookups = [ copy.copy(additional_lookup) for additional_lookup in getattr(rel_qs, '_prefetch_related_lookups', []) ] if additional_lookups: rel_qs._prefetch_related_lookups = [] all_related_objects = list(rel_qs) rel_obj_cache = {} for rel_obj in all_related_objects: rel_attr_val = rel_obj_attr(rel_obj) rel_obj_cache.setdefault(rel_attr_val, []).append(rel_obj) for obj in instances: instance_attr_val = instance_attr(obj) vals = rel_obj_cache.get(instance_attr_val, []) to_attr, as_attr = lookup.get_current_to_attr(level) if single: val = vals[0] if vals else None to_attr = to_attr if as_attr else cache_name setattr(obj, to_attr, val) else: if as_attr: setattr(obj, to_attr, vals) else: qs = getattr(obj, to_attr).all() qs._result_cache = vals qs._prefetch_done = True obj._prefetched_objects_cache[cache_name] = qs return all_related_objects, additional_lookups # apply the patch from django.db.models import query query.prefetch_one_level = prefetch_one_level