2

What's the most efficient way to get all the records from a ManyToMany into a queryset?

To give an example, If I have a model named Events that has a ManyToMany to a model named Items and I have a queryset that contains Events. How do I get the queryset that contains all the Items that all the Events in the queryset point on?

If it was a single event, it would be: Events.items.all(). but this is a queryset so I can't do it.

Thanks

marcusshep
  • 1,916
  • 2
  • 18
  • 31
Ronen Ness
  • 9,923
  • 4
  • 33
  • 50

2 Answers2

1

Items.filter(event_set__in=some_events_qs) will do it. This uses a lazily evaluated nested query - but see the performance considerations noted in the docs.

This might return dupes if an Item belongs to more than one event in the initial queryset, I can never remember how that works. If so, .distinct() will clean it up but can also have a performance impact.

Peter DeGlopper
  • 36,326
  • 7
  • 90
  • 83
0

Django has a prefetch_related for minimizing the number of DB hits for fetching related objects:

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.

Your query will look:

events = events.objects.all().prefetch_related('items')

And the related objects:

items = [e.items.all() for e in events]

If event were a single object, it would look:

event = events.objects.get(id=id).prefetch_related('items')
# items related to that event
items = event.items.all()
Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
  • Hi moses, thanks but I already know prefetch_related() its not exactly what I'm asking.. `items = [e.items.all() for e in events]` will give me the items, but I'm looking for a *queryset of items*, not a list (eg I want to apply other filters on it before fetching them etc.). Also I may be wrong here but I doubt its the most efficient way.. – Ronen Ness Jun 23 '16 at 22:15
  • 1
    Then you may have a look at [this](http://stackoverflow.com/questions/12973929/why-does-djangos-prefetch-related-only-work-with-all-and-not-filter). You can filter if you get the related object directly without using `prefetch_related` – Moses Koledoye Jun 23 '16 at 22:19