过滤Django数据库以获取包含数组中任何值的字段

时间:2012-01-20 23:24:59

标签: python django django-models

我有一个django模型和一个代表用户全名的字段。我的客户希望我设置一个过滤器,根据字符串数组搜索用户,其中所有字符串都必须不区分大小写,包含在全名中。

例如

如果是用户full_name = "Keith, Thomson S."

我有一个列表['keith','s','thomson']

我想执行相当于

的过滤器
Profile.objects.filter(full_name__icontains='keith',full_name__icontains='s',full_name__icontains='thomson')

问题是这个列表可能是动态大小的 - 所以我不知道该怎么做。

有人有什么想法吗?

3 个答案:

答案 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想要同时包含所有字符串的名称。