Django的 - 在__init__添加模型字段验证

问题描述 投票:1回答:2

我需要通过一个抽象类,添加一个字段验证。

我正在使用的代码假设每类从这个抽象类继承有一个字段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)
django django-admin django-models
2个回答
2
投票

您需要Options.get_field

...
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场。


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)
© www.soinside.com 2019 - 2024. All rights reserved.