Django将kwargs传递给继承的表单会导致错误(通用UpdateView)

时间:2015-03-27 13:07:03

标签: python django forms generics

当我使用django泛型视图 - UpdateView并尝试像这样更新表单kwargs时:

#views.py

from .forms import SomeInheritedForm
from .models import SomeModel

from django.views.generic import UpdateView

class SomeUpdateView(UpdateView):
    model = SomeModel
    form_class = SomeInheritedForm

    def get_form_kwargs(self, **kwargs):
        kwargs = super(SomeUpdateView, self).get_form_kwargs(**kwargs)
        kwargs['workspace'] = 'whatever'
        return kwargs

#forms.py

from .models import SomeModel

from django import forms

class ParentForm(forms.Form):
    def __init__(self, *args, **kwargs):
        self.workspace = kwargs.pop('workspace', None)
        super(ParentForm, self).__init__(*args, **kwargs)

class InheritedForm(forms.ModelForm, ParentForm):
    class Meta:
        model = SomeModel

这会产生这样的错误:

Django Version: 1.7.2
Exception Type: TypeError
Exception Value:    
__init__() got an unexpected keyword argument 'workspace'
Exception Location: /[ommited]/my_venv/local/lib/python2.7/site-packages/django/views/generic/edit.py in get_form, line 45
Python Executable:  /[ommited]/my_venv/bin/python
Python Version: 2.7.3

但是,如果我在InheritedForm中声明__init__,它将正常工作。但是,随着更多的继承形式,我将不得不复制代码,这是违反DRY原则的。

1 个答案:

答案 0 :(得分:2)

Python总是试图通过MRO查找方法,该方法基于父类声明的顺序。因此,在这种情况下,因为您将ModelForm放在类定义的第一位,它会先找到__init__,因此会出错。

解决方案就是交换订单:

class InheritedForm(ParentForm, forms.ModelForm):

虽然我确实想知道为什么你将ParentForm声明为从form.Form继承而来 - 不妨让它继承自ModelForm,然后你不需要在InheritedForm中进行多重继承。 / p>