使用Django在PostgreSQL的ArrayField上进行不区分大小写的查询

11

Django文档中的ArrayField列出了一个contains字段查找。然而,ArrayField中没有icontains(不区分大小写查找 - 许多其他字段都有)查找。

我需要一个类似于现有contains查找的ArrayField不区分大小写的查找函数。

3个回答

8

警告:这是一种黑客行为,可能会导致我的应用程序出现错误。请自行承担风险。


您可以使用 icontains 进行不区分大小写的查找,只需省略您用于 contains 的方括号:

queryset = my_model.objects.filter(field_name__icontains='my_substring')

这是有效的,因为Postgres将ArrayField转换为文本,然后检查'my_substring'是否为数组文本表示的子字符串。您可以通过检查生成的查询来查看此操作:
print(queryset.query)

# raw SQL output:
'SELECT ... WHERE UPPER("my_model"."field_name"::text) LIKE UPPER(%my_substring%)

这在我的Postgres 10.1中有效。


附录/错误

这种方法在我的项目中引起了一个错误。比如你想检查数组字段是否包含'my_substring'

field_name__icontains='my_substring'

这将检索'my_substring',但它也将检索'foo_my_substring'。这与上面提到的字符串转换有关。使用时请自行决定风险。


我尝试使用这个查询性别,结果返回了女性和男性,哈哈。 - Sabrina Leggett
小心!这并没有回答原问题,正如Stevula在他的回答末尾所承认的那样,如果表中有其他包含你要查找的字符串的字符串,它甚至会导致错误。应该使用@quick answer。 - GuiTeK

4

icontainsiexact仅适用于字符串类型:

my_array_field__contains=['H'] 

检查['H']是否包含在my_array_field中。但是,如果您尝试以下操作,它将起作用:
my_array_field__0__icontains='H'

因为它检查第一个元素是否包含 H 或 h。

3
您可以这样查询不区分大小写的数组:
select 'tartu' ILIKE ANY (array['Tallinn', 'Tartu','Narva']);

在Django中:
MyModel.objects.extra(
    where=['%s ILIKE ANY (array_column_name)'],
    params=['tartu', ]
)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接