summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2024-12-12 16:55:42 +0100
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2025-01-15 22:28:37 +0100
commit6c120508b6445cb0d6198b4eacccd411960686d2 (patch)
tree95eda814c10c2d78b1f0d4dc258b55b17fecea49
parent817bc5800b40bcc74534de5e5176919cb826494f (diff)
Refs #34462 -- Removed ModelAdmin.log_deletion() and LogEntryManager.log_action() per deprecation timeline.
-rw-r--r--django/contrib/admin/models.py49
-rw-r--r--django/contrib/admin/options.py34
-rw-r--r--docs/releases/6.0.txt3
-rw-r--r--tests/admin_utils/models.py24
-rw-r--r--tests/admin_utils/test_logentry.py59
-rw-r--r--tests/modeladmin/tests.py75
6 files changed, 4 insertions, 240 deletions
diff --git a/django/contrib/admin/models.py b/django/contrib/admin/models.py
index bb81be8297..5723ebff7f 100644
--- a/django/contrib/admin/models.py
+++ b/django/contrib/admin/models.py
@@ -1,5 +1,4 @@
import json
-import warnings
from django.conf import settings
from django.contrib.admin.utils import quote
@@ -7,7 +6,6 @@ from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.urls import NoReverseMatch, reverse
from django.utils import timezone
-from django.utils.deprecation import RemovedInDjango60Warning
from django.utils.text import get_text_list
from django.utils.translation import gettext
from django.utils.translation import gettext_lazy as _
@@ -26,56 +24,9 @@ ACTION_FLAG_CHOICES = [
class LogEntryManager(models.Manager):
use_in_migrations = True
- def log_action(
- self,
- user_id,
- content_type_id,
- object_id,
- object_repr,
- action_flag,
- change_message="",
- ):
- warnings.warn(
- "LogEntryManager.log_action() is deprecated. Use log_actions() instead.",
- RemovedInDjango60Warning,
- stacklevel=2,
- )
- if isinstance(change_message, list):
- change_message = json.dumps(change_message)
- return self.model.objects.create(
- user_id=user_id,
- content_type_id=content_type_id,
- object_id=str(object_id),
- object_repr=object_repr[:200],
- action_flag=action_flag,
- change_message=change_message,
- )
-
def log_actions(
self, user_id, queryset, action_flag, change_message="", *, single_object=False
):
- # RemovedInDjango60Warning.
- if type(self).log_action != LogEntryManager.log_action:
- warnings.warn(
- "The usage of log_action() is deprecated. Implement log_actions() "
- "instead.",
- RemovedInDjango60Warning,
- stacklevel=2,
- )
- return [
- self.log_action(
- user_id=user_id,
- content_type_id=ContentType.objects.get_for_model(
- obj, for_concrete_model=False
- ).id,
- object_id=obj.pk,
- object_repr=str(obj),
- action_flag=action_flag,
- change_message=change_message,
- )
- for obj in queryset
- ]
-
if isinstance(change_message, list):
change_message = json.dumps(change_message)
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index 25987171bf..3c2cf9d130 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -2,7 +2,6 @@ import copy
import enum
import json
import re
-import warnings
from functools import partial, update_wrapper
from urllib.parse import parse_qsl
from urllib.parse import quote as urlquote
@@ -56,7 +55,6 @@ from django.http.response import HttpResponseBase
from django.template.response import SimpleTemplateResponse, TemplateResponse
from django.urls import reverse
from django.utils.decorators import method_decorator
-from django.utils.deprecation import RemovedInDjango60Warning
from django.utils.html import format_html
from django.utils.http import urlencode
from django.utils.safestring import mark_safe
@@ -967,28 +965,6 @@ class ModelAdmin(BaseModelAdmin):
single_object=True,
)
- def log_deletion(self, request, obj, object_repr):
- """
- Log that an object will be deleted. Note that this method must be
- called before the deletion.
-
- The default implementation creates an admin LogEntry object.
- """
- warnings.warn(
- "ModelAdmin.log_deletion() is deprecated. Use log_deletions() instead.",
- RemovedInDjango60Warning,
- stacklevel=2,
- )
- from django.contrib.admin.models import DELETION, LogEntry
-
- return LogEntry.objects.log_action(
- user_id=request.user.pk,
- content_type_id=get_content_type_for_model(obj).pk,
- object_id=obj.pk,
- object_repr=object_repr,
- action_flag=DELETION,
- )
-
def log_deletions(self, request, queryset):
"""
Log that objects will be deleted. Note that this method must be called
@@ -998,16 +974,6 @@ class ModelAdmin(BaseModelAdmin):
"""
from django.contrib.admin.models import DELETION, LogEntry
- # RemovedInDjango60Warning.
- if type(self).log_deletion != ModelAdmin.log_deletion:
- warnings.warn(
- "The usage of log_deletion() is deprecated. Implement log_deletions() "
- "instead.",
- RemovedInDjango60Warning,
- stacklevel=2,
- )
- return [self.log_deletion(request, obj, str(obj)) for obj in queryset]
-
return LogEntry.objects.log_actions(
user_id=request.user.pk,
queryset=queryset,
diff --git a/docs/releases/6.0.txt b/docs/releases/6.0.txt
index 1f6f9a79da..e3f6c8afed 100644
--- a/docs/releases/6.0.txt
+++ b/docs/releases/6.0.txt
@@ -299,3 +299,6 @@ to remove usage of these features.
* ``django.urls.register_converter()`` no longer allows overriding existing
converters.
+
+* The ``ModelAdmin.log_deletion()`` and ``LogEntryManager.log_action()``
+ methods are removed.
diff --git a/tests/admin_utils/models.py b/tests/admin_utils/models.py
index 8e812e27eb..243f314b03 100644
--- a/tests/admin_utils/models.py
+++ b/tests/admin_utils/models.py
@@ -1,5 +1,4 @@
from django.contrib import admin
-from django.contrib.admin.models import LogEntry, LogEntryManager
from django.db import models
from django.utils.translation import gettext_lazy as _
@@ -87,26 +86,3 @@ class VehicleMixin(Vehicle):
class Car(VehicleMixin):
pass
-
-
-class InheritedLogEntryManager(LogEntryManager):
- model = LogEntry
-
- def log_action(
- self,
- user_id,
- content_type_id,
- object_id,
- object_repr,
- action_flag,
- change_message="",
- ):
- return LogEntry.objects.create(
- user_id=user_id,
- content_type_id=content_type_id,
- object_id=str(object_id),
- # Changing actual repr to test repr
- object_repr="Test Repr",
- action_flag=action_flag,
- change_message=change_message,
- )
diff --git a/tests/admin_utils/test_logentry.py b/tests/admin_utils/test_logentry.py
index e97441eb2e..491a220199 100644
--- a/tests/admin_utils/test_logentry.py
+++ b/tests/admin_utils/test_logentry.py
@@ -8,10 +8,9 @@ from django.contrib.contenttypes.models import ContentType
from django.test import TestCase, override_settings
from django.urls import reverse
from django.utils import translation
-from django.utils.deprecation import RemovedInDjango60Warning
from django.utils.html import escape
-from .models import Article, ArticleProxy, Car, InheritedLogEntryManager, Site
+from .models import Article, ArticleProxy, Car, Site
@override_settings(ROOT_URLCONF="admin_utils.urls")
@@ -236,22 +235,6 @@ class LogEntryTests(TestCase):
logentry = LogEntry.objects.first()
self.assertEqual(repr(logentry), str(logentry.action_time))
- # RemovedInDjango60Warning.
- def test_log_action(self):
- msg = "LogEntryManager.log_action() is deprecated. Use log_actions() instead."
- content_type_val = ContentType.objects.get_for_model(Article).pk
- with self.assertWarnsMessage(RemovedInDjango60Warning, msg) as ctx:
- log_entry = LogEntry.objects.log_action(
- self.user.pk,
- content_type_val,
- self.a1.pk,
- repr(self.a1),
- CHANGE,
- change_message="Changed something else",
- )
- self.assertEqual(log_entry, LogEntry.objects.latest("id"))
- self.assertEqual(ctx.filename, __file__)
-
def test_log_actions(self):
queryset = Article.objects.all().order_by("-id")
msg = "Deleted Something"
@@ -289,46 +272,6 @@ class LogEntryTests(TestCase):
]
self.assertSequenceEqual(logs, expected_log_values)
- # RemovedInDjango60Warning.
- def test_log_action_fallback(self):
- LogEntry.objects2 = InheritedLogEntryManager()
- queryset = Article.objects.all().order_by("-id")
- content_type = ContentType.objects.get_for_model(self.a1)
- self.assertEqual(len(queryset), 3)
- msg = (
- "The usage of log_action() is deprecated. Implement log_actions() instead."
- )
- with (
- self.assertNumQueries(3),
- self.assertWarnsMessage(RemovedInDjango60Warning, msg) as ctx,
- ):
- LogEntry.objects2.log_actions(self.user.pk, queryset, DELETION)
- self.assertEqual(ctx.filename, __file__)
- log_values = (
- LogEntry.objects.filter(action_flag=DELETION)
- .order_by("id")
- .values_list(
- "user",
- "content_type",
- "object_id",
- "object_repr",
- "action_flag",
- "change_message",
- )
- )
- expected_log_values = [
- (
- self.user.pk,
- content_type.id,
- str(obj.pk),
- "Test Repr",
- DELETION,
- "",
- )
- for obj in queryset
- ]
- self.assertSequenceEqual(log_values, expected_log_values)
-
def test_recentactions_without_content_type(self):
"""
If a LogEntry is missing content_type it will not display it in span
diff --git a/tests/modeladmin/tests.py b/tests/modeladmin/tests.py
index 00db6c19bc..3d2e8d00fb 100644
--- a/tests/modeladmin/tests.py
+++ b/tests/modeladmin/tests.py
@@ -21,7 +21,6 @@ from django.db import models
from django.forms.widgets import Select
from django.test import RequestFactory, SimpleTestCase, TestCase
from django.test.utils import isolate_apps
-from django.utils.deprecation import RemovedInDjango60Warning
from .models import Band, Concert, Song
@@ -891,80 +890,6 @@ class ModelAdminTests(TestCase):
]
self.assertSequenceEqual(logs, expected_log_values)
- # RemovedInDjango60Warning.
- def test_log_deletion(self):
- ma = ModelAdmin(Band, self.site)
- mock_request = MockRequest()
- mock_request.user = User.objects.create(username="bill")
- content_type = get_content_type_for_model(self.band)
- msg = "ModelAdmin.log_deletion() is deprecated. Use log_deletions() instead."
- with self.assertWarnsMessage(RemovedInDjango60Warning, msg) as ctx:
- created = ma.log_deletion(mock_request, self.band, str(self.band))
- self.assertEqual(ctx.filename, __file__)
- fetched = LogEntry.objects.filter(action_flag=DELETION).latest("id")
- self.assertEqual(created, fetched)
- self.assertEqual(fetched.action_flag, DELETION)
- self.assertEqual(fetched.content_type, content_type)
- self.assertEqual(fetched.object_id, str(self.band.pk))
- self.assertEqual(fetched.user, mock_request.user)
- self.assertEqual(fetched.change_message, "")
- self.assertEqual(fetched.object_repr, str(self.band))
-
- # RemovedInDjango60Warning.
- def test_log_deletion_fallback(self):
- class InheritedModelAdmin(ModelAdmin):
- def log_deletion(self, request, obj, object_repr):
- return super().log_deletion(request, obj, object_repr)
-
- ima = InheritedModelAdmin(Band, self.site)
- mock_request = MockRequest()
- mock_request.user = User.objects.create(username="akash")
- content_type = get_content_type_for_model(self.band)
- Band.objects.create(
- name="The Beatles",
- bio="A legendary rock band from Liverpool.",
- sign_date=date(1962, 1, 1),
- )
- Band.objects.create(
- name="Mohiner Ghoraguli",
- bio="A progressive rock band from Calcutta.",
- sign_date=date(1975, 1, 1),
- )
- queryset = Band.objects.all().order_by("-id")[:3]
- self.assertEqual(len(queryset), 3)
- msg = (
- "The usage of log_deletion() is deprecated. Implement log_deletions() "
- "instead."
- )
- with self.assertNumQueries(3):
- with self.assertWarnsMessage(RemovedInDjango60Warning, msg) as ctx:
- ima.log_deletions(mock_request, queryset)
- self.assertEqual(ctx.filename, __file__)
- logs = (
- LogEntry.objects.filter(action_flag=DELETION)
- .order_by("id")
- .values_list(
- "user_id",
- "content_type",
- "object_id",
- "object_repr",
- "action_flag",
- "change_message",
- )
- )
- expected_log_values = [
- (
- mock_request.user.id,
- content_type.id,
- str(obj.pk),
- str(obj),
- DELETION,
- "",
- )
- for obj in queryset
- ]
- self.assertSequenceEqual(logs, expected_log_values)
-
def test_get_autocomplete_fields(self):
class NameAdmin(ModelAdmin):
search_fields = ["name"]