Ronen Ness
Ronen Ness

Reputation: 10740

django queryset from other's queryset manytomany

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

Answers (2)

Peter DeGlopper
Peter DeGlopper

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

Moses Koledoye
Moses Koledoye

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 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()

Upvotes: 0

Related Questions