能否在Django过滤器中使用JSONPath谓词筛选嵌套JSONField数据?
Django JSONField递归嵌套筛选方案
核心思路
利用PostgreSQL支持的JSONPath表达式(@?运算符),实现任意嵌套层级的键值匹配,弥补contains(对应@>运算符)无法递归遍历的缺陷。
具体实现
假设你的模型为MyModel,JSONField字段名为data,要匹配任意嵌套位置中mykey等于myValue的对象:
方式一:自定义Func表达式(推荐)
通过Django的Func类封装PostgreSQL的@?运算符,更贴合ORM风格:
from django.db.models import Func, F class JSONPathMatch(Func): function = '@?' template = "%(expressions)s %(function)s %(jsonpath)s" # 构造JSONPath表达式,mykey和myValue为代码字面量 json_path = '$.** ? (@.mykey == "myValue")' matched_objects = MyModel.objects.filter(data=JSONPathMatch(F('data'), jsonpath=json_path))
方式二:直接使用RawSQL
如果需要更灵活的SQL编写,可以直接用原生查询:
from django.db.models import RawSQL json_path = '$.** ? (@.mykey == "myValue")' matched_objects = MyModel.objects.raw( 'SELECT * FROM yourapp_mymodel WHERE data @? %s', [json_path] )
注意要点
- 确保Django版本≥3.1(该版本开始支持JSONField的JSONPath查询)
- PostgreSQL版本需≥12(原生支持JSONPath语法)
- 由于
mykey和myValue是代码字面量,无需处理SQL注入;若涉及用户输入,必须做严格的转义校验
内容的提问来源于stack exchange,提问作者Chris Wesseling
相关产品推荐
相关产品推荐

