Ticket #17464: BaseCreateView-default_fields.diff

File BaseCreateView-default_fields.diff, 4.9 KB (added by madjar, 4 years ago)
  • django/views/generic/edit.py

    diff --git a/django/views/generic/edit.py b/django/views/generic/edit.py
    index 3cade52..3b4606b 100644
    a b class BaseCreateView(ModelFormMixin, ProcessFormView): 
    163163
    164164    Using this base class requires subclassing to provide a response mixin.
    165165    """
     166
     167    default_fields = None
     168
     169    def get_default_fields(self):
     170        """
     171        Returns the default keywords for the instance to be created, in case
     172        you need to set some fields that not in the form.
     173        """
     174        return self.default_fields
     175
    166176    def get(self, request, *args, **kwargs):
    167177        self.object = None
    168178        return super(BaseCreateView, self).get(request, *args, **kwargs)
    169179
    170180    def post(self, request, *args, **kwargs):
    171         self.object = None
     181        default_fields = self.get_default_fields()
     182        if default_fields:
     183            self.object = self.model(**default_fields)
     184        else:
     185            self.object = None
    172186        return super(BaseCreateView, self).post(request, *args, **kwargs)
    173187
    174188
  • docs/ref/class-based-views.txt

    diff --git a/docs/ref/class-based-views.txt b/docs/ref/class-based-views.txt
    index 692417e..2f1012d 100644
    a b CreateView 
    10311031    A view that displays a form for creating an object, redisplaying the form
    10321032    with validation errors (if there are any) and saving the object.
    10331033
     1034    When used with a form that excludes some of the fields (using `form_class
     1035    = modelform_factory(model, excludes=('date',))`, for example), the default
     1036    value for the excluded arguments can be specified using `default_fields` or
     1037    `get_default_fields`.
     1038
    10341039    :class:`~django.views.generic.edit.BaseCreateView` implements the same
    10351040    behavior as :class:`~django.views.generic.edit.CreateView`, but doesn't
    10361041    include the :class:`~django.views.generic.base.TemplateResponseMixin`.
    CreateView 
    10401045    * :class:`django.views.generic.edit.ModelFormMixin`
    10411046    * :class:`django.views.generic.edit.ProcessFormView`
    10421047
     1048    .. attribute:: default_fields
     1049
     1050        A dictionary containing default attributes for the created instance.
     1051
     1052    .. method:: get_default_fields()
     1053
     1054        Retrieve default attributes for the created instance. By default,
     1055        returns :attr:`.default_fields`.
     1056
    10431057UpdateView
    10441058~~~~~~~~~~
    10451059.. class:: BaseUpdateView()
  • tests/regressiontests/generic_views/edit.py

    diff --git a/tests/regressiontests/generic_views/edit.py b/tests/regressiontests/generic_views/edit.py
    index 182615a..5ce1f26 100644
    a b class CreateViewTests(TestCase): 
    9292        self.assertEqual(res.status_code, 302)
    9393        self.assertRedirects(res, 'http://testserver/accounts/login/?next=/edit/authors/create/restricted/')
    9494
     95    def test_create_with_default_values(self):
     96        res = self.client.post('/edit/authors/create/defaultinstance/',
     97                        {'name': 'Randall Munroe'})
     98        self.assertEqual(res.status_code, 302)
     99        self.assertRedirects(res, 'http://testserver/list/authors/')
     100        self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe>'])
     101        author = Author.objects.get(name='Randall Munroe')
     102        self.assertEqual(author.slug, 'default-slug')
     103
    95104class UpdateViewTests(TestCase):
    96105    urls = 'regressiontests.generic_views.urls'
    97106
  • tests/regressiontests/generic_views/urls.py

    diff --git a/tests/regressiontests/generic_views/urls.py b/tests/regressiontests/generic_views/urls.py
    index 090ec73..84ee509 100644
    a b urlpatterns = patterns('', 
    7171        views.AuthorCreate.as_view()),
    7272    (r'^edit/authors/create/special/$',
    7373        views.SpecializedAuthorCreate.as_view()),
     74    (r'^edit/authors/create/defaultinstance/$',
     75        views.DefaultInstanceAuthorCreate.as_view()),
    7476
    7577    (r'^edit/author/(?P<pk>\d+)/update/naive/$',
    7678        views.NaiveAuthorUpdate.as_view()),
  • tests/regressiontests/generic_views/views.py

    diff --git a/tests/regressiontests/generic_views/views.py b/tests/regressiontests/generic_views/views.py
    index 5ff9cf0..e60fc8d 100644
    a b from __future__ import absolute_import 
    33from django.contrib.auth.decorators import login_required
    44from django.core.paginator import Paginator
    55from django.core.urlresolvers import reverse
     6from django.forms.models import modelform_factory
    67from django.utils.decorators import method_decorator
    78from django.views import generic
    89
    class AuthorCreateRestricted(AuthorCreate): 
    103104    post = method_decorator(login_required)(AuthorCreate.post)
    104105
    105106
     107class DefaultInstanceAuthorCreate(AuthorCreate):
     108    form_class = modelform_factory(Author, fields=('name',))
     109    def get_default_fields(self):
     110        return {'slug': 'default-slug'}
     111
     112
    106113class ArtistUpdate(generic.UpdateView):
    107114    model = Artist
    108115
Back to Top