You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中JsonField字典列表的ILIKE模糊查询实现咨询

无需原生SQL的实现方案

针对Django JsonField数组内字典key值的全局模糊查询,有两种纯ORM的实现方式,无需手写原生SQL:

方案一:数组展开+子查询(兼容JsonField)

通过自定义数据库函数展开thing数组,再用Exists子查询判断是否存在匹配元素:

from django.db.models import Exists, OuterRef, Func, TextField

# 自定义函数:展开JSON数组中的thing元素
class JsonArrayElements(Func):
    function = 'json_array_elements'
    template = "%(function)s(%(expressions)s::json -> 'thing')"
    output_field = TextField()

# 构造子查询,检查当前对象的thing数组中是否有key包含目标字符串
subquery = ClassName.objects.filter(
    id=OuterRef('id'),
    # 提取展开后元素的key值,进行icontains匹配
    data=Func(
        JsonArrayElements('data'),
        function='->>',
        template="%(expressions)s ->> 'key'",
        output_field=TextField()
    ).icontains('wo')
)

# 执行主查询,只保留存在匹配的对象
matched_objects = ClassName.objects.filter(Exists(subquery))

方案二:JSONPath查询(PostgreSQL+JSONBField推荐)

如果项目使用PostgreSQL,且字段定义为JSONBField(比JsonField更高效),可直接用JSONPath正则匹配实现:

from django.db.models import Func, BooleanField

# 自定义函数:使用JSONPath检查模糊匹配
class JsonPathLike(Func):
    function = 'jsonb_path_exists'
    # JSONPath表达式:匹配thing数组中任意元素的key,不区分大小写包含"wo"
    template = "%(function)s(%(expressions)s, '$.thing[*].key like_regex \"wo\" flag \"i\"')"
    output_field = BooleanField()

# 直接过滤符合条件的对象
matched_objects = ClassName.objects.filter(JsonPathLike('data'))

关键说明

  • 方案一兼容标准JsonField,通过模拟json_array_elements的行为实现数组遍历,适用于多数支持JSON函数的数据库。
  • 方案二依赖PostgreSQL的JSONB特性,语法更简洁、查询效率更高,推荐在PostgreSQL环境下使用。
  • 两种方案完全基于Django ORM,避免了手写原生SQL的维护成本。

内容的提问来源于stack exchange,提问作者lebedev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 07:32:36