如何在 DJANGO 中查询包含值列表的 JSONField

问题描述 投票:0回答:2

我使用

JSONField
将配置参数(user_types)存储为列表,如下所示:

["user_type1", "user_type2", "user_type3"]

如何查询过滤“user_type1”类型的元素?以下查询不起作用:

rows=ConfigUserTable.objects.filter(user_types__in=["user_type1"])

谢谢

python json django orm django-jsonfield
2个回答
0
投票

使用

contains
查找,该查找在
JSONField
上被覆盖。例如,以下内容可能有效:

ConfigUserTable.objects.filter(user_types__contains="user_type1")

但是,这可能取决于您在字段中存储 JSON 数据的方式。如果您将数据存储为字典,则查询该键肯定会起作用。 IE。字段中采用此格式的数据

user_types
:

{"types": ["user_type1", "user_type2", "user_type3"]}

可以这样查询:

ConfigUserTable.objects.filter(user_types__types__contains="user_type1")

参考:https://docs.djangoproject.com/en/dev/topics/db/queries/#std:fieldlookup-jsonfield.contains


0
投票

__contains
有效。添加一个答案作为当前答案是一种猜测,Django 文档中没有涵盖这一点。
__icontains
还有一个转折点。

>>> for i in MyModel.objects.all():
>>>     i.aliases = None  # JSONField(null=True)
>>>     i.save()
>>> i.aliases = ['a', 'b', 'abc']
>>> i.save()
>>> MyModel.objects.filter(aliases__contains='a').exists()
True
>>> MyModel.objects.filter(aliases__contains='ab').exists()
False
>>> MyModel.objects.filter(aliases__contains='abc').exists()
True
>>> MyModel.objects.filter(aliases__contains='A').exists()
False
>>> MyModel.objects.filter(aliases__icontains='A').exists()
True
>>> MyModel.objects.filter(aliases__icontains='AB').exists()
True  

最后一个结果让我感到惊讶,因为

i
中的
__icontains
通常意味着不区分大小写,但在本例中,它意味着字符串条目不区分大小写并且部分匹配。

这是 因为 Django 使用

LIKE
进行
i
前缀查找:

>>> MyModel.objects.filter(aliases__contains='ab').exists()
False
>>> print(MyModel.objects.filter(aliases__contains='ab').query)
... WHERE "metadata_livelihoodcategory"."aliases" @> '"ab"' ...

>>> MyModel.objects.filter(aliases__icontains='ab').exists()
True
>>> print(MyModel.objects.filter(aliases__icontains='ab').query)
... WHERE UPPER("metadata_livelihoodcategory"."aliases"::text) LIKE UPPER(%ab%) ...

这里使用

LIKE
有点老套,但非常有用,如果我必须选择,我会选择这种行为。

Postgresql 上的 Django 4.2.7。

aliases
是标准
JSONField
null=True

© www.soinside.com 2019 - 2024. All rights reserved.