我使用
JSONField
将配置参数(user_types)存储为列表,如下所示:
["user_type1", "user_type2", "user_type3"]
如何查询过滤“user_type1”类型的元素?以下查询不起作用:
rows=ConfigUserTable.objects.filter(user_types__in=["user_type1"])
谢谢
使用
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
__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
。