我有一个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)
有没有直接的方法来做到这一点?
提前致谢
答案 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
基本上,这将构建一个包含多个条件的过滤器,即使您不知道先验是否val1
和val2
都可用。它可以使用连接(and
)来构造最具体的过滤器,而无需额外的逻辑评估来克服.filter(...).filter(...)
总是使用析取来评估标准的事实(or
) 。例如,如果稍后要将age
添加到您的连接中,只需添加以下两行(和val3
到函数参数列表中):
if val3:
filter_args["age"]=val3
我在一个项目中使用这种方法我正在努力取得巨大成功,并且认为这些信息对于有这个问题的新Django用户可能会有用。