Retrieve instances with log entries and use AdminURLFinder to locate edit URLs

pull/7535/head
Matt Westcott 2021-09-08 15:15:45 +01:00
rodzic 52e598179c
commit d67fdd1b8b
3 zmienionych plików z 36 dodań i 10 usunięć

Wyświetl plik

@ -27,13 +27,8 @@
{% for entry in object_list %}
<tr>
<td class="title">
{% if entry.page %}
{% page_permissions entry.page as page_perms %}
{% if page_perms.can_edit %}
<a href="{% url 'wagtailadmin_pages:edit' entry.page_id %}" title="{% trans 'Edit this page' %}">{{ entry.label }}</a>
{% else %}
{{ entry.label }}
{% endif %}
{% if entry.edit_url %}
<a href="{{ entry.edit_url }}" title="{% trans 'Edit this item' %}">{{ entry.label }}</a>
{% else %}
{{ entry.label }}
{% endif %}

Wyświetl plik

@ -11,6 +11,7 @@ from django.db.models import IntegerField, Value
from django.utils.encoding import force_str
from django.utils.translation import gettext_lazy as _
from wagtail.admin.admin_url_finder import AdminURLFinder
from wagtail.admin.filters import ContentTypeFilter, DateRangePickerWidget, WagtailFilterSet
from wagtail.core.log_actions import registry as log_action_registry
from wagtail.core.models import PageLogEntry
@ -158,6 +159,8 @@ class LogEntriesView(ReportView):
for row in queryset:
pks_by_log_model_index[row['log_model_index']].append(row['pk'])
url_finder = AdminURLFinder(self.request.user)
# for each log model found in the queryset, look up the set of log entries by id
# and build a lookup table
object_lookup = {}
@ -165,10 +168,13 @@ class LogEntriesView(ReportView):
log_entries = (
self.log_models[log_model_index].objects
.prefetch_related('user__wagtail_userprofile', 'content_type')
.in_bulk(pks)
.filter(pk__in=pks)
.with_instances()
)
for pk, log_entry in log_entries.items():
object_lookup[(log_model_index, pk)] = log_entry
for log_entry, instance in log_entries:
# annotate log entry with an 'edit_url' property
log_entry.edit_url = url_finder.get_edit_url(instance)
object_lookup[(log_model_index, log_entry.pk)] = log_entry
# return items from our lookup table in the order of the original queryset
return [

Wyświetl plik

@ -6,6 +6,8 @@ wagtail.core.models module or specific models such as Page.
import json
from collections import defaultdict
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
@ -46,6 +48,29 @@ class LogEntryQuerySet(models.QuerySet):
# instances (e.g. PageLogEntry, which treats all page types as a single Page type)
return self.filter(content_type_id=content_type.id)
def with_instances(self):
# return an iterable of (log_entry, instance) tuples for all log entries in this queryset.
# instance is None if the instance does not exist.
# Note: This is an expensive operation and should only be done on small querysets
# (e.g. after pagination).
# evaluate the queryset in full now, as we'll be iterating over it multiple times
log_entries = list(self)
ids_by_content_type = defaultdict(list)
for log_entry in log_entries:
ids_by_content_type[log_entry.content_type_id].append(log_entry.object_id)
instances_by_id = {} # lookup of (content_type_id, stringified_object_id) to instance
for content_type_id, object_ids in ids_by_content_type.items():
model = ContentType.objects.get_for_id(content_type_id).model_class()
model_instances = model.objects.in_bulk(object_ids)
for object_id, instance in model_instances.items():
instances_by_id[(content_type_id, str(object_id))] = instance
for log_entry in log_entries:
lookup_key = (log_entry.content_type_id, str(log_entry.object_id))
yield (log_entry, instances_by_id.get(lookup_key))
class BaseLogEntryManager(models.Manager):
def get_queryset(self):