mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	Fixed #34303 –- Allowed customizing admin site log entry list.
Added AdminSite.get_log_entries() as an override point and made this available to the template via each_context().
This commit is contained in:
		| @@ -336,6 +336,7 @@ class AdminSite: | ||||
|             "available_apps": self.get_app_list(request), | ||||
|             "is_popup": False, | ||||
|             "is_nav_sidebar_enabled": self.enable_nav_sidebar, | ||||
|             "log_entries": self.get_log_entries(request), | ||||
|         } | ||||
|  | ||||
|     def password_change(self, request, extra_context=None): | ||||
| @@ -588,6 +589,11 @@ class AdminSite: | ||||
|             context, | ||||
|         ) | ||||
|  | ||||
|     def get_log_entries(self, request): | ||||
|         from django.contrib.admin.models import LogEntry | ||||
|  | ||||
|         return LogEntry.objects.select_related("content_type", "user") | ||||
|  | ||||
|  | ||||
| class DefaultAdminSite(LazyObject): | ||||
|     def _setup(self): | ||||
|   | ||||
| @@ -1,5 +1,4 @@ | ||||
| from django import template | ||||
| from django.contrib.admin.models import LogEntry | ||||
|  | ||||
| register = template.Library() | ||||
|  | ||||
| @@ -12,16 +11,13 @@ class AdminLogNode(template.Node): | ||||
|         return "<GetAdminLog Node>" | ||||
|  | ||||
|     def render(self, context): | ||||
|         if self.user is None: | ||||
|             entries = LogEntry.objects.all() | ||||
|         else: | ||||
|         entries = context["log_entries"] | ||||
|         if self.user is not None: | ||||
|             user_id = self.user | ||||
|             if not user_id.isdigit(): | ||||
|                 user_id = context[self.user].pk | ||||
|             entries = LogEntry.objects.filter(user__pk=user_id) | ||||
|         context[self.varname] = entries.select_related("content_type", "user")[ | ||||
|             : int(self.limit) | ||||
|         ] | ||||
|             entries = entries.filter(user__pk=user_id) | ||||
|         context[self.varname] = entries[: int(self.limit)] | ||||
|         return "" | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -2832,6 +2832,7 @@ Templates can override or extend base admin templates as described in | ||||
|  | ||||
|     * ``is_popup``: whether the current page is displayed in a popup window | ||||
|     * ``is_nav_sidebar_enabled``: :attr:`AdminSite.enable_nav_sidebar` | ||||
|     * ``log_entries``: :meth:`.AdminSite.get_log_entries` | ||||
|  | ||||
| .. method:: AdminSite.get_app_list(request, app_label=None) | ||||
|  | ||||
| @@ -2889,6 +2890,15 @@ Templates can override or extend base admin templates as described in | ||||
|     Raises ``django.contrib.admin.sites.NotRegistered`` if a model isn't | ||||
|     already registered. | ||||
|  | ||||
| .. method:: AdminSite.get_log_entries(request) | ||||
|  | ||||
|     .. versionadded:: 5.0 | ||||
|  | ||||
|     Returns a queryset for the related | ||||
|     :class:`~django.contrib.admin.models.LogEntry` instances, shown on the site | ||||
|     index page. This method can be overridden to filter the log entries by | ||||
|     other criteria. | ||||
|  | ||||
| .. _hooking-adminsite-to-urlconf: | ||||
|  | ||||
| Hooking ``AdminSite`` instances into your URLconf | ||||
|   | ||||
| @@ -43,7 +43,8 @@ Minor features | ||||
| :mod:`django.contrib.admin` | ||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|  | ||||
| * ... | ||||
| * The new :meth:`.AdminSite.get_log_entries` method allows customizing the | ||||
|   queryset for the site's listed log entries. | ||||
|  | ||||
| :mod:`django.contrib.admindocs` | ||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|   | ||||
| @@ -1595,7 +1595,12 @@ class GetAdminLogTests(TestCase): | ||||
|         {% get_admin_log %} works if the user model's primary key isn't named | ||||
|         'id'. | ||||
|         """ | ||||
|         context = Context({"user": CustomIdUser()}) | ||||
|         context = Context( | ||||
|             { | ||||
|                 "user": CustomIdUser(), | ||||
|                 "log_entries": LogEntry.objects.all(), | ||||
|             } | ||||
|         ) | ||||
|         template = Template( | ||||
|             "{% load log %}{% get_admin_log 10 as admin_log for_user user %}" | ||||
|         ) | ||||
| @@ -1608,6 +1613,7 @@ class GetAdminLogTests(TestCase): | ||||
|         user.save() | ||||
|         ct = ContentType.objects.get_for_model(User) | ||||
|         LogEntry.objects.log_action(user.pk, ct.pk, user.pk, repr(user), 1) | ||||
|         context = Context({"log_entries": LogEntry.objects.all()}) | ||||
|         t = Template( | ||||
|             "{% load log %}" | ||||
|             "{% get_admin_log 100 as admin_log %}" | ||||
| @@ -1615,7 +1621,7 @@ class GetAdminLogTests(TestCase): | ||||
|             "{{ entry|safe }}" | ||||
|             "{% endfor %}" | ||||
|         ) | ||||
|         self.assertEqual(t.render(Context({})), "Added “<User: jondoe>”.") | ||||
|         self.assertEqual(t.render(context), "Added “<User: jondoe>”.") | ||||
|  | ||||
|     def test_missing_args(self): | ||||
|         msg = "'get_admin_log' statements require two arguments" | ||||
|   | ||||
| @@ -35,3 +35,19 @@ site = admin.AdminSite(name="admin") | ||||
| site.register(Article) | ||||
| site.register(ArticleProxy) | ||||
| site.register(Site, SiteAdmin) | ||||
|  | ||||
|  | ||||
| class CustomAdminSite(admin.AdminSite): | ||||
|     def get_log_entries(self, request): | ||||
|         from django.contrib.contenttypes.models import ContentType | ||||
|  | ||||
|         log_entries = super().get_log_entries(request) | ||||
|         return log_entries.filter( | ||||
|             content_type__in=ContentType.objects.get_for_models( | ||||
|                 *self._registry.keys() | ||||
|             ).values() | ||||
|         ) | ||||
|  | ||||
|  | ||||
| custom_site = CustomAdminSite(name="custom_admin") | ||||
| custom_site.register(Article) | ||||
|   | ||||
| @@ -10,7 +10,7 @@ from django.urls import reverse | ||||
| from django.utils import translation | ||||
| from django.utils.html import escape | ||||
|  | ||||
| from .models import Article, ArticleProxy, Site | ||||
| from .models import Article, ArticleProxy, Car, Site | ||||
|  | ||||
|  | ||||
| @override_settings(ROOT_URLCONF="admin_utils.urls") | ||||
| @@ -318,3 +318,30 @@ class LogEntryTests(TestCase): | ||||
|             with self.subTest(action_flag=action_flag): | ||||
|                 log = LogEntry(action_flag=action_flag) | ||||
|                 self.assertEqual(log.get_action_flag_display(), display_name) | ||||
|  | ||||
|     def test_hook_get_log_entries(self): | ||||
|         LogEntry.objects.log_action( | ||||
|             self.user.pk, | ||||
|             ContentType.objects.get_for_model(Article).pk, | ||||
|             self.a1.pk, | ||||
|             "Article changed", | ||||
|             CHANGE, | ||||
|             change_message="Article changed message", | ||||
|         ) | ||||
|         c1 = Car.objects.create() | ||||
|         LogEntry.objects.log_action( | ||||
|             self.user.pk, | ||||
|             ContentType.objects.get_for_model(Car).pk, | ||||
|             c1.pk, | ||||
|             "Car created", | ||||
|             ADDITION, | ||||
|             change_message="Car created message", | ||||
|         ) | ||||
|         response = self.client.get(reverse("admin:index")) | ||||
|         self.assertContains(response, "Article changed") | ||||
|         self.assertContains(response, "Car created") | ||||
|  | ||||
|         # site "custom_admin" only renders log entries of registered models | ||||
|         response = self.client.get(reverse("custom_admin:index")) | ||||
|         self.assertContains(response, "Article changed") | ||||
|         self.assertNotContains(response, "Car created") | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| from django.urls import path | ||||
|  | ||||
| from .admin import site | ||||
| from .admin import custom_site, site | ||||
|  | ||||
| urlpatterns = [ | ||||
|     path("test_admin/admin/", site.urls), | ||||
|     path("test_admin/custom_admin/", custom_site.urls), | ||||
| ] | ||||
|   | ||||
		Reference in New Issue
	
	Block a user