Django QuerySet调用len()报错TypeError:参数必须为int或float
问题原因分析
报错的核心是SQLite数据库中某DecimalField字段存储了非数字类型的值,导致Django在将数据库值转换为Python的Decimal对象时失败。
从错误栈能看到,最终触发错误的位置是SQLite的Decimal转换器:它尝试把数据库读取到的值转成Decimal,但该值不是int或float类型(比如是空字符串、非数字字符串,或是SQLite中存储的其他类型数据)。
SQLite是弱类型数据库,即使你在Django模型里定义了DecimalField,也可能被插入不符合要求的值,Django在查询加载数据时就会抛出这个类型错误。
解决步骤
1. 定位问题字段和错误数据
首先找出SignalSma模型中所有的DecimalField(比如value、sma_value这类字段),然后直接查询SQLite数据库,找出非法数据:
- 执行SQL查询(替换
your_decimal_field为你的字段名,signal_sma为表名,表名一般是appname_modelname小写):
-- 找非数字类型的记录 SELECT * FROM signal_sma WHERE typeof(your_decimal_field) NOT IN ('integer', 'real'); -- 或者找空字符串的情况 SELECT * FROM signal_sma WHERE your_decimal_field = '';
2. 修复数据库中的错误数据
根据业务逻辑处理找到的错误记录:
- 把非法值替换为合法数字(比如0,或业务允许的默认值):
UPDATE signal_sma SET your_decimal_field = 0 WHERE your_decimal_field = '';
- 或者直接删除无效记录:
DELETE FROM signal_sma WHERE typeof(your_decimal_field) NOT IN ('integer', 'real');
3. 避免后续再出现该问题
- 数据写入校验:所有写入该模型的操作(表单、API接口、后台脚本)都要严格验证数据,确保只有合法的数字(或NULL,如果字段允许空)被写入。
- 模型字段强化约束:
- 如果字段不允许为空,设置
blank=False,强制写入端必须提供合法值; - 如果允许为空,设置
null=True,并确保写入空值时存的是NULL而非空字符串; - 添加字段验证器,示例:
from django.core.validators import DecimalValidator class SignalSma(models.Model): sma_value = models.DecimalField( max_digits=10, decimal_places=2, validators=[DecimalValidator(max_digits=10, decimal_places=2)] )
- 如果字段不允许为空,设置
内容的提问来源于stack exchange,提问作者Agustin Gonzalez Ribas
相关产品推荐
相关产品推荐

