[Fixed]-How to properly query a ManyToManyField for all the objects in a list (or another ManyToManyField)?

23👍

Another Idea

Ok I guess I should have added this to the other answer, but when I started on it, it seemed like it was going to be a different direction haha

No need to iterate:

person_specialties = person.specialties.values_list('pk', flat=True)

non_specialties = Specialties.objects.exclude(pk__in=person_specialties)

jobs = Job.objects.exclude(required_specialties__in=non_specialties)

note: I don’t know exactly how fast this is. You may be better off with my other suggestions.
Also: This code is untested

👤Jiaaro

7👍

I think you should look at using values_list to get the person’s specialties

Replace:

[s.name for s in person.specialties]

with:

person.specialties.values_list('name', flat=True)

That will give you a plain list (ie. [‘spec1’, ‘spec2’, …]) which you can use again. And the sql query used in the bg will also be faster because it will only select ‘name’ instead of doing a select * to populate the ORM objects

You might also get a speed improvement by filtering jobs that the person definately can NOT perform:

so replace:

jobs = Job.objects.all()

with (2 queries – works for django 1.0+)

person_specialties = person.specialties.values_list('id', flat=True)
jobs = Job.objects.filter(required_specialties__id__in=person_specialties)

or with (1 query? – works for django1.1+)

jobs = Job.objects.filter(required_specialties__in=person.specialties.all())

You may also get an improvement by using select_related() on your jobs/person queries (since they have a foreign key that you’re using)

👤Jiaaro

Leave a comment