1

我有一个由 2 个孩子继承的抽象模型。在孩子们中,一个是设置一个验证器。当我运行代码时,我看到两个孩子都有验证器。

这是伪代码:

class myAbstract(models.Model):
    Intro         = models.TextField(blank=True, null=True, )

    class Meta:
        abstract = True

class child1(myAbstract):
    class Meta:
         verbose_name = 'child 1'

class child2(myAbstract):
    def __init__(self, *args, **kwargs):
        super(child2, self).__init__(*args, **kwargs)

        intro = self._meta.get_field('Intro')
        intro.validators.append(MaxLengthValidator(60))

     class Meta:
         verbose_name = 'child 2'

在管理员中,如果我添加一个 child1,然后添加一个 child2,则验证器会为 child2 启动并限制字符数。如果我从 child2 开始,那么 child2 不会得到验证器。

这是预期的行为吗?如果有,建议的编码方式是什么?我考虑将 Intro 移至子类。

已解决: 正如 Alasdair 指出的那样,验证器是一个类变量,因此这是预期的行为。

我尝试将 Intro 字段移至孩子,但这没有用。我使用了这个解决方案:
https://stackoverflow.com/a/3209550/757955在模型表单中设置 forms.CharField 。

4

2 回答 2

0

我并没有真正预料到这种行为,但是在模型的背景中有很多神奇的事情发生。我看到了 2 个解决方案:

  1. 更改实例,而不是类。_meta 是一个类变量,因此 _meta.get_field 将返回类属性。我宁愿尝试像这样操作实例字段

    def init (...): self.intro.validators.append(MaxLengthValidator(60))

  2. 如果 1 不起作用,或者您不喜欢它,请不要理会模型,即不要添加验证器,而是将验证器添加到您用于模型的表单中。在那里你有更多的灵活性,可以做你想做的事。

于 2012-08-21T21:12:13.163 回答
0

validators不是为每个模型实例设置的。附加 时MaxLengthValidator,您正在更改intro父类的字段。

我不认为有一个简单的方法来解决这个问题。您可以为每个子模型编写一个clean()方法,并在那里执行验证。但是,我认为将intro字段移到子类中可能是最好的选择。

于 2012-08-21T21:12:21.920 回答