Django filter queryset __in=list for *every* item in queryset

Issue

Let’s say I have the following models

class Offer(models.Model):
    skills_required = models.ManyToManyField(Skill, blank=True)

class Skill(models.Model)
    title = models.CharField(max_length=80, primary_key=True)

class UserProfile(models.Model):
    skills = models.ManyToManyField(Skill)

How can I filter Offer.objects with an instance of UserProfile in a way that skills_required of remaining offers would be a subset of user_profile.skills?

Solution

We can count the number of required skills for that offer, and check if the number of skills is equal to the number of skills for that userprofile with:

from django.db.models import Count, F, Q

Offer.objects.alias(
    req_skill=Count('skills_required', distinct=True),
    skills=Count(
        'skills_required',
        filter=Q(skills_required__userprofile=my_userprofile),
        distinct=True
    )
).filter(
    req_skill=F('skills')
)

For Django prior to , you should use .annotate(…) [Django-doc] instead of .alias(…) [Django-doc].

Answered By – Willem Van Onsem

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published