问题描述
||
我有一个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)
有直接的方法吗?
提前致谢
解决方法
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
这是可行的(不是效率低下),因为查询集是惰性的。
,(免责声明:尽管应该可以正常使用,但已在Python 2.7,Django 1.6中进行了测试)
我最近被介绍了以下结构,该结构直接适用于OP的问题:
def search(request,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
)评估准则的事实。例如,如果以后要在连接词上添加“ 10”,则只需添加以下两行(并将“ 11”添加到函数参数列表):
if val3:
filter_args[\"age\"]=val3
我在正在努力取得成功的项目中使用了这种方法,并且认为此信息对于有相同问题的Django新用户可能有用。