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

Viewed 364

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?

1 Answers

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].

Related