Mixin pour forms multiples

This commit is contained in:
Ludovic Stephan 2020-07-21 14:47:07 +02:00
parent 15936751c0
commit b6626093e5

View file

@ -1,5 +1,103 @@
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.core.exceptions import ImproperlyConfigured
from django.http import HttpResponseRedirect
from django.views.generic.base import ContextMixin, TemplateResponseMixin, View
class StaffRequiredMixin(PermissionRequiredMixin):
permission_required = "bds.is_team"
class MultipleFormMixin(ContextMixin):
""" Mixin pour gérer plusieurs formulaires dans la même vue.
Le fonctionnement est relativement identique à celui de
FormMixin.
"""
form_classes = {}
prefixes = {}
initial = {}
success_url = None
def get_form_classes(self):
return self.form_classes
def get_initial(self, form_name):
initial_attr = "%s_initial" % form_name
initial_method = "get_%s_initial" % form_name
initial_method = getattr(self, initial_method, None)
if hasattr(self, initial_attr):
return getattr(self, initial_attr)
elif callable(initial_method):
return initial_method()
else:
return self.initial.copy()
def get_prefix(self, form_name):
return self.prefixes.get(form_name, form_name)
def get_instance(self, form_name):
# Au cas où certaines des forms soient des ModelForms
instance_method = "get_%s_instance" % form_name
instance_method = getattr(self, instance_method, None)
if callable(instance_method):
return instance_method()
else:
return None
def get_form_kwargs(self, form_name):
kwargs = {
"initial": self.get_initial(form_name),
"prefix": self.get_prefix(form_name),
"instance": self.get_instance(form_name),
}
if self.request.method in ("POST", "PUT"):
kwargs.update({"data": self.request.POST, "files": self.request.FILES})
return kwargs
def get_forms(self):
form_classes = self.get_form_classes()
return {
form_name: form_class(**self.get_form_kwargs(form_name))
for form_name, form_class in form_classes.items()
}
def get_success_url(self):
if not self.success_url:
raise ImproperlyConfigured("No URL to redirect to. Provide a success_url.")
return str(self.success_url)
def form_valid(self, forms):
# on garde le nom form_valid pour l'interface avec SuccessMessageMixin
return HttpResponseRedirect(self.get_success_url())
def form_invalid(self, forms):
"""If the form is invalid, render the invalid form."""
return self.render_to_response(self.get_context_data(forms=forms))
class ProcessMultipleFormView(View):
def get(self, request, *args, **kwargs):
forms = self.get_forms()
return self.render_to_response(self.get_context_data(forms=forms))
def post(self, request, *args, **kwargs):
forms = self.get_forms()
if all(form.is_valid() for form in forms.values()):
return self.form_valid(forms)
else:
return self.form_invalid(forms)
class BaseMultipleFormView(MultipleFormMixin, ProcessMultipleFormView):
pass
class MultipleFormView(TemplateResponseMixin, BaseMultipleFormView):
pass