Sem
Sem

Reputation: 4669

Django prefetch_related from foreignkey with manytomanyfield not working

For example, in Django 1.8:

class A(models.Model):
    x = models.BooleanField(default=True)

class B(models.Model):
    y = models.ManyToManyField(A)

class C(models.Model):
    z = models.ForeignKey(A)

In this scenario, C.objects.all().prefetch_related('z__b_set') doesn't work.

Is there a way to prefetch the information I need for c[0].z.b_set.all() to work without an extra query?

Upvotes: 6

Views: 11974

Answers (2)

301_Moved_Permanently
301_Moved_Permanently

Reputation: 4186

You can use select_related to follow the first part of the relationship (C.z's ForeignKey) in one batch:

C.objects.all().select_related('z').prefetch_related('z__b_set')

The prefetch_related part, however, will be done in at least two queries, as stated in the docs:

prefetch_related, on the other hand, does a separate lookup for each relationship, and does the ‘joining’ in Python. This allows it to prefetch many-to-many and many-to-one objects, which cannot be done using select_related, in addition to the foreign key and one-to-one relationships that are supported by select_related. It also supports prefetching of GenericRelation and GenericForeignKey.

Upvotes: 9

nima
nima

Reputation: 6733

You should explicitly set the related_name in B and migrate:

class B(models.Model):
    y = models.ManyToManyField(A, related_name="bs")

Upvotes: 1

Related Questions