PostgreSQL环境下Django JSON字段筛选异常:content__title__value过滤返回空数组
解决JSON嵌套字段筛选返回空数组的问题
问题背景
你的数据结构为嵌套JSON:
{"title": {"value": "dene", "type": null}, "description": {"value": "desc", "type": null}, "detay": {"value": "det", "type": "text"}, "tarih": {"value": "2024-05-02", "type": "date"}}
尝试用objects.filter(content__title__value='dene')筛选时返回空数组,以下是针对性解决方法:
排查与解决步骤
1. 确认字段类型是否为JSONField
先检查模型中content字段的定义,必须是JSONField而非普通TextField:
from django.db import models class YourModel(models.Model): content = models.JSONField() # 确保是该类型,若用TextField存储JSON,ORM无法解析嵌套结构 # 其他字段...
2. 适配不同数据库的JSON查询语法
不同数据库对嵌套JSON的查询支持有差异:
- PostgreSQL:
若双下划线查询失效,可尝试两种替代方式:# 方式1:用KeyTextTransform拆解嵌套字段 from django.db.models.fields.json import KeyTextTransform YourModel.objects.annotate( title_value=KeyTextTransform('value', KeyTextTransform('title', 'content')) ).filter(title_value='dene') # 方式2:原生SQL查询 YourModel.objects.raw("SELECT * FROM your_table WHERE content->'title'->>'value' = %s", ['dene']) - MySQL/SQLite:
部分版本对双下划线嵌套查询支持有限,可改用以下方式:# 用contains匹配完整嵌套结构 YourModel.objects.filter(content__contains={'title': {'value': 'dene'}}) # MySQL原生查询 YourModel.objects.raw("SELECT * FROM your_table WHERE JSON_UNQUOTE(JSON_EXTRACT(content, '$.title.value')) = %s", ['dene'])
3. 验证数据库中是否存在目标数据
直接在数据库执行SQL确认数据是否存在:
-- PostgreSQL SELECT * FROM your_table WHERE content->'title'->>'value' = 'dene'; -- MySQL SELECT * FROM your_table WHERE JSON_UNQUOTE(JSON_EXTRACT(content, '$.title.value')) = 'dene';
如果数据库中也查不到,说明是数据本身的问题,而非查询语法错误。
4. 检查Django版本兼容性
Django 3.1以下版本对JSONField嵌套查询支持不完善,建议升级到3.1及以上版本。
内容的提问来源于stack exchange,提问作者Muharrem ustaoglu
相关产品推荐
相关产品推荐

