简体   繁体   中英

Django passing kwargs to inherited form causes error (generic UpdateView)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM