Home > Mobile >  Is it possible to filter django Many-To-Many QuerySet fields by checking if they're intersectio
Is it possible to filter django Many-To-Many QuerySet fields by checking if they're intersectio

Time:12-13

Doing an exercise about creating a Django service that given a certain job returns the best candidates. Sure it's a Machine Learning problem, and the scoring algorithm here is very simple. Frankly, this is the first time I'm using Django and I'm having some issues to filter out objects from one of the models.

This is my model class:

from django.db import models

class Skill(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self) -> str:
        return f'Skill name: {self.name}'

class Candidate(models.Model):
    title = models.CharField(max_length=100)
    name = models.CharField(max_length=100, default='')
    skills = models.ManyToManyField(Skill)

    def __str__(self) -> str:
        return f'Name: {self.name}, title: {self.title}'

class Job(models.Model):
    title = models.CharField(max_length=100)
    skills = models.ManyToManyField(Skill)

    def __str__(self) -> str:
        return f'title: {self.title}'

Given a job name, I would first like to filter by the skills i.e., go over the given Candidates and filter out the ones that don't have a mutual skill with the given job. In a more mathematical approach - the job_skills_set and the candidate_skills_set intersection is not empty. Something likes this: (I mixed Python syntax)

Candidate.objects.filter(len(set.intersection(set(skills), set(job.skills))) > 0)

Is there a way I can do that in Django? Tried multiple ways and did not succeed.

Thanks in advance!

CodePudding user response:

To get all candidates that share at least one skill with a given job you can just follow the relationship all the way through the skills table

Candidate.objects.filter(skills__job=job).distinct()

To get candidates that have all the same skills as the job you can count the number of matches and then filter where the count matches the number of skills

from django.db.models import Count
Candidate.objects.filter(
    skills__job=job
).annotate(
    match=Count('skills')
).filter(
    match=job.skills.count()
)
  • Related