diff --git a/django/views/generic/edit.py b/django/views/generic/edit.py
index 3cade52..3b4606b 100644
a
|
b
|
class BaseCreateView(ModelFormMixin, ProcessFormView):
|
163 | 163 | |
164 | 164 | Using this base class requires subclassing to provide a response mixin. |
165 | 165 | """ |
| 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 | |
166 | 176 | def get(self, request, *args, **kwargs): |
167 | 177 | self.object = None |
168 | 178 | return super(BaseCreateView, self).get(request, *args, **kwargs) |
169 | 179 | |
170 | 180 | 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 |
172 | 186 | return super(BaseCreateView, self).post(request, *args, **kwargs) |
173 | 187 | |
174 | 188 | |
diff --git a/docs/ref/class-based-views.txt b/docs/ref/class-based-views.txt
index 692417e..2f1012d 100644
a
|
b
|
CreateView
|
1031 | 1031 | A view that displays a form for creating an object, redisplaying the form |
1032 | 1032 | with validation errors (if there are any) and saving the object. |
1033 | 1033 | |
| 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 | |
1034 | 1039 | :class:`~django.views.generic.edit.BaseCreateView` implements the same |
1035 | 1040 | behavior as :class:`~django.views.generic.edit.CreateView`, but doesn't |
1036 | 1041 | include the :class:`~django.views.generic.base.TemplateResponseMixin`. |
… |
… |
CreateView
|
1040 | 1045 | * :class:`django.views.generic.edit.ModelFormMixin` |
1041 | 1046 | * :class:`django.views.generic.edit.ProcessFormView` |
1042 | 1047 | |
| 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 | |
1043 | 1057 | UpdateView |
1044 | 1058 | ~~~~~~~~~~ |
1045 | 1059 | .. class:: BaseUpdateView() |
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):
|
92 | 92 | self.assertEqual(res.status_code, 302) |
93 | 93 | self.assertRedirects(res, 'http://testserver/accounts/login/?next=/edit/authors/create/restricted/') |
94 | 94 | |
| 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 | |
95 | 104 | class UpdateViewTests(TestCase): |
96 | 105 | urls = 'regressiontests.generic_views.urls' |
97 | 106 | |
diff --git a/tests/regressiontests/generic_views/urls.py b/tests/regressiontests/generic_views/urls.py
index 090ec73..84ee509 100644
a
|
b
|
urlpatterns = patterns('',
|
71 | 71 | views.AuthorCreate.as_view()), |
72 | 72 | (r'^edit/authors/create/special/$', |
73 | 73 | views.SpecializedAuthorCreate.as_view()), |
| 74 | (r'^edit/authors/create/defaultinstance/$', |
| 75 | views.DefaultInstanceAuthorCreate.as_view()), |
74 | 76 | |
75 | 77 | (r'^edit/author/(?P<pk>\d+)/update/naive/$', |
76 | 78 | views.NaiveAuthorUpdate.as_view()), |
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
|
3 | 3 | from django.contrib.auth.decorators import login_required |
4 | 4 | from django.core.paginator import Paginator |
5 | 5 | from django.core.urlresolvers import reverse |
| 6 | from django.forms.models import modelform_factory |
6 | 7 | from django.utils.decorators import method_decorator |
7 | 8 | from django.views import generic |
8 | 9 | |
… |
… |
class AuthorCreateRestricted(AuthorCreate):
|
103 | 104 | post = method_decorator(login_required)(AuthorCreate.post) |
104 | 105 | |
105 | 106 | |
| 107 | class DefaultInstanceAuthorCreate(AuthorCreate): |
| 108 | form_class = modelform_factory(Author, fields=('name',)) |
| 109 | def get_default_fields(self): |
| 110 | return {'slug': 'default-slug'} |
| 111 | |
| 112 | |
106 | 113 | class ArtistUpdate(generic.UpdateView): |
107 | 114 | model = Artist |
108 | 115 | |