我正在尝试准备搜索表单,用户可以在其中输入1,2或全部(在本例中为3个)搜索过滤器。
让我们说搜索过滤器是: 姓氏,电话和地址。我试图通过以下方式过滤queryset:
if filterForm.is_valid():
last_name = filterForm.cleaned_data.get('last_name')
phone= filterForm.cleaned_data.get('phone')
address = filterForm.cleaned_data.get('address')
if last_name is None and phone is None and address is None:
pass
#we dont do search id db
else:
clients = Client.objects.filter(Q(last_name__contains=last_name) | Q(phone=phone) | Q(address__contains=address))
每个搜索键可能都是空白。
不幸的是,它会返回比预期更多的结果。当我输入搜索过滤器"示例"作为姓氏字段,它返回具有此姓氏+许多其他行的所有字段。
知道如何修复此搜索问题吗?
答案 0 :(得分:1)
我认为当任何搜索键为空时,搜索会返回比预期更多的结果,因为空白键会匹配任何带有值的行。
只过滤包含值的键,它应该更好。
以下是如何完成的一个例子:
if filterForm.is_valid():
last_name = filterForm.cleaned_data.get('last_name')
phone= filterForm.cleaned_data.get('phone')
address = filterForm.cleaned_data.get('address')
import operator
predicates = []
if last_name:
predicates.append(Q(last_name__contains=last_name))
if phone:
predicates.append(Q(phone=phone))
if address:
predicates.append(Q(address__contains=address))
if len(predicates) == 0:
# Nothing to search for
pass
else:
clients = Client.objects.filter(reduce(operator.or_, predicates))
上面的代码将动态添加应添加到查询中的过滤器。 oprator.or_
的用法将语句与OR
连接起来(=至少需要满足一个语句)。如果您希望满足所有陈述,则可以使用operator.and_
代替。