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

xiz*_*zor 26 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')
Run Code Online (Sandbox Code Playgroud)

问题是这个列表可以是动态大小 - 所以我不知道如何做到这一点.

有人有主意吗?

Ism*_*awi 50

连续拨打电话filter,如下:

queryset = Profile.objects.all()
strings = ['keith', 's', 'thompson']
for string in strings:
    queryset = queryset.filter(full_name__icontains=string)
Run Code Online (Sandbox Code Playgroud)

或者你可以&把一堆Q对象放在一起:

condition = Q(full_name__icontains=s[0])
for string in strings[1:]:
    condition &= Q(full_name__icontains=string)
queryset = Profile.objects.filter(condition) 
Run Code Online (Sandbox Code Playgroud)

写一个更神秘的方法,避免显式循环:

import operator
# ...
condition = reduce(operator.and_, [Q(full_name__icontains=s) for s in strings])
queryset = Profile.objects.filter(condition)
Run Code Online (Sandbox Code Playgroud)

  • @isbadawi,+ 1 - 请注意,多个Q对象的默认运算符是AND,因此您可以只使用`*[Q1,Q2,Q3]`而不使用reduce/operator.and_. (3认同)

C14*_*14L 8

甚至更短的使用operator功能and_or_组合Q()条件列表

from operator import and_, or_
li = ['keith', 's', 'thompson']
Run Code Online (Sandbox Code Playgroud)

匹配所有字符串的项目(and_)

Profile.objects.filter(reduce(and_, [Q(full_name__icontains=q) for q in li]))
Run Code Online (Sandbox Code Playgroud)

与任何字符串匹配的项目(or_)

Profile.objects.filter(reduce(or_, [Q(full_name__icontains=q) for q in li]))
Run Code Online (Sandbox Code Playgroud)

Q()函数实现__or__()并将__and__()两个Q()对象连接在一起,因此可以使用相应的operator函数调用它们.