Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
group creators can add/remove organizers, delete events and group
- Loading branch information
Showing
8 changed files
with
318 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
# Class-based Views for handling multiple forms | ||
# https://gist.github.com/jamesbrobb/748c47f46b9bd224b07f | ||
|
||
from django.views.generic.base import TemplateResponseMixin, ContextMixin | ||
from django.views.generic.edit import ProcessFormView | ||
from django.http import HttpResponseRedirect, HttpResponseForbidden | ||
|
||
|
||
class MultiFormMixin(ContextMixin): | ||
|
||
form_classes = {} | ||
prefixes = {} | ||
success_urls = {} | ||
grouped_forms = {} | ||
|
||
initial = {} | ||
prefix = None | ||
success_url = None | ||
|
||
def get_form_classes(self): | ||
return self.form_classes | ||
|
||
def get_forms(self, form_classes, form_names=None, bind_all=False): | ||
return dict([(key, self._create_form(key, klass, | ||
(form_names and key in form_names) or bind_all)) for key, klass in form_classes.items()]) | ||
|
||
def get_form_kwargs(self, form_name, bind_form=False): | ||
kwargs = {} | ||
kwargs.update({'initial': self.get_initial(form_name)}) | ||
kwargs.update({'prefix': self.get_prefix(form_name)}) | ||
|
||
if bind_form: | ||
kwargs.update(self._bind_form_data()) | ||
|
||
return kwargs | ||
|
||
def forms_valid(self, forms, form_name): | ||
form_valid_method = '%s_form_valid' % form_name | ||
if hasattr(self, form_valid_method): | ||
return getattr(self, form_valid_method)(forms[form_name]) | ||
else: | ||
return HttpResponseRedirect(self.get_success_url(form_name)) | ||
|
||
def forms_invalid(self, forms): | ||
return self.render_to_response(self.get_context_data(forms=forms)) | ||
|
||
def get_initial(self, form_name): | ||
initial_method = 'get_%s_initial' % form_name | ||
if hasattr(self, initial_method): | ||
return getattr(self, initial_method)() | ||
else: | ||
return self.initial.copy() | ||
|
||
def get_prefix(self, form_name): | ||
return self.prefixes.get(form_name, self.prefix) | ||
|
||
def get_success_url(self, form_name=None): | ||
return self.success_urls.get(form_name, self.success_url) | ||
|
||
def _create_form(self, form_name, klass, bind_form): | ||
form_kwargs = self.get_form_kwargs(form_name, bind_form) | ||
form_create_method = 'create_%s_form' % form_name | ||
if hasattr(self, form_create_method): | ||
form = getattr(self, form_create_method)(**form_kwargs) | ||
else: | ||
form = klass(**form_kwargs) | ||
return form | ||
|
||
def _bind_form_data(self): | ||
if self.request.method in ('POST', 'PUT'): | ||
return{'data': self.request.POST, | ||
'files': self.request.FILES, | ||
} | ||
return {} | ||
|
||
|
||
class ProcessMultipleFormsView(ProcessFormView): | ||
|
||
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() | ||
form_name = request.POST.get('action') | ||
if self._individual_exists(form_name): | ||
return self._process_individual_form(form_name, form_classes) | ||
elif self._group_exists(form_name): | ||
return self._process_grouped_forms(form_name, form_classes) | ||
else: | ||
return self._process_all_forms(form_classes) | ||
|
||
def _individual_exists(self, form_name): | ||
return form_name in self.form_classes | ||
|
||
def _group_exists(self, group_name): | ||
return group_name in self.grouped_forms | ||
|
||
def _process_individual_form(self, form_name, form_classes): | ||
forms = self.get_forms(form_classes, (form_name,)) | ||
form = forms.get(form_name) | ||
if not form: | ||
return HttpResponseForbidden() | ||
elif form.is_valid(): | ||
return self.forms_valid(forms, form_name) | ||
else: | ||
return self.forms_invalid(forms) | ||
|
||
def _process_grouped_forms(self, group_name, form_classes): | ||
form_names = self.grouped_forms[group_name] | ||
forms = self.get_forms(form_classes, form_names) | ||
if all([forms.get(form_name).is_valid() for form_name in form_names.values()]): | ||
return self.forms_valid(forms) | ||
else: | ||
return self.forms_invalid(forms) | ||
|
||
def _process_all_forms(self, form_classes): | ||
forms = self.get_forms(form_classes, None, True) | ||
if all([form.is_valid() for form in forms.values()]): | ||
return self.forms_valid(forms) | ||
else: | ||
return self.forms_invalid(forms) | ||
|
||
|
||
class BaseMultipleFormsView(MultiFormMixin, ProcessMultipleFormsView): | ||
""" | ||
A base view for displaying several forms. | ||
""" | ||
|
||
|
||
class MultiFormsView(TemplateResponseMixin, BaseMultipleFormsView): | ||
""" | ||
A view for displaying several forms, and rendering a template response. | ||
""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{% extends "base.html" %} | ||
|
||
{% block content %} | ||
<h3>Add organizers</h3> | ||
<form action="{% url 'edit_organizers' object.slug %}" method="post"> | ||
{% csrf_token %} | ||
{{ forms.add.as_p }} | ||
<button name="action" value="add" class="btn btn-default" type="submit">Add</button> | ||
</form> | ||
<hr /> | ||
<h3>Remove organizers</h3> | ||
<form action="{% url 'edit_organizers' object.slug %}" method="post"> | ||
{% csrf_token %} | ||
{{ forms.remove.as_p }} | ||
<button name="action" value="remove" class="btn btn-danger" type="submit">Remove</button> | ||
</form> | ||
{% endblock content %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.