Refs #33263 -- Added warning to BaseDeleteView when delete() method is overridden.

Follow up to 3a45fea083.
This commit is contained in:
Mariusz Felisiak 2021-11-09 09:03:40 +01:00 committed by GitHub
parent 948d6d8805
commit 6bc437c0d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 1 deletions

View File

@ -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

View File

@ -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()