如何使用Django ORM过滤JSONField数组中的子字符串?
Django JSONField数组多元素info字段模糊匹配方案
针对PostgreSQL(推荐,Django对PostgreSQL JSON支持最完善)
直接通过events__info__icontains即可匹配数组中任意元素的info字段,无需指定索引:
from django.db.models import Q MyModel.objects.filter( Q(name__icontains='abc') | Q(events__info__icontains='abc') )
Django在PostgreSQL下会自动解析该查询,生成匹配数组所有元素info字段的SQL语句,实现不区分大小写的子字符串模糊匹配。
如果需要更精确的JSON路径控制,也可以用jsonb_path_exists函数自定义查询:
from django.db.models import Func, F, Q MyModel.objects.filter( Q(name__icontains='abc') | Func( F('events'), "'$[*].info like_regex \"abc\" flag \"i\"'", function='jsonb_path_exists', template="%(function)s(%(expressions)s, %(jsonpath)s::jsonpath)" ) )
针对MySQL
MySQL的JSON支持需要借助JSON_SEARCH函数实现数组元素匹配,可自定义一个Func封装逻辑:
from django.db.models import Q, Func, Value, TextField class JSONSearchIContains(Func): function = 'JSON_SEARCH' template = "%(function)s(%(expressions)s, 'one', %(needle)s, null, '$[*].info') IS NOT NULL" MyModel.objects.filter( Q(name__icontains='abc') | JSONSearchIContains(F('events'), Value('%abc%', output_field=TextField())) )
这里%abc%是MySQL的模糊匹配通配符,结合JSON_SEARCH定位数组中所有info字段,判断是否存在匹配项。
通用注意事项
- 确保
events字段定义为Django 3.1+版本的JSONField,PostgreSQL环境下默认使用JSONBField,查询性能更优。 - 若数据库版本较低,建议升级以支持完整的JSON查询语法。
内容的提问来源于stack exchange,提问作者Pitsoon
相关产品推荐
相关产品推荐

