Django中的条件嵌套过滤器

时间:2011-05-26 16:36:23

标签: django django-models

我有一个django模型,让我们说:

class Person(models.Model):
   first_name = models.CharField(max_length=25)
   last_name  = models.CharField(max_length=25)

并且,存在一个搜索表单,我可以在其中搜索行,无论是first_name,last_name还是两者。我注意到我可以链接django查询集中的过滤器,例如:

def search(request):
   list = Person.objects.filter(first_name= val1).filter(last_name=val2)

但是如果其中一个值val1,val2为空呢?我应该做点什么:

def searh(request):
   if val1 != null and val2 == null:
      list = Person.objects.filter(first_name= val1)
   if val2 == null and val2 != null:
       list = Person.objects.filter(last_name= val2)
   if val2 != null and val2 != null:
       list = Person.objects.filter(first_name= val1).filter(last_name=val2)

有没有直接的方法来做到这一点?

提前致谢

2 个答案:

答案 0 :(得分:6)

def search(request, val1, val2):
    persons = Person.objects.all()
    if val1:
        persons = persons.filter(first_name=val1)
    if val2:
        persons = persons.filter(last_name=val2)
    return persons

这有效(效率不高)因为Querysets are lazy

答案 1 :(得分:4)

(免责声明:在Python 2.7中测试,Django 1.6,虽然它应该可以正常工作)

我最近介绍了以下直接适用于OP问题的构造:

def search(request, val1, val2):
    filter_args={}
    if val1:
        filter_args["first_name"]=val1
    if val2:
        filter_args["last_name"]=val2

    persons = Person.objects.filter(**filter_args)

    return persons

基本上,这将构建一个包含多个条件的过滤器,即使您不知道先验是否val1val2都可用。它可以使用连接(and)来构造最具体的过滤器,而无需额外的逻辑评估来克服.filter(...).filter(...)总是使用析取来评估标准的事实(or) 。例如,如果稍后要将age添加到您的连接中,只需添加以下两行(和val3到函数参数列表中):

    if val3:
        filter_args["age"]=val3

我在一个项目中使用这种方法我正在努力取得巨大成功,并且认为这些信息对于有这个问题的新Django用户可能会有用。