Reputation: 10740
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
Upvotes: 2
Views: 940
Reputation: 37319
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.
Upvotes: 1
Reputation: 78536
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 byselect_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()
Upvotes: 0