7

Say I have a few models in Django:

class Foo(models.Model):
    bars = models.ManyToManyField(Bar)
    bazs = models.ManyToManyField(Baz)

class Bar(models.Model):
    quxs = models.ManyToManyField(Qux)

I can use prefetch_related to get all Bars belonging to Foo and all Quxs belonging to Bar with:

Foo.objects.prefetch_related('bars__quxs')

But how can I use prefetch_related to get this information as well as all the Bazs belonging to Foo? Would something like:

Foo.objects.prefetch_related('bars__quxs', 'bazs')

work?

swiss_knight
  • 5,787
  • 8
  • 50
  • 92
mitchfuku
  • 309
  • 1
  • 2
  • 7

1 Answers1

13

Yes. You can pass in multiple lookups to .prefetch_related()

jproffitt
  • 6,225
  • 30
  • 42
  • 3
    so this: Foo.objects.prefetch_related('bars__quxs', 'bazs') – mitchfuku Sep 16 '13 at 02:08
  • yes, that is correct. Is that not working for you? I know as long as `bars` and `bazs` are many to many fields on Foo that should work. – jproffitt Sep 16 '13 at 02:19
  • I guess what I don't understand is how to access `Foo.bars.quxs` now. Normally, it's just `Foo.bazs.all()`, but I can't access the `quxs` through `Foo.bars.all().quxs.all()`. – mitchfuku Sep 16 '13 at 03:14
  • I think I've found my answer [here](http://stackoverflow.com/questions/14916642/many-to-many-and-how-to-get-a-queryset-from-queryset). Is that the only way to do it? – mitchfuku Sep 16 '13 at 03:20
  • Are you trying to filter on the `Foo.bars.quxs` or just access it once you have it? To access quxs, first grab one of the bars, then access's its quxs. For example: `foo_object.bars.all()[0].quxs.all()` that will access all the quxs for the first bar in foo_object. – jproffitt Sep 16 '13 at 03:26
  • Yeah I'm trying to filter on it, so what I ended up doing was `Qux.objects.filter(bars__in=Foo.bars.all()).all()`. I think this should get me what I need right? – mitchfuku Sep 16 '13 at 03:42
  • First of all, you can't actually call `Foo.bars.all()` unless `Foo` is an instance of `Foo`. Secondly, since `Qux` is on the other side of the many to many relation with `Bar`, if you're filtering from `Qux` you need to filter with `bar_set`. For example: `Qux.ojects.filter(bar_set__in=foo_object.bars.all()).all()` – jproffitt Sep 16 '13 at 12:46