是否可以通过检查它们的交集是否为空来过滤 django 多对多 QuerySet 字段?

Posted

技术标签:

【中文标题】是否可以通过检查它们的交集是否为空来过滤 django 多对多 QuerySet 字段?【英文标题】:Is it possible to filter django Many-To-Many QuerySet fields by checking if they're intersection is not empty? 【发布时间】:2022-01-15 21:35:10 【问题描述】:

做一个关于创建一个给定工作的 Django 服务的练习会返回最好的候选人。 肯定是机器学习问题,这里的评分算法很简单。 坦率地说,这是我第一次使用 Django,我在从其中一个模型中过滤掉对象时遇到了一些问题。

这是我的模型类:

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'

给定一个工作名称,我首先想按技能进行过滤,即检查给定的候选人并过滤掉与给定工作没有共同技能的候选人。在更数学的方法中 - job_skills_set 和 Candidate_skills_set 交集不为空。 像这样的东西:(我混合了 Python 语法)

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

有没有办法在 Django 中做到这一点? 尝试了多种方法,都没有成功。

提前致谢!

【问题讨论】:

【参考方案1】:

要让所有候选人与给定工作至少共享一项技能,您只需在技能表中一直跟踪关系

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

要获得与工作具有所有相同技能的候选人,您可以计算匹配的数量,然后过滤计数与技能数量匹配的位置

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

【讨论】:

谢谢,第一个正是我想要的。

以上是关于是否可以通过检查它们的交集是否为空来过滤 django 多对多 QuerySet 字段?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在 Swift 2.1 中检查目录是否为空? [复制]

判断对象是否为空

NodeJS检查对象属性是否为空。

检查EditText是否为空。 [关闭]

PostgreSQL:根据哪个为空,选择两个字段之一

Python过滤器/最大组合 - 检查空迭代器