From 6bc437c0d82675ebe6aa92c8e249892205c316ef Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Tue, 9 Nov 2021 09:03:40 +0100 Subject: [PATCH] Refs #33263 -- Added warning to BaseDeleteView when delete() method is overridden. Follow up to 3a45fea0832c5910acee6e0d29f230f347a50462. --- django/views/generic/edit.py | 20 ++++++++++++++++++++ tests/generic_views/test_edit.py | 23 ++++++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) 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()