diff --git a/django/views/generic/edit.py b/django/views/generic/edit.py index ef8930650f..3146933fd5 100644 --- a/django/views/generic/edit.py +++ b/django/views/generic/edit.py @@ -1,5 +1,5 @@ from django.core.exceptions import ImproperlyConfigured -from django.forms import Form +from django.forms import Form, ModelForm from django.forms import models as model_forms from django.http import HttpResponseRedirect from django.views.generic.base import ContextMixin, TemplateResponseMixin, View @@ -103,6 +103,13 @@ class ModelFormMixin(FormMixin, SingleObjectMixin): kwargs.update({"instance": self.object}) return kwargs + def _get_model(self): + model = super()._get_model() + if model is None and self.form_class is not None: + if issubclass(self.form_class, ModelForm): + model = self.form_class.Meta.model + return model + def get_success_url(self): """Return the URL to redirect to after processing a valid form.""" if self.success_url: diff --git a/docs/releases/5.2.txt b/docs/releases/5.2.txt index 9064c46ebe..0f44e38fd4 100644 --- a/docs/releases/5.2.txt +++ b/docs/releases/5.2.txt @@ -231,6 +231,11 @@ Generic Views overridden. If ``queryset`` is provided, it takes precedence as the source of objects. +* The new :meth:`~django.views.generic.detail.SingleObjectMixin._get_model` + method is overridden in :class:`~django.views.generic.edit.ModelFormMixin` + to allow `ModelFormMixin` to retrive the view's `model` from the `form_class` + if a `ModelForm` is specified for `form_class`. + Internationalization ~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/generic_views/test_edit.py b/tests/generic_views/test_edit.py index 09d887ae92..56784bdaab 100644 --- a/tests/generic_views/test_edit.py +++ b/tests/generic_views/test_edit.py @@ -164,7 +164,7 @@ class CreateViewTests(TestCase): self.assertIsInstance(res.context["form"], views.AuthorForm) self.assertNotIn("object", res.context) self.assertNotIn("author", res.context) - self.assertTemplateUsed(res, "generic_views/form.html") + self.assertTemplateUsed(res, "generic_views/author_form.html") res = self.client.post( "/edit/authors/create/special/", @@ -324,7 +324,7 @@ class UpdateViewTests(TestCase): self.assertEqual(res.context["object"], self.author) self.assertEqual(res.context["thingy"], self.author) self.assertNotIn("author", res.context) - self.assertTemplateUsed(res, "generic_views/form.html") + self.assertTemplateUsed(res, "generic_views/author_form.html") res = self.client.post( "/edit/author/%d/update/special/" % self.author.pk, diff --git a/tests/generic_views/views.py b/tests/generic_views/views.py index bd930ef9b4..5b4c8e36d7 100644 --- a/tests/generic_views/views.py +++ b/tests/generic_views/views.py @@ -144,9 +144,7 @@ class AuthorCreate(generic.CreateView): class SpecializedAuthorCreate(generic.CreateView): - model = Author form_class = AuthorForm - template_name = "generic_views/form.html" context_object_name = "thingy" def get_success_url(self): @@ -187,9 +185,7 @@ class OneAuthorUpdate(generic.UpdateView): class SpecializedAuthorUpdate(generic.UpdateView): - model = Author form_class = AuthorForm - template_name = "generic_views/form.html" context_object_name = "thingy" def get_success_url(self):