Fixed #15247 -- Ensured that if a SingleObject view defines get_object but not get_queryset, the ModelFormMixin doesn't fail. Thanks to Sergey N. Belinsky for the report and test case.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@15540 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2011-02-15 08:12:29 +00:00
parent 4bb2db0cae
commit 64b042bb3c
4 changed files with 39 additions and 1 deletions

View File

@ -75,6 +75,16 @@ class ModelFormMixin(FormMixin, SingleObjectMixin):
if self.form_class: if self.form_class:
return self.form_class return self.form_class
else: else:
if self.model is not None:
# If a model has been explicitly provided, use it
model = self.model
elif hasattr(self, 'object') and self.object is not None:
# If this view is operating on a single object, use
# the class of that object
model = self.object.__class__
else:
# Try to get a queryset and extract the model class
# from that
model = self.get_queryset().model model = self.get_queryset().model
return model_forms.modelform_factory(model) return model_forms.modelform_factory(model)

View File

@ -201,6 +201,25 @@ class UpdateViewTests(TestCase):
except ImproperlyConfigured: except ImproperlyConfigured:
pass pass
def test_update_get_object(self):
a = Author.objects.create(
name='Randall Munroe',
slug='randall-munroe',
)
res = self.client.get('/edit/author/update/')
self.assertEqual(res.status_code, 200)
self.assertTrue(isinstance(res.context['form'], forms.ModelForm))
self.assertEqual(res.context['object'], Author.objects.get(pk=a.pk))
self.assertEqual(res.context['author'], Author.objects.get(pk=a.pk))
self.assertTemplateUsed(res, 'generic_views/author_form.html')
# Modification with both POST and PUT (browser compatible)
res = self.client.post('/edit/author/update/',
{'name': 'Randall Munroe (xkcd)', 'slug': 'randall-munroe'})
self.assertEqual(res.status_code, 302)
self.assertRedirects(res, 'http://testserver/list/authors/')
self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe (xkcd)>'])
class DeleteViewTests(TestCase): class DeleteViewTests(TestCase):
urls = 'regressiontests.generic_views.urls' urls = 'regressiontests.generic_views.urls'

View File

@ -74,6 +74,8 @@ urlpatterns = patterns('',
views.NaiveAuthorUpdate.as_view(success_url='/edit/author/%(id)d/update/')), views.NaiveAuthorUpdate.as_view(success_url='/edit/author/%(id)d/update/')),
(r'^edit/author/(?P<pk>\d+)/update/$', (r'^edit/author/(?P<pk>\d+)/update/$',
views.AuthorUpdate.as_view()), views.AuthorUpdate.as_view()),
(r'^edit/author/update/$',
views.OneAuthorUpdate.as_view()),
(r'^edit/author/(?P<pk>\d+)/update/special/$', (r'^edit/author/(?P<pk>\d+)/update/special/$',
views.SpecializedAuthorUpdate.as_view()), views.SpecializedAuthorUpdate.as_view()),
(r'^edit/author/(?P<pk>\d+)/delete/naive/$', (r'^edit/author/(?P<pk>\d+)/delete/naive/$',

View File

@ -114,6 +114,13 @@ class AuthorUpdate(generic.UpdateView):
success_url = '/list/authors/' success_url = '/list/authors/'
class OneAuthorUpdate(generic.UpdateView):
success_url = '/list/authors/'
def get_object(self):
return Author.objects.get(pk=1)
class SpecializedAuthorUpdate(generic.UpdateView): class SpecializedAuthorUpdate(generic.UpdateView):
model = Author model = Author
form_class = AuthorForm form_class = AuthorForm