如何编写Django QuerySet去除JSONField指定键值的空格
解决Django QuerySet更新JSONField指定键去空格的问题
核心方案(针对PostgreSQL)
因为Django的F()对象不支持直接调用Python字符串方法(比如strip),必须借助数据库原生函数处理JSON字段的指定键。以下是两种可行方案:
方案一:使用RawSQL直接执行原生SQL
利用PostgreSQL的TRIM函数去除空格,再通过jsonb_set(对应JSONBField)或json_set(对应JSONField)更新原JSON字段:
from django.db.models import RawSQL # 批量更新key_1和key_2 MyModel.objects.update( properties=RawSQL( "jsonb_set(jsonb_set(properties, '{key_1}', TRIM(properties->>'key_1')::jsonb), '{key_2}', TRIM(properties->>'key_2')::jsonb)", [] ) )
关键语法说明:
properties->>'key_1':提取JSON字段中key_1的纯文本值(自动去除字符串两端的引号)TRIM(...):数据库层面去除字符串两端空格jsonb_set(原字段, 键路径, 新值):将处理后的值写回JSON字段的对应键,{key_1}是键的路径格式,::jsonb是把处理后的字符串转成JSONB类型- 如果你的
properties是JSONField而非JSONBField,把jsonb_set换成json_set,::jsonb换成::json
方案二:用Django Func表达式封装(更贴合ORM风格)
自定义Func类封装数据库函数,避免直接写原生SQL:
from django.db.models import Func, Value from django.db.models.fields.json import KeyTextTransform # 封装TRIM函数 class Trim(Func): function = 'TRIM' # 封装jsonb_set函数 class JsonbSet(Func): function = 'jsonb_set' arity = 3 # 指定函数接收3个参数 # 更新key_1 MyModel.objects.update( properties=JsonbSet( 'properties', Value('{key_1}'), Trim(KeyTextTransform('key_1', 'properties')) ) ) # 更新key_2 MyModel.objects.update( properties=JsonbSet( 'properties', Value('{key_2}'), Trim(KeyTextTransform('key_2', 'properties')) ) )
之前尝试出错的原因
F("properties_key_1").strip():F对象是数据库字段的引用,没有Python的strip方法,必须用数据库原生函数处理RawSQL(...).strip():strip是Python字符串方法,不能调用在RawSQL对象上,要把TRIM写在SQL语句内部- 第三个尝试的语法错误:
RawSQL必须传入第二个参数(参数列表,空的话传[]),且你写错了键名(asset_class应为key_1)
内容的提问来源于stack exchange,提问作者Ben2pop
相关产品推荐
相关产品推荐

