Django表单字段验证器触发AttributeError问题求助
解决Django自定义验证器中的'NoneType' has no attribute 'isdecimal'错误
你的问题核心出在自定义验证器没有处理value为None的边缘情况——虽然理论上CharField(默认required=True)应该不会把None传给验证器,但实际验证流程中可能存在一些你没注意到的场景(比如表单初始化时传入了None值、AJAX提交时字段缺失但意外绕过了必填校验,或者旧版本Django的字段处理逻辑差异),导致验证器接收到了None值,调用isdecimal()方法时触发报错。
而把验证器移到表单clean函数后能正常运行,是因为cleaned_data里的value已经经过了字段的to_python()处理,会把None转换成空字符串"",不会出现None的情况,自然不会触发属性错误。
修复方案
在验证器开头先添加对None和空值的判断,提前拦截这种情况,同时修正你原来导入语句的语法错误:
from django.core.exceptions import ValidationError from django.utils.translation import ugettext_lazy def validate_value(value): # 先处理None或空字符串的情况 if value is None or not value: # 如果字段是必填的,Django本身会处理必填校验,这里也可以自定义错误信息 raise ValidationError(ugettext_lazy('This field cannot be empty.')) if value.isalpha(): if len(value) != 1: raise ValidationError( ugettext_lazy('Invalid zone value: %(value)s'), params={'value': value} ) elif value.isdecimal(): if int(value) == 0: raise ValidationError( ugettext_lazy('Invalid zone value: %(value)s'), params={'value': value} ) else: raise ValidationError( ugettext_lazy('Invalid zone value: %(value)s'), params={'value': value} )
这样修改后,验证器就能处理所有可能的输入情况,既保留了独立验证器的复用性,又避免了None值引发的崩溃。
内容的提问来源于stack exchange,提问作者Jerry Bi
相关产品推荐
相关产品推荐

