我有一个由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在modelform中设置forms.CharField。
答案 0 :(得分:0)
我并没有真正期待这种行为,但是在模型的背景中有很多神奇的标志。我看到了两个解决方案:
更改实例,而不是类。 _meta是一个类变量,因此_meta.get_field将返回类属性。我宁愿尝试像这样操作实例字段
def init (...): self.intro.validators.append(MaxLengthValidator(60))
如果1不起作用,或者您不喜欢它,请保留模型,即不添加验证器,而是将validators添加到用于模型的表单中。你有更多的灵活性,可以做你想做的事。
答案 1 :(得分:0)
每个模型实例未设置validators
。附加MaxLengthValidator
后,您正在更改父类的intro
字段。
我不认为这有一个简单的方法。您可以为每个子模型编写clean()
方法,并在那里执行验证。但是,我认为将intro
字段移动到子类中可能是最好的选择。