在 Django 中从 class 外部使用 super() (或替代它,如果有的话)
Using super() from outside a class in Django (or alternative to it, if any)
以下我使用 Python 2.7 / Django 1.5.
我正在尝试重构一些使用自定义验证程序覆盖 Django 表单的 clean() 方法的生产代码。它在多个表单中重复出现,因此我们想将其抽象为一个外部函数,我们可以在表单中调用它。
假设我有以下内容,
# ... 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
从 class 外部从 my_custom_clean_function 调用 super 会导致超过最大递归深度(只是调用 form_instance class 中的 clean() 方法,调用自定义函数等...
创建 ModelForm 的临时实例并调用它的 clean 方法似乎不起作用,因为它会有 none 个字段。
有什么方法可以按惯用方式执行此操作,还是我最好从表单 class 内部调用父 clean method(),然后将该数据传递给我的自定义方法以进行进一步验证?
你的super(type(instance), instance).clean()
也可以;除非您进一步对表单进行子类化,否则 type(instance)
将是传入的错误对象。
或者在方法中使用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
或者你可以把它做成一个 mixin:
class SharedCleanupMixin:
def clean(self):
cleaned_data = super(SharedCleanupMixin, self).clean()
# other validation routines
return cleaned_data
并在您的表单中使用它:
class MyForm(forms.ModelForm, SharedCleanupMixin):
# ...
以下我使用 Python 2.7 / Django 1.5.
我正在尝试重构一些使用自定义验证程序覆盖 Django 表单的 clean() 方法的生产代码。它在多个表单中重复出现,因此我们想将其抽象为一个外部函数,我们可以在表单中调用它。
假设我有以下内容,
# ... 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
从 class 外部从 my_custom_clean_function 调用 super 会导致超过最大递归深度(只是调用 form_instance class 中的 clean() 方法,调用自定义函数等...
创建 ModelForm 的临时实例并调用它的 clean 方法似乎不起作用,因为它会有 none 个字段。
有什么方法可以按惯用方式执行此操作,还是我最好从表单 class 内部调用父 clean method(),然后将该数据传递给我的自定义方法以进行进一步验证?
你的super(type(instance), instance).clean()
也可以;除非您进一步对表单进行子类化,否则 type(instance)
将是传入的错误对象。
或者在方法中使用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
或者你可以把它做成一个 mixin:
class SharedCleanupMixin:
def clean(self):
cleaned_data = super(SharedCleanupMixin, self).clean()
# other validation routines
return cleaned_data
并在您的表单中使用它:
class MyForm(forms.ModelForm, SharedCleanupMixin):
# ...