diff --git a/django/views/generic/detail.py b/django/views/generic/detail.py
|
a
|
b
|
|
| 58 | 58 | `get_object` is overridden. |
| 59 | 59 | """ |
| 60 | 60 | if self.queryset is None: |
| 61 | | if self.model: |
| 62 | | return self.model._default_manager.all() |
| | 61 | model = self.get_model() |
| | 62 | if model: |
| | 63 | return model._default_manager.all() |
| 63 | 64 | else: |
| 64 | 65 | raise ImproperlyConfigured(u"%(cls)s is missing a queryset. Define " |
| 65 | 66 | u"%(cls)s.model, %(cls)s.queryset, or override " |
| … |
… |
|
| 92 | 93 | context[context_object_name] = self.object |
| 93 | 94 | return context |
| 94 | 95 | |
| | 96 | def get_model(self): |
| | 97 | return self.model |
| | 98 | |
| 95 | 99 | |
| 96 | 100 | class BaseDetailView(SingleObjectMixin, View): |
| 97 | 101 | def get(self, request, **kwargs): |
| … |
… |
|
| 132 | 136 | self.object._meta.object_name.lower(), |
| 133 | 137 | self.template_name_suffix |
| 134 | 138 | )) |
| 135 | | elif hasattr(self, 'model') and hasattr(self.model, '_meta'): |
| 136 | | names.append("%s/%s%s.html" % ( |
| 137 | | self.model._meta.app_label, |
| 138 | | self.model._meta.object_name.lower(), |
| 139 | | self.template_name_suffix |
| 140 | | )) |
| | 139 | elif hasattr(self, 'get_model'): |
| | 140 | model = self.get_model() |
| | 141 | if hasattr(model, '_meta'): |
| | 142 | names.append("%s/%s%s.html" % ( |
| | 143 | model._meta.app_label, |
| | 144 | model._meta.object_name.lower(), |
| | 145 | self.template_name_suffix |
| | 146 | )) |
| 141 | 147 | return names |
| 142 | 148 | |
| 143 | 149 | |
diff --git a/django/views/generic/edit.py b/django/views/generic/edit.py
|
a
|
b
|
|
| 75 | 75 | if self.form_class: |
| 76 | 76 | return self.form_class |
| 77 | 77 | else: |
| 78 | | if self.model is not None: |
| 79 | | # If a model has been explicitly provided, use it |
| 80 | | model = self.model |
| 81 | | elif hasattr(self, 'object') and self.object is not None: |
| 82 | | # If this view is operating on a single object, use |
| 83 | | # the class of that object |
| 84 | | model = self.object.__class__ |
| 85 | | else: |
| 86 | | # Try to get a queryset and extract the model class |
| 87 | | # from that |
| 88 | | model = self.get_queryset().model |
| | 78 | model = self.get_model() |
| 89 | 79 | return model_forms.modelform_factory(model) |
| 90 | 80 | |
| 91 | 81 | def get_form_kwargs(self): |
| … |
… |
|
| 120 | 110 | if context_object_name: |
| 121 | 111 | context[context_object_name] = self.object |
| 122 | 112 | return context |
| | 113 | |
| | 114 | def get_model(self): |
| | 115 | if self.model: |
| | 116 | return self.model |
| | 117 | elif self.form_class and issubclass(self.form_class, model_forms.ModelForm): |
| | 118 | return self.form_class._meta.model |
| | 119 | elif hasattr(self, 'object') and self.object is not None: |
| | 120 | return self.object.__class__ |
| | 121 | else: |
| | 122 | return self.get_queryset().model |
| 123 | 123 | |
| 124 | 124 | |
| 125 | 125 | class ProcessFormView(View): |
diff --git a/tests/regressiontests/generic_views/edit.py b/tests/regressiontests/generic_views/edit.py
|
a
|
b
|
|
| 75 | 75 | self.assertRedirects(res, reverse('author_detail', kwargs={'pk': obj.pk})) |
| 76 | 76 | self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe>']) |
| 77 | 77 | |
| | 78 | def test_create_with_only_form_class(self): |
| | 79 | res = self.client.get('/edit/artists/create/formclass/') |
| | 80 | self.assertEqual(res.status_code, 200) |
| | 81 | self.assertTrue(isinstance(res.context['form'], views.ArtistForm)) |
| | 82 | self.assertFalse('object' in res.context) |
| | 83 | self.assertFalse('artist' in res.context) |
| | 84 | self.assertTemplateUsed(res, 'generic_views/artist_form.html') |
| | 85 | |
| | 86 | res = self.client.post('/edit/artists/create/formclass/', |
| | 87 | {'name': 'Rene Magritte'}) |
| | 88 | self.assertEqual(res.status_code, 302) |
| | 89 | artist = Artist.objects.get(name='Rene Magritte') |
| | 90 | self.assertRedirects(res, 'http://testserver/detail/artist/%d/' % artist.pk) |
| | 91 | self.assertQuerysetEqual(Artist.objects.all(), ['<Artist: Rene Magritte>']) |
| | 92 | |
| 78 | 93 | def test_create_without_redirect(self): |
| 79 | 94 | try: |
| 80 | 95 | res = self.client.post('/edit/authors/create/naive/', |
diff --git a/tests/regressiontests/generic_views/forms.py b/tests/regressiontests/generic_views/forms.py
|
a
|
b
|
|
| 1 | 1 | from django import forms |
| 2 | 2 | |
| 3 | | from regressiontests.generic_views.models import Author |
| | 3 | from regressiontests.generic_views.models import Author, Artist |
| 4 | 4 | |
| 5 | 5 | |
| 6 | 6 | class AuthorForm(forms.ModelForm): |
| … |
… |
|
| 9 | 9 | |
| 10 | 10 | class Meta: |
| 11 | 11 | model = Author |
| | 12 | |
| | 13 | |
| | 14 | class ArtistForm(forms.ModelForm): |
| | 15 | name = forms.CharField() |
| | 16 | |
| | 17 | class Meta: |
| | 18 | model = Artist |
diff --git a/tests/regressiontests/generic_views/urls.py b/tests/regressiontests/generic_views/urls.py
|
a
|
b
|
|
| 54 | 54 | # Create/UpdateView |
| 55 | 55 | (r'^edit/artists/create/$', |
| 56 | 56 | views.ArtistCreate.as_view()), |
| | 57 | (r'^edit/artists/create/formclass/$', |
| | 58 | views.ArtistOnlyFormClassCreate.as_view()), |
| 57 | 59 | (r'^edit/artists/(?P<pk>\d+)/update/$', |
| 58 | 60 | views.ArtistUpdate.as_view()), |
| 59 | 61 | |
diff --git a/tests/regressiontests/generic_views/views.py b/tests/regressiontests/generic_views/views.py
|
a
|
b
|
|
| 5 | 5 | from django.views import generic |
| 6 | 6 | |
| 7 | 7 | from regressiontests.generic_views.models import Artist, Author, Book, Page |
| 8 | | from regressiontests.generic_views.forms import AuthorForm |
| | 8 | from regressiontests.generic_views.forms import AuthorForm, ArtistForm |
| 9 | 9 | |
| 10 | 10 | |
| 11 | 11 | class CustomTemplateView(generic.TemplateView): |
| … |
… |
|
| 77 | 77 | class ArtistCreate(generic.CreateView): |
| 78 | 78 | model = Artist |
| 79 | 79 | |
| | 80 | class ArtistOnlyFormClassCreate(generic.CreateView): |
| | 81 | form_class = ArtistForm |
| | 82 | |
| 80 | 83 | |
| 81 | 84 | class NaiveAuthorCreate(generic.CreateView): |
| 82 | 85 | queryset = Author.objects.all() |