我需要通过一个抽象类,添加一个字段验证。
我正在使用的代码假设每类从这个抽象类继承有一个字段name
,但这个领域本身不是抽象类定义的不幸。
所以我尝试以下,但我不知道什么是寻找在self._meta.fields
领域的好办法,因为这是一个列表??
class AbsClass(models.Model):
class Meta:
abstract = True
def __init__(self, *args, **kw):
super(AbsClass, self).__init__(*args, **kw)
name_field = [f for f in self._meta.fields if f.name == 'name'][0] # Is there another way?
name_field.validators.append(my_validator)
...
name_field = self._meta.get_field('name')
name_field.validators.append(my_validator)
...
你的方法但是,似乎不是一个好主意:你模型的现场实例模型的所有实例之间共享(它们的引用都存储在一个类的属性,而不是在实例属性)。这意味着,每次你实例化模型的对象时,你会被添加my_validator
的另一个副本到外地的验证,因为你将它添加到同一个字段实例。
你可以实现一个元类为你的抽象基类,并添加在编译的时候验证,而不是在运行时现场的情况下,沿此(未测试)线的东西篡改:
from django.utils.six import with_metaclass
from django.db.models.base import ModelBase
# inherit from Django's model metaclass
class AbsClassMeta(ModelBase):
def __new__(cls, name, bases, attrs):
if 'name' in attrs:
attrs['name'].validators.append(my_validator)
elif name != 'AbsClass':
# is it an error to not have a "name" field in your subclasses?
# handle situation appropriately
return super(AbsClassMeta, cls).__new__(cls, name, bases, attrs)
class AbsClass(with_metaclass(AbsClassMeta, models.Model)):
...
请注意,您AbsClass
类本身也将使用此元类来创建。如果你决定抛出一个异常,在AbsClassMeta.__new__
如果类没有name
场,你需要考虑到这一点,因为你的AbsClass
类没有name
场。
在Django的2.X
代替
name_field = self._meta.get_field('name')
name_field.validators.append(my_validator)
你可以做:
name_field = self.fields['name']
password_field.validators.append(my_validator)