Ticket #16256: ticket16256.patch

File ticket16256.patch, 24.8 KB (added by rasca, 13 years ago)
  • AUTHORS

    diff --git a/AUTHORS b/AUTHORS
    index 8cb71c1..fae6f81 100644
    a b answer newbie questions, and generally made Django that much better:  
    412412    Luciano Ramalho
    413413    Amit Ramon <amit.ramon@gmail.com>
    414414    Philippe Raoult <philippe.raoult@n2nsoft.com>
     415    Iván Raskovsky <raskovsky@gmail.com>
    415416    Massimiliano Ravelli <massimiliano.ravelli@gmail.com>
    416417    Brian Ray <http://brianray.chipy.org/>
    417418    Łukasz Rekucki <lrekucki@gmail.com>
  • django/views/generic/__init__.py

    diff --git a/django/views/generic/__init__.py b/django/views/generic/__init__.py
    index 1a98067..5ef8d97 100644
    a b from django.views.generic.detail import DetailView  
    66from django.views.generic.edit import FormView, CreateView, UpdateView, DeleteView
    77from django.views.generic.list import ListView
    88
     9from django.views.generic.formsets import (FormSetsView, ModelFormSetsView,
     10                               InlineFormSetsView, EnhancedFormSet,
     11                               EnhancedModelFormSet, EnhancedInlineFormSet, )
     12
    913
    1014class GenericViewError(Exception):
    1115    """A problem in a generic view."""
  • new file django/views/generic/formsets.py

    diff --git a/django/views/generic/formsets.py b/django/views/generic/formsets.py
    new file mode 100644
    index 0000000..da9c2ad
    - +  
     1from django.http import HttpResponseRedirect
     2from django.core.exceptions import ImproperlyConfigured
     3from django.forms.formsets import formset_factory, BaseFormSet, all_valid
     4from django.forms.models import (modelformset_factory, inlineformset_factory,
     5                                 BaseModelFormSet, BaseInlineFormSet, ModelForm)
     6
     7from django.views.generic.base import View, TemplateResponseMixin
     8from django.views.generic.detail import SingleObjectTemplateResponseMixin
     9from django.views.generic.edit import ModelFormMixin
     10
     11
     12class EnhancedFormSet(object):
     13    """
     14    A base class for generic formsets
     15    """
     16
     17    form_class = None
     18    formset_class = BaseFormSet
     19
     20    # formset_factory kwargs
     21    extra = 3
     22    can_order = False
     23    can_delete = False
     24    max_num = None
     25
     26    def get_base_formset(self, **kwargs):
     27        """
     28        Returns the base formset
     29        """
     30        new_kwargs = self.get_kwargs()
     31        new_kwargs.update(**kwargs)
     32        return self.get_factory()(**new_kwargs)
     33
     34    def get_factory(self):
     35        """
     36        Returns the factory used to construct the formsets
     37        """
     38        return formset_factory
     39
     40    def get_form_class(self):
     41        return self.form_class
     42
     43    def get_formset_class(self):
     44        return self.formset_class
     45
     46    def get_kwargs(self):
     47        return {'form': self.get_form_class(),
     48                'formset': self.get_formset_class(),
     49                'extra': self.extra,
     50                'can_order': self.can_order,
     51                'can_delete': self.can_delete,
     52                'max_num': self.max_num, }
     53
     54
     55class EnhancedModelFormSet(EnhancedFormSet):
     56    """
     57    A base class for generic model formsets
     58    """
     59    # TODO: provide a hook for formfield_callback
     60
     61    form_class = ModelForm
     62    formset_class = BaseModelFormSet
     63    model = None
     64    queryset = None
     65    fields = None
     66    exclude = None
     67
     68    def get_factory(self):
     69        return modelformset_factory
     70
     71    def get_model(self):
     72        if self.model:
     73            return self.model
     74        else:
     75            try:
     76                return self.get_form_class().Meta.model
     77            except AttributeError:
     78                raise ImproperlyConfigured(
     79                "No model to create the modelformset. Provide one.")
     80
     81    def get_queryset(self):
     82        return self.queryset
     83
     84    def get_fields(self):
     85        return self.fields
     86
     87    def get_exclude(self):
     88        return self.exclude
     89
     90    def get_kwargs(self):
     91        kwargs = super(EnhancedModelFormSet, self).get_kwargs()
     92        kwargs.update({
     93            'model': self.get_model(),
     94            'fields': self.get_fields(),
     95            'exclude': self.get_exclude(),
     96        })
     97        return kwargs
     98
     99
     100class EnhancedInlineFormSet(EnhancedModelFormSet):
     101    """
     102    A base class for generic inline formsets
     103    """
     104
     105    fk_name = None
     106    formset_class = BaseInlineFormSet
     107
     108    def get_factory(self):
     109        return inlineformset_factory
     110
     111    def get_fk_name(self):
     112        return self.fk_name
     113
     114    def get_kwargs(self):
     115        kwargs = super(EnhancedInlineFormSet, self).get_kwargs()
     116        kwargs.update({
     117            'fk_name': self.get_fk_name(),
     118        })
     119        return kwargs
     120
     121
     122class FormSetsMixin(object):
     123    """
     124    A mixin that provides a way to show and handle formsets
     125    """
     126
     127    formsets = []  # must be a list of BaseGenericFormSet
     128    success_url = None
     129
     130    def __init__(self, *args, **kwargs):
     131        self.instantiate_enhanced_formsets()
     132
     133    def instantiate_enhanced_formsets(self):
     134        """
     135        Instantiates the enhanced formsets
     136        """
     137        self.enhanced_formsets_instances = []
     138        for formset in self.formsets:
     139            enhanced_formset_instance = formset()
     140            self.enhanced_formsets_instances.append(enhanced_formset_instance)
     141
     142    def construct_formsets(self):
     143        """
     144        Constructs the formsets
     145        """
     146        self.formsets_instances = []
     147
     148        prefixes = {}
     149        for enhanced_formset in self.enhanced_formsets_instances:
     150            base_formset = enhanced_formset.get_base_formset(
     151                **self.get_factory_kwargs())
     152
     153            # calculate prefix
     154            prefix = base_formset.get_default_prefix()
     155            prefixes[prefix] = prefixes.get(prefix, 0) + 1
     156            if prefixes[prefix] != 1:
     157                prefix = "%s-%s" % (prefix, prefixes[prefix])
     158
     159            self.formsets_instances.append(
     160                base_formset(prefix=prefix, **self.get_formsets_kwargs(
     161                    enhanced_formset))
     162            )
     163
     164    def get_factory_kwargs(self):
     165        """
     166        Returns the keyword arguments for the formsets factory
     167        """
     168        return {}
     169
     170    def get_formsets_kwargs(self, enhanced_formset):
     171        """"
     172        Returns the keyword arguments for instanciating the formsets
     173        """
     174
     175        # default kwargs
     176        kwargs = {}
     177
     178        if self.request.method in ('POST', 'PUT'):
     179            kwargs.update({
     180                'data': self.request.POST,
     181                'files': self.request.FILES,
     182            })
     183        return kwargs
     184
     185    def get_context_data(self, **kwargs):
     186        context_data = {
     187            'formsets': [formset for formset in self.formsets_instances],
     188        }
     189
     190        context_data.update(kwargs)
     191        return context_data
     192
     193    def get_success_url(self):
     194        if self.success_url:
     195            url = self.success_url
     196        else:
     197            raise ImproperlyConfigured(
     198                "No URL to redirect to. Provide a success_url")
     199        return url
     200
     201    def formsets_valid(self):
     202        return HttpResponseRedirect(self.get_success_url())
     203
     204    def formsets_invalid(self):
     205        return self.render_to_response(self.get_context_data())
     206
     207
     208class ModelFormSetsMixin(FormSetsMixin):
     209    """
     210    A mixin that provides a way to show and handle model formsets
     211    """
     212
     213    def get_formsets_kwargs(self, enhanced_formset):
     214        """"
     215        Returns the keyword arguments for instanciating the model formsets
     216        """
     217        kwargs = super(ModelFormSetsMixin, self).get_formsets_kwargs(
     218                                                    enhanced_formset)
     219        kwargs.update({
     220            'queryset': enhanced_formset.get_queryset()
     221        })
     222        return kwargs
     223
     224    def formsets_valid(self):
     225        # FIXME: beware of m2m
     226        for formset in self.formsets_instances:
     227            formset.save()
     228        return super(ModelFormSetsMixin, self).formsets_valid()
     229
     230
     231class InlineFormSetsMixin(ModelFormSetsMixin, ModelFormMixin):
     232    """
     233    A mixin that provides a way to show and handle a model with it's inline
     234    formsets
     235    """
     236    def get_formsets_kwargs(self, enhanced_formset):
     237        """"
     238        Returns the keyword arguments for instanciating the inline formsets
     239        """
     240        kwargs = super(InlineFormSetsMixin, self).get_formsets_kwargs(
     241                                                    enhanced_formset)
     242        kwargs.update({
     243            'instance': self.object
     244        })
     245        return kwargs
     246
     247    def get_context_data(self, **kwargs):
     248        """
     249        Adds the context data from both parents
     250        """
     251        context_data = ModelFormSetsMixin.get_context_data(self)
     252        context_data.update(ModelFormMixin.get_context_data(self, **kwargs))
     253        return context_data
     254
     255    def get_factory_kwargs(self):
     256        """
     257        Returns the keyword arguments for the formsets factory
     258        """
     259        return {
     260            'parent_model': self.object.__class__,
     261        }
     262
     263    def form_valid(self, form):
     264        self.object.save()
     265        form.save_m2m()
     266        for formset in self.formsets_instances:
     267            formset.save()
     268
     269        return HttpResponseRedirect(self.get_success_url())
     270
     271    def form_invalid(self, form):
     272        return self.render_to_response(self.get_context_data(form=form))
     273
     274
     275class ProcessFormSetsView(View):
     276    """
     277    A mixin that processes formsets on POST
     278    """
     279    def get(self, request, *args, **kwargs):
     280        self.construct_formsets()
     281        return self.render_to_response(self.get_context_data())
     282
     283    def post(self, request, *args, **kwargs):
     284        self.construct_formsets()
     285        if all_valid(self.formsets_instances):
     286            return self.formsets_valid()
     287        else:
     288            return self.formsets_invalid()
     289
     290    def put(self, request, *args, **kwargs):
     291        return self.post(*args, **kwargs)
     292
     293
     294class ProcessInlineFormSetsView(View):
     295    """
     296    A mixin that processes a model instance and it's inline formsets on POST
     297    """
     298
     299    def get(self, request, *args, **kwargs):
     300        # Create or Update
     301        try:
     302            self.object = self.get_object()
     303        except AttributeError:
     304            self.object = self.model()
     305
     306        # ProcessFormView
     307        form_class = self.get_form_class()
     308        form = self.get_form(form_class)
     309
     310        # ProcessFormSetsView
     311        self.construct_formsets()
     312
     313        return self.render_to_response(self.get_context_data(form=form))
     314
     315    def post(self, request, *args, **kwargs):
     316        # Create or Update
     317        try:
     318            self.object = self.get_object()
     319        except AttributeError:
     320            self.object = self.model()
     321
     322        # ProcessFormView
     323        form_class = self.get_form_class()
     324        form = self.get_form(form_class)
     325
     326        if form.is_valid():
     327            self.object = form.save(commit=False)
     328
     329            # ProcessFormSetsViewV
     330            self.construct_formsets()
     331
     332            if all_valid(self.formsets_instances):
     333                return self.form_valid(form)
     334        else:
     335            # ProcessFormSetsViewV
     336            self.construct_formsets()
     337        return self.form_invalid(form)
     338
     339
     340    def put(self, request, *args, **kwargs):
     341        return self.post(*args, **kwargs)
     342
     343
     344class BaseFormSetsView(FormSetsMixin, ProcessFormSetsView):
     345    """
     346    A base view for displaying formsets
     347    """
     348
     349
     350class BaseModelFormSetsView(ModelFormSetsMixin, ProcessFormSetsView):
     351    """
     352    A base view for displaying model formsets
     353    """
     354
     355
     356class BaseInlineFormSetsView(InlineFormSetsMixin, ProcessInlineFormSetsView):
     357    """
     358    A base view for displaying a model instance with it's inline formsets
     359    """
     360
     361
     362class FormSetsView(TemplateResponseMixin, BaseFormSetsView):
     363    """
     364    A view for displaying formsets, and rendering a template response
     365    """
     366
     367
     368class ModelFormSetsView(TemplateResponseMixin, BaseModelFormSetsView):
     369    """
     370    A view for displaying model formsets, and rendering a template response
     371    """
     372
     373
     374class InlineFormSetsView(SingleObjectTemplateResponseMixin,
     375                         BaseInlineFormSetsView):
     376    """
     377    A view for displaying a model instance with it's inline formsets, and
     378    rendering a template response
     379    """
     380    template_name_suffix = '_form'
     381
  • tests/regressiontests/generic_views/forms.py

    diff --git a/tests/regressiontests/generic_views/forms.py b/tests/regressiontests/generic_views/forms.py
    index 7200947..b6ee715 100644
    a b  
    11from django import forms
     2from django.forms.formsets import formset_factory
    23
    3 from regressiontests.generic_views.models import Author
     4from django.views.generic import (EnhancedFormSet, EnhancedModelFormSet,
     5                                     EnhancedInlineFormSet, )
     6from regressiontests.generic_views.models import Author, Article
    47
    58
    69class AuthorForm(forms.ModelForm):
    class AuthorForm(forms.ModelForm):  
    912
    1013    class Meta:
    1114        model = Author
     15
     16
     17class ArticleForm(forms.ModelForm):
     18    class Meta:
     19        model = Article
     20        exclude = ('author', )
     21
     22
     23class ArticleEnhancedFormSet(EnhancedFormSet):
     24    form_class = ArticleForm
     25
     26
     27class AuthorEnhancedFormSet(EnhancedFormSet):
     28    form_class = AuthorForm
     29
     30
     31class ArticleEnhancedModelFormSet(EnhancedModelFormSet):
     32    model = Article
     33
     34
     35class AuthorEnhancedModelFormSet(EnhancedModelFormSet):
     36    model = Author
     37
     38
     39class ArticleEnhancedInlineFormSet(EnhancedInlineFormSet):
     40    model = Article
  • new file tests/regressiontests/generic_views/formsets.py

    diff --git a/tests/regressiontests/generic_views/formsets.py b/tests/regressiontests/generic_views/formsets.py
    new file mode 100644
    index 0000000..c9ae954
    - +  
     1from django.test import TestCase
     2from django.core.exceptions import ImproperlyConfigured
     3from django.views.generic.formsets import (FormSetsMixin, ModelFormSetsMixin,
     4        EnhancedModelFormSet, )
     5from regressiontests.generic_views.models import Author, Article
     6
     7
     8class FormSetsViewTests(TestCase):
     9    urls = 'regressiontests.generic_views.urls'
     10
     11    def setUp(self):
     12        self.data = {
     13            'form-TOTAL_FORMS': u'3',
     14            'form-INITIAL_FORMS': u'0',
     15            'form-MAX_NUM_FORMS': u'',
     16            'form-0-title': u'',
     17            'form-0-pubdate': u'',
     18            'form-1-title': u'',
     19            'form-1-pubdate': u'',
     20            'form-2-title': u'',
     21            'form-2-pubdate': u'',
     22
     23            'form-2-TOTAL_FORMS': u'3',
     24            'form-2-INITIAL_FORMS': u'0',
     25            'form-2-MAX_NUM_FORMS': u'',
     26            'form-2-0-name': u'',
     27            'form-2-0-slug': u'',
     28            'form-2-1-name': u'',
     29            'form-2-1-slug': u'',
     30            'form-2-2-name': u'',
     31            'form-2-2-slug': u'',
     32        }
     33
     34    def test_get(self):
     35        response = self.client.get('/edit/formsets/')
     36        self.assertEqual(response.status_code, 200)
     37
     38    def test_empty_post(self):
     39        response = self.client.post('/edit/formsets/', self.data)
     40        self.assertEqual(response.status_code, 302)
     41
     42    def test_valid(self):
     43        self.data.update({
     44            'form-0-title': u'first title',
     45            'form-0-pubdate': u'2011-01-13',
     46            'form-1-title': u'second title',
     47            'form-1-pubdate': u'2011-01-13',
     48            'form-2-0-name': u'this is my name',
     49            'form-2-0-slug': u'this-is-my-name',
     50        })
     51        response = self.client.post('/edit/formsets/', self.data)
     52        self.assertEqual(response.status_code, 302)
     53
     54    def test_invalid(self):
     55        self.data.update({
     56            'form-0-title': u'first title',
     57            'form-0-pubdate': u'',
     58        })
     59        response = self.client.post('/edit/formsets/', self.data)
     60        self.assertEqual(response.status_code, 200)
     61        self.assertContains(response, 'ERROR')
     62
     63
     64class ModelFormSetsTests(TestCase):
     65    def test_no_model_no_form_class(self):
     66        formset = EnhancedModelFormSet()
     67        self.assertRaises(ImproperlyConfigured, formset.get_model)
     68
     69
     70class ModelFormSetsViewTests(TestCase):
     71    urls = 'regressiontests.generic_views.urls'
     72
     73    def setUp(self):
     74        self.data = {
     75            'form-TOTAL_FORMS': u'3',
     76            'form-INITIAL_FORMS': u'0',
     77            'form-MAX_NUM_FORMS': u'',
     78            'form-0-title': u'',
     79            'form-0-pubdate': u'',
     80            'form-1-title': u'',
     81            'form-1-pubdate': u'',
     82            'form-2-title': u'',
     83            'form-2-pubdate': u'',
     84
     85            'form-2-TOTAL_FORMS': u'3',
     86            'form-2-INITIAL_FORMS': u'0',
     87            'form-2-MAX_NUM_FORMS': u'',
     88            'form-2-0-name': u'',
     89            'form-2-1-name': u'',
     90            'form-2-2-name': u'',
     91        }
     92
     93    def test_get(self):
     94        response = self.client.get('/edit/modelformsets/')
     95        self.assertEqual(response.status_code, 200)
     96
     97    def test_empty_post(self):
     98        response = self.client.post('/edit/modelformsets/', self.data)
     99        self.assertEqual(response.status_code, 302)
     100
     101    def test_valid(self):
     102        self.data.update({
     103            'form-0-title': u'first title',
     104            'form-0-pubdate': u'2011-01-13',
     105            'form-1-title': u'second title',
     106            'form-1-pubdate': u'2011-01-13',
     107            'form-2-0-name': u'this is my name',
     108            'form-2-0-slug': u'this-is-my-name',
     109        })
     110        response = self.client.post('/edit/modelformsets/', self.data)
     111        self.assertEqual(Article.objects.count(), 2)
     112        self.assertEqual(Author.objects.count(), 1)
     113        self.assertEqual(response.status_code, 302)
     114
     115    def test_invalid(self):
     116        self.data.update({
     117            'form-0-title': u'first title',
     118            'form-0-pubdate': u'',
     119        })
     120        response = self.client.post('/edit/modelformsets/', self.data)
     121        self.assertEqual(Article.objects.count(), 0)
     122        self.assertEqual(Author.objects.count(), 0)
     123        self.assertEqual(response.status_code, 200)
     124        self.assertContains(response, 'ERROR')
     125
     126
     127class InlineFormSetsViewTests(TestCase):
     128    urls = 'regressiontests.generic_views.urls'
     129
     130    def setUp(self):
     131        self.formsetmgmt = {
     132            'article_set-TOTAL_FORMS': u'3',
     133            'article_set-INITIAL_FORMS': u'0',
     134            'article_set-MAX_NUM_FORMS': u'',
     135        }
     136        self.formsetdata = {
     137            'article_set-0-title': u'title1',
     138            'article_set-0-pubdate': u'2011-01-26',
     139            'article_set-1-title': u'title2',
     140            'article_set-1-pubdate': u'2011-01-26',
     141            'article_set-2-title': u'title3',
     142            'article_set-2-pubdate': u'2011-01-26',
     143        }
     144        self.formdata = {
     145            'name': u'this is my name',
     146            'slug': u'this-is-my-name',
     147        }
     148
     149    def test_get(self):
     150        response = self.client.get('/edit/inlineformsets/')
     151        self.assertEqual(response.status_code, 200)
     152
     153    def test_empty_post(self):
     154        data = {
     155            'article_set-TOTAL_FORMS': u'3',
     156            'article_set-INITIAL_FORMS': u'0',
     157            'article_set-MAX_NUM_FORMS': u'',
     158            'article_set-0-title': u'',
     159            'article_set-0-pubdate': u'',
     160            'article_set-1-title': u'',
     161            'article_set-1-pubdate': u'',
     162            'article_set-2-title': u'',
     163            'article_set-2-pubdate': u'',
     164            'name': u'',
     165        }
     166        response = self.client.post('/edit/inlineformsets/', data)
     167        self.assertEqual(response.status_code, 200)
     168
     169    def test_valid(self):
     170        data = self.formdata
     171        data.update(self.formsetdata)
     172        data.update(self.formsetmgmt)
     173        response = self.client.post('/edit/inlineformsets/', data)
     174        self.assertEqual(Article.objects.count(), 3)
     175        self.assertEqual(Author.objects.count(), 1)
     176        self.assertEqual(response.status_code, 302)
     177
     178    def test_no_form(self):
     179        data = self.formsetdata
     180        data.update(self.formsetmgmt)
     181        response = self.client.post('/edit/inlineformsets/', data)
     182        self.assertEqual(Article.objects.count(), 0)
     183        self.assertEqual(Author.objects.count(), 0)
     184        self.assertEqual(response.status_code, 200)
     185        self.assertContains(response, 'ERROR')
     186
     187    def test_no_formset(self):
     188        data = self.formdata
     189        data.update(self.formsetmgmt)
     190        response = self.client.post('/edit/inlineformsets/', data)
     191        self.assertEqual(Article.objects.count(), 0)
     192        self.assertEqual(Author.objects.count(), 1)
     193        self.assertEqual(response.status_code, 302)
  • tests/regressiontests/generic_views/models.py

    diff --git a/tests/regressiontests/generic_views/models.py b/tests/regressiontests/generic_views/models.py
    index 5445e24..3a0d9ab 100644
    a b class Book(models.Model):  
    4141class Page(models.Model):
    4242    content = models.TextField()
    4343    template = models.CharField(max_length=300)
     44
     45
     46class Article(models.Model):
     47    title = models.CharField(max_length=100)
     48    pubdate = models.DateField()
     49    author = models.ForeignKey(Author, blank=True, null=True)
  • new file tests/regressiontests/generic_views/templates/authors_articles.html

    diff --git a/tests/regressiontests/generic_views/templates/authors_articles.html b/tests/regressiontests/generic_views/templates/authors_articles.html
    new file mode 100644
    index 0000000..7c9eca3
    - +  
     1{% for formset in formsets %}
     2    {% if formset.errors %}
     3    ERROR
     4    {{formset.errors}}
     5    {% endif %}
     6    {% for form in formset %}
     7    {{form.as_p}}
     8    {% endfor %}
     9    {{formset.management_form}}
     10{% endfor %}
  • tests/regressiontests/generic_views/tests.py

    diff --git a/tests/regressiontests/generic_views/tests.py b/tests/regressiontests/generic_views/tests.py
    index a4010aa..0ab240c 100644
    a b from regressiontests.generic_views.dates import ArchiveIndexViewTests, YearArchi  
    33from regressiontests.generic_views.detail import DetailViewTest
    44from regressiontests.generic_views.edit import ModelFormMixinTests, CreateViewTests, UpdateViewTests, DeleteViewTests
    55from regressiontests.generic_views.list import ListViewTests
     6from regressiontests.generic_views.formsets import FormSetsViewTests, ModelFormSetsTests, ModelFormSetsViewTests, InlineFormSetsViewTests
  • tests/regressiontests/generic_views/urls.py

    diff --git a/tests/regressiontests/generic_views/urls.py b/tests/regressiontests/generic_views/urls.py
    index 067c1f6..8ec94cf 100644
    a b urlpatterns = patterns('',  
    208208        views.BookDetail.as_view(allow_future=True)),
    209209    (r'^dates/books/(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\d{1,2})/nopk/$',
    210210        views.BookDetail.as_view()),
    211 
    212211    (r'^dates/books/(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\d{1,2})/byslug/(?P<slug>[\w-]+)/$',
    213212        views.BookDetail.as_view()),
    214213
     214    # FormSets
     215    (r'^edit/formsets/$',
     216        views.AuthorsArticlesView.as_view()),
     217    (r'^edit/modelformsets/$',
     218        views.AuthorsArticlesModelsView.as_view()),
     219    (r'^edit/inlineformsets/$',
     220        views.AuthorsInlinesView.as_view()),
     221
    215222    # Useful for testing redirects
    216223    (r'^accounts/login/$',  'django.contrib.auth.views.login')
    217224)
  • tests/regressiontests/generic_views/views.py

    diff --git a/tests/regressiontests/generic_views/views.py b/tests/regressiontests/generic_views/views.py
    index 0c8fd49..69ea1ac 100644
    a b from django.utils.decorators import method_decorator  
    55from django.views import generic
    66
    77from regressiontests.generic_views.models import Artist, Author, Book, Page
    8 from regressiontests.generic_views.forms import AuthorForm
    9 
     8from regressiontests.generic_views.forms import (AuthorForm,
     9        ArticleEnhancedFormSet, AuthorEnhancedFormSet,
     10        ArticleEnhancedModelFormSet, AuthorEnhancedModelFormSet,
     11        ArticleEnhancedInlineFormSet, )
    1012
    1113class CustomTemplateView(generic.TemplateView):
    1214    template_name = 'generic_views/about.html'
    class BookDetail(BookConfig, generic.DateDetailView):  
    177179class AuthorGetQuerySetFormView(generic.edit.ModelFormMixin):
    178180    def get_queryset(self):
    179181        return Author.objects.all()
     182
     183
     184class AuthorsArticlesView(generic.FormSetsView):
     185    formsets = [ArticleEnhancedFormSet, AuthorEnhancedFormSet, ]
     186    template_name = 'authors_articles.html'
     187    success_url = '/list/authors/'
     188   
     189
     190class AuthorsArticlesModelsView(generic.ModelFormSetsView):
     191    formsets = [ArticleEnhancedModelFormSet, AuthorEnhancedModelFormSet, ]
     192    template_name = 'authors_articles.html'
     193    success_url = '/list/authors/'
     194
     195
     196class AuthorsInlinesView(generic.InlineFormSetsView):
     197    formsets = [ArticleEnhancedInlineFormSet, ]
     198    template_name = 'authors_articles.html'
     199    success_url = '/list/authors/'
     200    model = Author
Back to Top