我有一个django模型和一个代表用户全名的字段。我的客户希望我设置一个过滤器,根据字符串数组搜索用户,其中所有字符串都必须不区分大小写,包含在全名中。
例如
如果是用户full_name = "Keith, Thomson S."
我有一个列表['keith','s','thomson']
我想执行相当于
的过滤器Profile.objects.filter(full_name__icontains='keith',full_name__icontains='s',full_name__icontains='thomson')
问题是这个列表可能是动态大小的 - 所以我不知道该怎么做。
有人有什么想法吗?
答案 0 :(得分:41)
连续拨打filter
,如下:
queryset = Profile.objects.all()
strings = ['keith', 's', 'thompson']
for string in strings:
queryset = queryset.filter(full_name__icontains=string)
或者,您可以&
一起使用Q
个对象:
condition = Q(full_name__icontains=s[0])
for string in strings[1:]:
condition &= Q(full_name__icontains=string)
queryset = Profile.objects.filter(condition)
更加神秘的写作方式,避免显式循环:
import operator
# ...
condition = reduce(operator.and_, [Q(full_name__icontains=s) for s in strings])
queryset = Profile.objects.filter(condition)
答案 1 :(得分:8)
使用operator
函数and_
或or_
组合Q()
条件列表
from operator import and_, or_
li = ['keith', 's', 'thompson']
匹配所有字符串(and_
)
Profile.objects.filter(reduce(and_, [Q(full_name__icontains=q) for q in li]))
与任何字符串(or_
)
Profile.objects.filter(reduce(or_, [Q(full_name__icontains=q) for q in li]))
Q()
函数实现__or__()
和__and__()
将两个Q()
对象连接在一起,因此可以使用相应的operator
函数调用它们。
答案 2 :(得分:2)
这些内容:
array = ['keith', 's', 'thomson']
regex = '^.*(%s).*$' % '|'.join(array)
Profile.objects.filter(full_name__iregex=regex)
编辑:这是错误的,OP想要同时包含所有字符串的名称。