Python 如何编写基于类的Django验证器?

Python 如何编写基于类的Django验证器?,python,django,validation,class,oop,Python,Django,Validation,Class,Oop,我正在使用Django 1.8 有一个基于函数的验证器示例。它还说明了使用类的以下内容: 对于更复杂或可配置的验证器,您还可以使用带有\uuuu call\uuu()方法的类。例如,RegexValidator使用这种技术。如果在validators model字段选项中使用了基于类的验证器,则应通过添加deconstruct()和\uuuu eq\uuu()方法,确保它可由迁移框架序列化 基于类的验证器和基于函数的验证器的优缺点是什么 \uuuu call\uuuu()用于什么,以及如何使用

我正在使用Django 1.8

有一个基于函数的验证器示例。它还说明了使用类的以下内容:

对于更复杂或可配置的验证器,您还可以使用带有
\uuuu call\uuu()
方法的类。例如,RegexValidator使用这种技术。如果在validators model字段选项中使用了基于类的验证器,则应通过添加
deconstruct()
\uuuu eq\uuu()
方法,确保它可由迁移框架序列化

  • 基于类的验证器和基于函数的验证器的优缺点是什么
  • \uuuu call\uuuu()
    用于什么,以及如何使用
  • deconstruct()
    用于什么,如何使用
  • \uuuu eq\uuuu()
    用于什么,如何使用
举个例子会很有帮助。完整的答案也可能值得在官方文件中提交


谢谢

从一开始,几乎没有什么缺点-除了实现基于类的验证器可能有些复杂

但也有一些优点:yon可以在类实例中保存一些内容以备将来验证,因此不会在每次验证某个内容时计算它,例如编译的正则表达式模式。您还可以通过将代码传播到类中的其他方法来创建更复杂的验证器

此外,您还可以使用一些参数构造验证器,这些参数可以稍后在验证过程中使用


\uuuu调用\uuuu
方法是实际的验证函数-它将像普通的验证函数一样被调用,具有相同的参数(以及附加的
self
参数-类的实例,与所有方法一样)。它不是来自django框架,而是来自python本身。任何类都可以像函数一样被调用,只要它实现了
\uu call\uu
方法<代码>解构方法在中进行了说明<代码>\uuuueq\uuuuuu也来自python本身,每个类都可以有它,它将简单地比较两个对象以检查它们是否相等。

除了能够从
BaseValidator
继承之外,选择函数和基于类的验证器不一定有显著的利/弊。我更喜欢基于类,因为您可以在必要时保持内部状态,而不使其对客户端可见(例如,编译的正则表达式、表中的预计算值、历史记录等)

\uuuuu call\uuuuu
方法使对象可调用,并允许它模拟类似函数的行为(即,可以像函数一样调用对象),并且将调用对象的
\uuuuu call\uuuuu
覆盖。它要求您在验证器中实现特殊的
\uuu调用(self)
方法

class Callable(object):
    def __call__(self,*args,**kwargs):
        print('Calling', args, kwargs)

>>> c = Callable()
>>> c(2, 3, color='red')
Calling (2, 3) {'color': 'red'}
>>>
deconstruct
方法似乎提供了一个点,客户机(即您)可以通过编写自定义实现来覆盖序列化行为。例如,请参见。这似乎类似于
clean
方法,在该方法中,您可以为模型实现自定义输入卫生,并在调用
full\u clean
时自动调用(例如,当表单使用
是否有效时)

\uuuu eq\uuu
允许您在两个本身不可比较的对象之间进行比较。例如,如果您有

class Vector2:
    def __init__(self, x, y):
        self.x = x
        self.y = y
您的
\uuuu eq\uuuu
实现可以如下所示,以检查两个向量对象之间的相等性:

# ...
def __eq__(self, other):
    return self.x == other.x and self.y == other.y

这样,就避免了对底层引用进行肤浅的比较。

验证程序函数的一大优点是它们非常简单。他们只需将一个值作为参数,检查它是否有效,如果无效,则引发
ValidationError
。您不需要担心
解构
均衡
方法来实现迁移

文档中的
validate\u甚至
示例比validator类要简单得多

def validate_even(value):
    if value % 2 != 0:
        raise ValidationError('%s is not an even number' % value)

如果您还需要检查其他数字的可分性,那么创建一个验证器类
validateVisibleBy
是值得的。然后可以使用
validatedvisibleby(2)
validatedvisibleby(3)
等等。但很多时候,验证器功能已经足够好了。

记住接受对您最有帮助的答案。