基于ManyToManyField的过滤-如果列表中存在项目,则获取记录

时间:2019-02-14 03:36:20

标签: python django

我想知道是否有一种方法可以基于ManyToManyField字段进行过滤。我知道有一个__in过滤器,但是似乎此过滤器需要一个ID,而我没有一个ID(我可以获取这些ID,但我想知道是否可以不使用它)。 这就是我的模型的样子

class modelEmployee(models.Model):
    user                = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
    title               = models.CharField(max_length=200, unique=False, blank=False, null=True)
    skills              = models.ManyToManyField(modelSkill, blank=True)

class modelJob(models.Model):
    skills              = models.ManyToManyField(modelSkill,blank=True)
    title               = models.CharField(max_length=200, unique=False,blank=False,null=True)

这是多对多的模型

class modelSkill(models.Model):
    skill_description   = models.CharField(max_length=50, unique=True)

现在我有一个看起来像这样的列表

  skillList = [SkillA,SkillB,SkillC...] #Description field

目前我无法做到这一点

modelJob.objects.filter(skills__in=skillList)

我无法执行上述操作的原因是因为Skills__in希望获得的列表中包含该技能的ID号而不是该技能的其他字段。我的问题是如何告诉技能__,因为我传递的列表是skill_description中的modelSkill而不是ID?

更新: 如果我这样做

  queryset_list = modelEmployee.objects.filter(skills___skill_description__in=skill_filter)

我得到了错误

raise FieldError('Related Field got invalid lookup: {}'.format(lookups[0]))
django.core.exceptions.FieldError: Related Field got invalid lookup: _skill_description

1 个答案:

答案 0 :(得分:1)

您可以更深入地研究一个级别,并专门匹配skill_description字段:

modelJob.objects.filter(skills__skill_description__in=skillList)

来自Django文档:

  

例如,如果某个条目具有一个称为标签的ManyToManyField,我们可能想要查找链接到名为“ music”和“ bands”的标签的条目,或者我们想要一个包含名称为“ music”的标签的条目,并且状态为“公开”。

     

要处理这两种情况,Django有一致的处理filter()调用的方式。单个filter()调用中的所有内容将同时应用,以过滤出符合所有这些要求的项目。连续的filter()调用进一步限制了对象的集合,但是对于多值关系,它们适用于链接到主模型的任何对象,不一定适用于先前的filter()调用选择的那些对象。

     

这听起来可能有些混乱,所以希望可以阐明一个例子。要选择所有标题都包含“ Lennon”并且在2008年发布的博客(满足两个条件的同一个博客),我们将这样写:

Blog.objects.filter(entry__headline__contains='Lennon', entry__pub_date__year=2008)

https://docs.djangoproject.com/en/2.1/topics/db/queries/#spanning-multi-valued-relationships