查询多个ManyToMany条件

时间:2015-11-27 15:36:13

标签: python django

假设我有一份技能清单:

skills = ['Python', 'Django', 'Java']

假设我然后执行

Freelancer.object.filter(Q(skills=skills[0]))

两位自由职业者都有这种技能但是尽管查询不是他们的全部曲目我仍然希望他们出现,他们会。我执行:

Freelancer.object.filter(Q(skills=skills[0]) | Q(skills=skills[1]) | Q(skills=skills[3]))

自由职业者有三种技能,所以我希望他出现。自由职业者两个只匹配2/3所以我不希望他出现,但他显然会因为查询。我怎么能这样做?

假设Q可以执行此操作,skills是一个大小为n的列表。是否可以动态执行此查询?

# models.py

class Freelancer(models.Model):
    def __unicode__(self):
        return self.first_name

    user = models.OneToOneField(User)
    first_name = models.CharField(max_length=128)
    surname = models.CharField(max_length=128)
    university = models.CharField(max_length=256)
    biography = models.TextField(default="")
    skills = models.ManyToManyField(Skill, blank=True)
    profile_picture = models.ImageField(blank=True, upload_to='freelancer/images')

    object = UserManager()


class Skill(models.Model):
    skill = models.TextField(primary_key=True, max_length=128)

    def __unicode__(self):
        return self.skill

编辑:

为清楚起见,我提供了视图的POST部分

# views.py

    form = FilterFreelancerForm(request.POST)
    skills = request.POST.getlist('skills_select')

    queries = [Q(skills=s) for s in skills]
    freelancers = Freelancer.object.filter(*queries)

2 个答案:

答案 0 :(得分:1)

您需要多次调用filter,因为在一个过滤器中,JOIN表只能有一个Skills。资料来源:https://docs.djangoproject.com/en/1.8/topics/db/queries/#spanning-multi-valued-relationships

那么为什么不这样试试呢:

freelancers = Freelancer.objects.all()

for skill in skills:
    freelancers = freelancers.filter(skills__skill=skill)

print(list(freelancers))

答案 1 :(得分:1)

您需要使用&(AND)代替|(OR)

skills = ['Python', 'Django', 'Java']
queries = [Q(skill=s) for s in skills]
Freelancer.Object.filter(*queries)

Freelancer.Object.filter(Q(skills=skills[0]) & Q(skills=skills[1]) & Q(skills=skills[3]))