For the following I am using Python 2.7 / Django 1.5.
对于以下我使用的是Python 2.7 / Django 1.5。
I am trying to refactor some production code which overrides Django form's clean() method with a custom validation procedure. It is repeated in several of the forms so we want to abstract it to an external function that we can just call within the forms.
我试图重构一些生产代码,它使用自定义验证程序覆盖Django form的clean()方法。它以几种形式重复,因此我们想将它抽象为我们可以在表单中调用的外部函数。
Say I have the following,
说我有以下,
# ... imports ...
class MyProperties(models.Model):
label = models.CharField(max_length=100, blank=True, null=True, verbose_name=u'label'
def __unicode__(self):
return self.label
class MyForm(forms.ModelForm):
choices = forms.ModelChoiceField(required=False, ...)
class Meta:
model = MyProperties
def __init__(self, *args, **kwargs):
super(MyForm, self).__init__(*args, **kwargs)
def clean(self):
return my_custom_clean_function(self)
def my_custom_clean_function(form_instance):
cleaned_data = super(type(form_instance), form_instance).clean() ## DOES NOT WORK
# other validation routines
return cleaned_data
Calling super from the my_custom_clean_function from outside the class leads to exceeding the maximum recursive depth (is just calls the clean() method in the form_instance class, which calls the custom function, etc...
从类外部调用my_custom_clean_function中的super导致超出最大递归深度(只调用form_instance类中的clean()方法,该方法调用自定义函数等...
Creating a temp instance of ModelForm and calling it's clean method does not seem to work, since it would have none of the fields.
创建ModelForm的临时实例并调用它的clean方法似乎不起作用,因为它没有任何字段。
Is there any way to do this idiomatically, or would I be better off calling the parent clean method() from inside the form class, and then passing that data to my custom method for further validation?
有没有办法以惯用方式执行此操作,或者我最好从表单类中调用parent clean method(),然后将该数据传递给我的自定义方法以进行进一步验证?
1 个解决方案
#1
1
Your super(type(instance), instance).clean()
works too; unless you are subclassing your forms further, at which point type(instance)
would be the wrong object to pass in.
你的超级(类型(实例),实例).clean()也可以工作;除非你进一步继承你的表单,否则type(instance)将是传入的错误对象。
Alternatively use super()
in the method and pass that result in:
或者在方法中使用super()并将结果传递给:
class MyForm(forms.ModelForm):
# ...
def clean(self):
return my_custom_clean_function(super(MyForm, form_instance).clean())
def my_custom_clean_function(cleaned_data):
# other validation routines
return cleaned_data
Or you could just make it a mixin:
或者你可以把它变成一个混合:
class SharedCleanupMixin:
def clean(self):
cleaned_data = super(SharedCleanupMixin, self).clean()
# other validation routines
return cleaned_data
and use that in your forms:
并在表单中使用它:
class MyForm(forms.ModelForm, SharedCleanupMixin):
# ...
#1
1
Your super(type(instance), instance).clean()
works too; unless you are subclassing your forms further, at which point type(instance)
would be the wrong object to pass in.
你的超级(类型(实例),实例).clean()也可以工作;除非你进一步继承你的表单,否则type(instance)将是传入的错误对象。
Alternatively use super()
in the method and pass that result in:
或者在方法中使用super()并将结果传递给:
class MyForm(forms.ModelForm):
# ...
def clean(self):
return my_custom_clean_function(super(MyForm, form_instance).clean())
def my_custom_clean_function(cleaned_data):
# other validation routines
return cleaned_data
Or you could just make it a mixin:
或者你可以把它变成一个混合:
class SharedCleanupMixin:
def clean(self):
cleaned_data = super(SharedCleanupMixin, self).clean()
# other validation routines
return cleaned_data
and use that in your forms:
并在表单中使用它:
class MyForm(forms.ModelForm, SharedCleanupMixin):
# ...