Skip to content

Instantly share code, notes, and snippets.

@michelts
Created June 16, 2011 14:34
Show Gist options
  • Star 55 You must be signed in to star a gist
  • Fork 13 You must be signed in to fork a gist
  • Save michelts/1029336 to your computer and use it in GitHub Desktop.
Save michelts/1029336 to your computer and use it in GitHub Desktop.
FormsView
from django.views.generic.base import View, TemplateResponseMixin
from django.views.generic.edit import FormMixin, ProcessFormView
class MultipleFormsMixin(FormMixin):
"""
A mixin that provides a way to show and handle several forms in a
request.
"""
form_classes = {} # set the form classes as a mapping
def get_form_classes(self):
return self.form_classes
def get_forms(self, form_classes):
return dict([(key, klass(**self.get_form_kwargs())) \
for key, klass in form_classes.items()])
def forms_valid(self, forms):
return super(MultipleFormsMixin, self).form_valid(forms)
def forms_invalid(self, forms):
return self.render_to_response(self.get_context_data(forms=forms))
class ProcessMultipleFormsView(ProcessFormView):
"""
A mixin that processes multiple forms on POST. Every form must be
valid.
"""
def get(self, request, *args, **kwargs):
form_classes = self.get_form_classes()
forms = self.get_forms(form_classes)
return self.render_to_response(self.get_context_data(forms=forms))
def post(self, request, *args, **kwargs):
form_classes = self.get_form_classes()
forms = self.get_forms(form_classes)
if all([form.is_valid() for form in forms.values()]):
return self.forms_valid(forms)
else:
return self.forms_invalid(forms)
class BaseMultipleFormsView(MultipleFormsMixin, ProcessMultipleFormsView):
"""
A base view for displaying several forms.
"""
class MultipleFormsView(TemplateResponseMixin, BaseMultipleFormsView):
"""
A view for displaing several forms, and rendering a template response.
"""
@techoutlooks
Copy link

Loved it !

@fosil
Copy link

fosil commented Jul 7, 2019

Thx for the great solution!
In Django 2.2 (elsewhere I did not test it) will cause an error. The problem is in the get_context_data (self, ** kwargs) method from FormMixin:

if 'form' not in kwargs:
  kwargs ['form'] = self.get_form()

The solution is simple - add to MultipleFormsMixin:

def get_context_data(self, **kwargs):
  if 'forms' not in kwargs:
    kwargs['forms'] = self.get_forms()
  return super().get_context_data(**kwargs)

And even a little detail: import View from django.views.generic.base is unnecessary. There's no use anywhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment