docs: def get_prefetch_queryset(self, instances, queryset=None):
          """
           Overrides the parent method to:
           - force queryset to use the querytime of the parent objects
           - ensure that the join is done on identity, not id
           - make the cache key identity, not id.
           """
          if queryset is None:
              queryset = self.get_queryset()
          queryset._add_hints(instance=instances[0])
  
          # CleanerVersion change 1: force the querytime to be the same as the
          # prefetched-for instance.
          # This is necessary to have reliable results and avoid extra queries
          # for cache misses when accessing the child objects from their
          # parents (e.g. choice.poll).
          instance_querytime = instances[0]._querytime
          if instance_querytime.active:
              if queryset.querytime.active and \
                              queryset.querytime.time != instance_querytime.time:
                  raise ValueError(
                      "A Prefetch queryset that specifies an as_of time must "
                      "match the as_of of the base queryset.")
              else:
                  queryset.querytime = instance_querytime
  
          # CleanerVersion change 2: make rel_obj_attr return a tuple with
          # the object's identity.
          # rel_obj_attr = self.field.get_foreign_related_value
          def versioned_fk_rel_obj_attr(versioned_rel_obj):
              return versioned_rel_obj.identity,
  
          rel_obj_attr = versioned_fk_rel_obj_attr
          instance_attr = self.field.get_local_related_value
          instances_dict = {instance_attr(inst): inst for inst in instances}
          # CleanerVersion change 3: fake the related field so that it provides
          # a name of 'identity'.
          # related_field = self.field.foreign_related_fields[0]
          related_field = namedtuple('VersionedRelatedFieldTuple', 'name')(
              'identity')
  
          # FIXME: This will need to be revisited when we introduce support for
          # composite fields. In the meantime we take this practical approach to
          # solve a regression on 1.6 when the reverse manager in hidden
          # (related_name ends with a '+'). Refs #21410.
          # The check for len(...) == 1 is a special case that allows the query
          # to be join-less and smaller. Refs #21760.
          if self.field.remote_field.is_hidden() or len(
                  self.field.foreign_related_fields) == 1:
              query = {'%s__in' % related_field.name: set(
                  instance_attr(inst)[0] for inst in instances)}
          else:
              query = {'%s__in' % self.field.related_query_name(): instances}
          queryset = queryset.filter(**query)
  
          # Since we're going to assign directly in the cache,
          # we must manage the reverse relation cache manually.
          if not self.field.remote_field.multiple:
              rel_obj_cache_name = self.field.remote_field.get_cache_name()
              for rel_obj in queryset:
                  instance = instances_dict[rel_obj_attr(rel_obj)]
                  setattr(rel_obj, rel_obj_cache_name, instance)
  
          if VERSION[:1] < (2,):
              return (queryset, rel_obj_attr, instance_attr, True,
                      self.field.get_cache_name())
          else:
              return (queryset, rel_obj_attr, instance_attr, True,
                      self.field.get_cache_name(), False)