有很多类似的问题,但我只找到了部分解决方案.我有一组用户作为对象存储,有一个名称属性(User.name)。 我希望用用户输入(Foo)来做一个查询,这样我就可以(在不区分大小写的情况下)找到所有用户,其中有一个人。
举个例子,我希望用户能够输入 "Jeff William II",并返回 "Anderson Jeff William II"、"jeff william iii",以及 "Jeff Will "和 "william ii"
我知道我可以用 Q功能 来组合两个查询,我可以使用annotate()来转换User.name,就像这样(如果你发现这段代码中有错误,我欢迎编辑)。
users = User.objects.annotate(name_upper=Upper(name)).filter(Q(name_upper__icontains=foo) | Q(name_upper__in=foo))
但我在使用 __in
来匹配一个字符串中的多个字母。 因此,如果User.name是 "F",我在输入Jeff时就会被击中,但如果User.name是 "JE",那么就不会显示出来。 如何匹配多个字母,或者说有没有更好的方法来做这个查询?
附注:我最初用下面的方法解决了这个问题,但如果可能的话,我更倾向于做一个查询。
for u in User.objects.all():
if u.name in foo or foo in u.name:
请做 不 使用 Upper
. 一个常见的误解是,通过将两个项目转换为大写(或小写),你可以进行大小写不敏感的平等检查。某些字符,如ß没有大写小写,并且有更复杂的规则(整理)来考虑这些字符的等价性。在 Python 中,我们使用 .casefold(…)
[python-doc] 来实现。
对于数据库,你可以简单地利用annotate,然后使用两个检查。
from django.db.models import CharField, F, Q, Value
foo = 'Jeff William II'
User.objects.annotate(foo=Value(foo, CharField())).filter(
Q(name__icontains=foo) | Q(foo__icontains=F('name'))
)