djangodjango-select-relateddjango-generic-relations

How to prefetch or use select related in reverse generic relation in django?


Assume i have two models:

class A:
  content_type = models.ForeignKey(ContentType, on_delete=models.PROTECT, null=True, blank=True)
  object_id = models.PositiveIntegerField(null=True, blank=True)
  attached_object = fields.GenericForeignKey('content_type', 'object_id')
class B:
  some_field = GenericRelation(class A)

Now I have a scenario where i need to list all of class B instances, and in that result list, i need to include some of class A which is related to class B. While trying to do that, obviously it is leading to as many query hits as there are instances of class B. I have searched all online forums to try and reduce queries in this case.

instances_of_b = B.objects.all()
for instance in instances_of_b:
  some_list.append(instance.related_instance_of_class_A.some_field_of_class_A)

To get related_instance_of_class_A, i am using ContentType.objects.get_for_model(content_object)

Is there any way to use select_related/prefetch related in this case?


Solution

  • Couldn't find the exact solution using select_related/ prefetch_related. Since my queryset for instances_of_class_b is not so large, reduced the queries this way.

    ids_of_instances_of_b = B.objects.values_list('id', flat=True)
    related_instances_of_a = A.objects.filter(object_id__in=ids_of_instances_of_b)
    

    Now, whenever i need to loop over instances of B, no sql query needs to be fired.