def clean(self, value): """ 验证给定的值并将其“清洗”后的值作为合适的Python对象返回。 对任何错误抛出ValidationError。 """ value = self.to_python(value) self.validate(value) self.run_validators(value) return value从 源码分析来看,clean 方法接受一个 value 参数,分别经过三个方法的处理,返回已“清洗”的 value 或者是抛出异常 ValidationError。这个三个方法的源码如下所示:
def to_python(self, value): return value def validate(self, value): if value in self.empty_values and self.required: raise ValidationError(self.error_messages['required'], code='required') def run_validators(self, value): if value in self.empty_values: return errors = [] for v in self.validators: try: v(value) except ValidationError as e: if hasattr(e, 'code') and e.code in self.error_messages: e.message = self.error_messages[e.code] errors.extend(e.error_list) if errors: raise ValidationError(errors)我们分析一下这三个方法的作用。分别如下所示:
class BookField(forms.Field): default_error_message={ 'invalid':'Enter a whole number', 'not_exist':'Book Not Exist', } def to_python(self,num): try: num=int(str(num).strip()) return Book.objects.get(id=num) except (ValueError,TypeError): raise ValidationError(self.error_messages['invalid'],code='invalid') except Exception: raise ValidationError(self.error_messages['not_exist'],code='not_exist')在编写代码的过程中,我们一定要善于参考 Django Field 类的源码,首先理解定义内置字段的过程,然后照葫芦画瓢,实现自定义 Field 字段。BookField 字段继承自 Field 基类,它重写了 to_python 方法,把 num 当做主键去查询 Book 实例,然后将其作实例对象返回。如下所示:
In [1]: from index.forms import BookField In [2]: x=BookField() In [3]: x.clean(1) Out[3]: <Book: title: Python Django pub:PubName object (8) price:59.00>
class AddstrField(forms.CharField): def clean(self,value): return 'C语言中文网 %s'% super().clean(value)AddstrField 该字段在 clean 方法中使用 super 方法调用了父类的 clean(),也就是使用了 CharField 的数据校验方法,这样就很大程度上简化了该功能实现过程,实例演示如下所示:
In [1]: from index.forms import AddstrField In [2]: x=AddstrField() In [3]: x.clean('hello') Out[3]: 'C语言中文网 hello'
#自定义一个验证偶数的验证器,否则抛出异常 def even_validator(value): if value % 2 !=0: raise ValidationError('%d is not a even number'% value) #编写 EvenField字段,只可以接受偶数,否则抛出异常ValidationError class EvenField(forms.IntegerField): #使用构造函数__init__ 对其进行初始化,并添加验证器规则 def __init__(self,**kwargs): super().__init__(validators=[even_validator],**kwargs)实例演示如下所示:
In [1]: from index.forms import EvenField In [2]: x=EvenField() In [3]: x.clean("1") .... ValidationError: ['1 is not a even number'] In [5]: x.clean(2) Out[5]: 2本节我们讲解 Django Form 表单的自定义字段的实现方法。通过本节的学习,你可能会领略到读源码的重要性,善于学习的人,总会找到合适的方法去学习自己想要掌握的知识,在下一节中,我们将讲解 Django Form 表单如何实现自定义验证规则。
Copyright © 广州京杭网络科技有限公司 2005-2025 版权所有 粤ICP备16019765号
广州京杭网络科技有限公司 版权所有