summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/views/generic/edit.py20
-rw-r--r--tests/generic_views/test_edit.py23
2 files changed, 42 insertions, 1 deletions
diff --git a/django/views/generic/edit.py b/django/views/generic/edit.py
index d0de788c46..8cbdeb8d13 100644
--- a/django/views/generic/edit.py
+++ b/django/views/generic/edit.py
@@ -1,3 +1,5 @@
+import warnings
+
from django.core.exceptions import ImproperlyConfigured
from django.forms import Form, models as model_forms
from django.http import HttpResponseRedirect
@@ -225,6 +227,11 @@ class DeletionMixin:
"No URL to redirect to. Provide a success_url.")
+# RemovedInDjango50Warning.
+class DeleteViewCustomDeleteWarning(Warning):
+ pass
+
+
class BaseDeleteView(DeletionMixin, FormMixin, BaseDetailView):
"""
Base view for deleting an object.
@@ -233,6 +240,19 @@ class BaseDeleteView(DeletionMixin, FormMixin, BaseDetailView):
"""
form_class = Form
+ def __init__(self, *args, **kwargs):
+ # RemovedInDjango50Warning.
+ if self.__class__.delete is not DeletionMixin.delete:
+ warnings.warn(
+ f'DeleteView uses FormMixin to handle POST requests. As a '
+ f'consequence, any custom deletion logic in '
+ f'{self.__class__.__name__}.delete() handler should be moved '
+ f'to form_valid().',
+ DeleteViewCustomDeleteWarning,
+ stacklevel=2,
+ )
+ super().__init__(*args, **kwargs)
+
def post(self, request, *args, **kwargs):
# Set self.object before the usual form processing flow.
# Inlined because having DeletionMixin as the first base, for
diff --git a/tests/generic_views/test_edit.py b/tests/generic_views/test_edit.py
index d69ae6463e..4292600911 100644
--- a/tests/generic_views/test_edit.py
+++ b/tests/generic_views/test_edit.py
@@ -4,7 +4,10 @@ from django.test import SimpleTestCase, TestCase, override_settings
from django.test.client import RequestFactory
from django.urls import reverse
from django.views.generic.base import View
-from django.views.generic.edit import CreateView, FormMixin, ModelFormMixin
+from django.views.generic.edit import (
+ CreateView, DeleteView, DeleteViewCustomDeleteWarning, FormMixin,
+ ModelFormMixin,
+)
from . import views
from .forms import AuthorForm
@@ -426,3 +429,21 @@ class DeleteViewTests(TestCase):
res.context_data['form'].errors['confirm'],
['This field is required.'],
)
+
+ # RemovedInDjango50Warning.
+ def test_delete_with_custom_delete(self):
+ class AuthorDeleteView(DeleteView):
+ model = Author
+
+ def delete(self, request, *args, **kwargs):
+ # Custom logic.
+ pass
+
+ msg = (
+ 'DeleteView uses FormMixin to handle POST requests. As a '
+ 'consequence, any custom deletion logic in '
+ 'AuthorDeleteView.delete() handler should be moved to '
+ 'form_valid().'
+ )
+ with self.assertWarnsMessage(DeleteViewCustomDeleteWarning, msg):
+ AuthorDeleteView()