forked from rasca/django-enhanced-cbv
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
256 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
from django import forms | ||
from django.forms.formsets import formset_factory | ||
|
||
from enhanced_cbv.views.edit import EnhancedFormSet | ||
|
||
|
||
class ArticleForm(forms.Form): | ||
title = forms.CharField() | ||
pub_date = forms.DateField(required=True) | ||
|
||
class AuthorForm(forms.Form): | ||
name = forms.CharField() | ||
|
||
class ArticleEnhancedFormSet(EnhancedFormSet): | ||
form_class = ArticleForm | ||
|
||
class AuthorEnhancedFormSet(EnhancedFormSet): | ||
form_class = AuthorForm |
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,9 @@ | ||
{% for formset in formsets %} | ||
{% if formset.errors %} | ||
ERROR | ||
{% endif %} | ||
{% for form in formset %} | ||
{{form.as_p}} | ||
{% endfor %} | ||
{{formset.management_form}} | ||
{% endfor %} |
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 @@ | ||
Dummy |
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 |
---|---|---|
@@ -1,2 +1,55 @@ | ||
from django.test import TestCase | ||
|
||
from enhanced_cbv.views.edit import FormSetsMixin | ||
|
||
class FormSetsViewTests(TestCase): | ||
urls = 'enhanced_cbv.tests.urls' | ||
|
||
def setUp(self): | ||
self.data = { | ||
'form-TOTAL_FORMS': u'3', | ||
'form-INITIAL_FORMS': u'0', | ||
'form-MAX_NUM_FORMS': u'', | ||
'form-0-title': u'', | ||
'form-0-pub_date': u'', | ||
'form-1-title': u'', | ||
'form-1-pub_date': u'', | ||
'form-2-title': u'', | ||
'form-2-pub_date': u'', | ||
|
||
'form-2-TOTAL_FORMS': u'3', | ||
'form-2-INITIAL_FORMS': u'0', | ||
'form-2-MAX_NUM_FORMS': u'', | ||
'form-2-0-name': u'', | ||
'form-2-1-name': u'', | ||
'form-2-2-name': u'', | ||
} | ||
|
||
def test_get(self): | ||
response = self.client.get('/edit/formsets/') | ||
self.assertEqual(response.status_code, 200) | ||
|
||
def test_empty_post(self): | ||
response = self.client.post('/edit/formsets/', self.data) | ||
self.assertEqual(response.status_code, 302) | ||
|
||
def test_valid(self): | ||
self.data.update({ | ||
'form-0-title': u'first title', | ||
'form-0-pub_date': u'2011-01-13', | ||
'form-1-title': u'second title', | ||
'form-1-pub_date': u'2011-01-13', | ||
'form-2-0-name': u'this is my name', | ||
}) | ||
response = self.client.post('/edit/formsets/', self.data) | ||
self.assertEqual(response.status_code, 302) | ||
|
||
def test_invalid(self): | ||
self.data.update({ | ||
'form-0-title': u'first title', | ||
'form-0-pub_date': u'', | ||
}) | ||
response = self.client.post('/edit/formsets/', self.data) | ||
self.assertEqual(response.status_code, 200) | ||
self.assertContains(response, 'ERROR') | ||
|
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,11 @@ | ||
from django.conf.urls.defaults import * | ||
|
||
from enhanced_cbv.tests.views import AuthorsArticlesView | ||
|
||
|
||
urlpatterns = patterns('', | ||
|
||
# FormSetsView | ||
(r'^edit/formsets/$', | ||
AuthorsArticlesView.as_view()), | ||
) |
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,10 @@ | ||
from enhanced_cbv.views import FormSetsView | ||
|
||
from enhanced_cbv.tests.forms import (ArticleEnhancedFormSet, | ||
AuthorEnhancedFormSet) | ||
|
||
|
||
class AuthorsArticlesView(FormSetsView): | ||
formsets = [ArticleEnhancedFormSet, AuthorEnhancedFormSet] | ||
template_name = 'authors_articles.html' | ||
success_url = '/success/' |
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 @@ | ||
from edit import FormSetsView |
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,149 @@ | ||
from django.forms.formsets import formset_factory, BaseFormSet, all_valid | ||
from django.http import HttpResponseRedirect | ||
|
||
from django.views.generic.base import View, TemplateResponseMixin | ||
|
||
|
||
class EnhancedFormSet(object): | ||
""" | ||
A base class for generic formsets | ||
""" | ||
|
||
form_class = None | ||
formset_class = BaseFormSet | ||
|
||
# formset_factory kwargs | ||
extra = 3 | ||
can_order = False | ||
can_delete = False | ||
max_num = None | ||
|
||
def get_formset(self, prefix=None, **kwargs): | ||
""" | ||
Returns the instantiated formset | ||
""" | ||
formset = self.get_factory()(**self.get_kwargs()) | ||
return formset(prefix=prefix, **kwargs) | ||
|
||
def get_factory(self): | ||
""" | ||
Returns the factory used to construct the formsets | ||
""" | ||
return formset_factory | ||
|
||
def get_form_class(self): | ||
return self.form_class | ||
|
||
def get_formset_class(self): | ||
return self.formset_class | ||
|
||
def get_kwargs(self): | ||
return {'form': self.get_form_class(), | ||
'formset': self.get_formset_class(), | ||
'extra': self.extra, | ||
'can_order': self.can_order, | ||
'can_delete': self.can_delete, | ||
'max_num': self.max_num, } | ||
|
||
|
||
class FormSetsMixin(object): | ||
""" | ||
A mixin that provides a way to show and handle formsets | ||
""" | ||
|
||
# must be a list of BaseGenericFormSet | ||
formsets = [] | ||
|
||
def __init__(self, *args, **kwargs): | ||
self.instantiate_enhanced_formsets() | ||
|
||
def instantiate_enhanced_formsets(self): | ||
""" | ||
Instantiates the enhanced formsets | ||
""" | ||
self.enhanced_formsets_instances = [] | ||
for formset in self.formsets: | ||
enhanced_formset_instance = formset() | ||
self.enhanced_formsets_instances.append(enhanced_formset_instance) | ||
|
||
def construct_formsets(self): | ||
""" | ||
Constructs the formsets | ||
""" | ||
kwargs = self.get_formsets_kwargs() | ||
|
||
self.formsets_instances = [] | ||
|
||
prefixes = {} | ||
for enhanced_formset in self.enhanced_formsets_instances: | ||
prefix = enhanced_formset.get_formset_class().get_default_prefix() | ||
prefixes[prefix] = prefixes.get(prefix, 0) + 1 | ||
if prefixes[prefix] != 1: | ||
prefix = "%s-%s" % (prefix, prefixes[prefix]) | ||
self.formsets_instances.append( | ||
enhanced_formset.get_formset(prefix=prefix, **kwargs)) | ||
|
||
def get_formsets_kwargs(self): | ||
"""" | ||
Returns the keyword arguments for instanciating the formsets | ||
""" | ||
|
||
# default kwargs | ||
kwargs = {} | ||
|
||
if self.request.method in ('POST', 'PUT'): | ||
kwargs.update({ | ||
'data': self.request.POST, | ||
'files': self.request.FILES, | ||
}) | ||
return kwargs | ||
|
||
def get_context_data(self, **kwargs): | ||
context_data = { | ||
'formsets': [formset for formset in self.formsets_instances], | ||
} | ||
|
||
context_data.update(kwargs) | ||
return context_data | ||
|
||
def get_success_url(self): | ||
if self.success_url: | ||
url = self.success_url | ||
else: | ||
raise ImproperlyConfigured( | ||
"No URL to redirect to. Provide a success_url") | ||
return url | ||
|
||
def formsets_valid(self): | ||
return HttpResponseRedirect(self.get_success_url()) | ||
|
||
def formsets_invalid(self): | ||
return self.render_to_response(self.get_context_data()) | ||
|
||
|
||
class ProcessFormSetsView(View): | ||
""" | ||
A mixin that processes formsets on POST | ||
""" | ||
def get(self, request, *args, **kwargs): | ||
self.construct_formsets() | ||
return self.render_to_response(self.get_context_data()) | ||
|
||
def post(self, request, *args, **kwargs): | ||
self.construct_formsets() | ||
if all_valid(self.formsets_instances): | ||
return self.formsets_valid() | ||
else: | ||
return self.formsets_invalid() | ||
|
||
|
||
class BaseFormSetsView(FormSetsMixin, ProcessFormSetsView): | ||
""" | ||
A base view for displaying formsets | ||
""" | ||
|
||
|
||
class FormSetsView(TemplateResponseMixin, BaseFormSetsView): | ||
""" | ||
A view for displaying formsets, and rendering a template response | ||
""" |