我需要通过抽象类添加字段验证器。
我正在使用的代码假设从这个抽象类继承的每个类都有一个字段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)
答案 0 :(得分:2)
...
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
类没有{ {1}}字段。
答案 1 :(得分:0)
在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)