【问题标题】:django: model inheritance and validators in admindjango:管理员中的模型继承和验证器
【发布时间】:2012-08-21 20:07:41
【问题描述】:

我有一个由 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。

【问题讨论】:

    标签: django


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

        def 初始化(...): self.intro.validators.append(MaxLengthValidator(60))

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

      【讨论】:

      • 在模型表单中设置验证器是个好主意。但是第一个建议不起作用,因为self.intro 是字段的值,所以没有validators 属性。
      猜你喜欢
      • 2014-05-21
      • 2012-09-18
      • 2018-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-14
      相关资源
      最近更新 更多