Django搜索多个过滤器

时间:2010-12-15 13:34:39

标签: python django django-forms

让我说我有一个模特

models.py

class user:
    name = models.CharField(max_length=25)

class job:
    job_name = models.CharField(max_length=25)

class user_job:
    user = models.ForeignKey('user')
    job  = models.ForeignKey('job')

forms.py

 jobs = (
     ('0', 'a'),
     ('1', 'b'),
     ('2', 'c'),
 )

 class searchForm:
     box = forms.ModelMultipleChoiceField(
                                          choices = jobs,
                                          widget  = forms.CheckboxSelectMultiple(),
                                          label   = 'Search',
                                         )

我可以搜索有

作业'a'的用户
user_job.objects.filter(job__exact = 'a') ...

我试图搜索同时拥有工作'a'和工作'c'的用户

search_q = user_job.objects.filter(job__exact = 'a')
search_q = search_q.filter(job__exact = 'c')

但是我让所有用户都有'a'作业'c',我需要所有这两个工作的用户。

有没有办法可以通过Django过滤它,或者我是否需要过滤一个作业然后迭代结果并检查第二个作业?

1 个答案:

答案 0 :(得分:9)

您可能会发现从User模型中搜索更容易,因为您想要的是同时拥有这两项工作的Users列表。 Django会自动在模型上设置属性,允许您从模型实例和数据库查询中访问相关模型。

假设你设置了这样的模型:

from django.db import models

class User(models.Model):
    name = models.CharField(max_length=25)

    def __repr__(self):
        return '<User: %s>' % self.name

class Job(models.Model):
    name = models.CharField(max_length=25)

    def __repr__(self):
        return '<Job: %s>' % self.name

class UserJob(models.Model):
    user = models.ForeignKey(User)
    job = models.ForeignKey(Job)

    def __repr__(self):
        return '<UserJob: %s %s>' % (self.user.name, self.job.name)

并填写如下:

u1 = User.objects.create(name='u1')
u2 = User.objects.create(name='u2')
u3 = User.objects.create(name='u3')

a = Job.objects.create(name='a')
b = Job.objects.create(name='b')
c = Job.objects.create(name='c')

UserJob.objects.create(user=u1, job=a)
UserJob.objects.create(user=u2, job=a)
UserJob.objects.create(user=u2, job=b)
UserJob.objects.create(user=u3, job=a)
UserJob.objects.create(user=u3, job=c)

以下查询将返回用户3,这是唯一同时拥有“作业a”和“作业c”的用户:

u = User.objects.filter(userjob__job=a).filter(userjob__job=c)

(或者,如果您更喜欢按名称而不是Job实例引用作业):

u = User.objects.filter(userjob__job__name='a').filter(userjob__job__name='c')

您可以看到Django如何允许您使用双下划线表示法将User模型中的相关字段遍历到UserJob模型(此处的Django文档位于此处:{{3} }。

一旦获得User对象,您可以使用Django添加到模型的关系属性来类似地访问UserJob实例:

u = User.objects.filter(userjob__job__name='a').filter(userjob__job__name='c')
jobs = u.userjob_set.all()