When I use django generic view - UpdateView and try to update form kwargs like this:
#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
This will give such an error:
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
However, if I declare __init__
in InheritedForm it will work fine. But then, with more inherited forms I would have to copy the code, which is against DRY principle.
Python always tries to find methods via the MRO, which is based on the order the parent classes are declared. So in this case since you put ModelForm
first in the class definition, it will find the __init__
there first, hence the error.
The solution is just to swap the order:
class InheritedForm(ParentForm, forms.ModelForm):
although I do wonder why you've declared ParentForm as inheriting from forms.Form in the first place - might as well make it inherit from ModelForm, then you don't need the multiple inheritance in InheritedForm.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.