def prefetch_one_level(instances, prefetcher, attname):
    # prefetcher must have a method get_prefetch_query_set() which takes a list
    # of instances, and returns a tuple:

    # (queryset of instances of self.model that are related to passed in instances,
    #  callable that gets value to be matched for returned instances,
    #  callable that gets value to be matched for passed in instances,
    #  boolean that is True for singly related objects,
    #  cache name to assign to).

    # The 'values to be matched' must be hashable as they will be used
    # in a dictionary.

    rel_qs, rel_obj_attr, instance_attr, single, cache_name =\
        prefetcher.get_prefetch_query_set(instances)
    # We have to handle the possibility that the default manager itself added
    # prefetch_related lookups to the QuerySet we just got back. We don't want to
    # trigger the prefetch_related functionality by evaluating the query.
    # Rather, we need to merge in the prefetch_related lookups.
    additional_prl = getattr(rel_qs, '_prefetch_related_lookups', [])
    if additional_prl:
        # Don't need to clone because the manager should have given us a fresh
        # instance, so we access an internal instead of using public interface
        # for performance reasons.
        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, [])
        if single:
            # Need to assign to single cache on instance
            setattr(obj, cache_name, vals[0] if vals else None)
        else:
            # Multi, attribute represents a manager with an .all() method that
            # returns a QuerySet
            qs = getattr(obj, attname).all()
            qs._result_cache = vals
            # We don't want the individual qs doing prefetch_related now, since we
            # have merged this into the current work.
            qs._prefetch_done = True
            obj._prefetched_objects_cache[cache_name] = qs
    return all_related_objects, additional_prl
Helper function for prefetch_related_objects
dataset/ETHPy150Open AppScale/appscale/AppServer/lib/django-1.5/django/db/models/query.py/prefetch_one_level