如何通过JSON中存储的Decimal值过滤Django QuerySet?
解决Django JSONField中Decimal字符串过滤的问题
问题分析
你遇到的DataError是因为数据库里部分cached_data->price的值是字符串"none",尝试将其转换为Decimal类型时,数据库无法识别这个无效数字格式,从而抛出错误。另外你的annotate写法存在语法错误,不能用字典传参。
解决方案
先过滤掉所有无效的price值(比如字符串"none"、空字符串、JSON null),再将合法的字符串转换为Decimal后进行过滤:
from django.db.models import DecimalField, Cast, Q # 先排除无效值,再转换并过滤 valid_assets = Asset.objects.filter( # 排除值为"none"的记录 ~Q(cached_data__price="none"), # 排除JSON中price为null的记录 cached_data__price__isnull=False, # 排除空字符串的记录 cached_data__price__ne="" ).annotate( # 转换为DecimalField,注意指定精度参数 price_as_decimal=Cast( 'cached_data__price', output_field=DecimalField(max_digits=10, decimal_places=3) ) ).filter(price_as_decimal__gt=100)
关键说明
- 过滤无效值:必须先排除所有无法转换为Decimal的字符串(比如"none"),否则Cast操作会触发数据库错误。
- 修正annotate语法:正确写法是直接传递关键字参数
price_as_decimal=Cast(...),而非字典形式。 - 指定Decimal精度:转换时要给
DecimalField指定max_digits和decimal_places,避免因精度不匹配导致潜在问题。
内容的提问来源于stack exchange,提问作者Vassily
相关产品推荐
相关产品推荐

