Django查询与大小写不敏感的数据双向查询

问题描述 投票:1回答:1

有很多类似的问题,但我只找到了部分解决方案.我有一组用户作为对象存储,有一个名称属性(User.name)。 我希望用用户输入(Foo)来做一个查询,这样我就可以(在不区分大小写的情况下)找到所有用户,其中有一个人。

  1. foo在User.name中
  2. 用户名在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:
django django-queryset case-insensitive
1个回答
1
投票

请做 使用 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'))
)
© www.soinside.com 2019 - 2024. All rights reserved.