[Backport] Improving performance for history api
parent
b6e513e73b
commit
e8bcc84b35
|
@ -102,8 +102,8 @@ class HistoryViewSet(ReadOnlyListViewSet):
|
|||
def retrieve(self, request, pk):
|
||||
obj = self.get_object()
|
||||
self.check_permissions(request, "retrieve", obj)
|
||||
|
||||
qs = services.get_history_queryset_by_model_instance(obj)
|
||||
qs = services.prefetch_owners_in_history_queryset(qs)
|
||||
return self.response_for_queryset(qs)
|
||||
|
||||
|
||||
|
|
|
@ -78,6 +78,8 @@ class HistoryEntry(models.Model):
|
|||
is_snapshot = models.BooleanField(default=False)
|
||||
|
||||
_importing = None
|
||||
_owner = None
|
||||
_prefetched_owner = False
|
||||
|
||||
@cached_property
|
||||
def is_change(self):
|
||||
|
@ -91,14 +93,23 @@ class HistoryEntry(models.Model):
|
|||
def is_delete(self):
|
||||
return self.type == HistoryType.delete
|
||||
|
||||
@cached_property
|
||||
@property
|
||||
def owner(self):
|
||||
pk = self.user["pk"]
|
||||
model = get_user_model()
|
||||
try:
|
||||
return model.objects.get(pk=pk)
|
||||
except model.DoesNotExist:
|
||||
return None
|
||||
if not self._prefetched_owner:
|
||||
pk = self.user["pk"]
|
||||
model = get_user_model()
|
||||
try:
|
||||
owner = model.objects.get(pk=pk)
|
||||
except model.DoesNotExist:
|
||||
owner = None
|
||||
|
||||
self.prefetch_owner(owner)
|
||||
|
||||
return self._owner
|
||||
|
||||
def prefetch_owner(self, owner):
|
||||
self._owner = owner
|
||||
self._prefetched_owner = True
|
||||
|
||||
@cached_property
|
||||
def values_diff(self):
|
||||
|
|
|
@ -33,6 +33,7 @@ from functools import wraps
|
|||
from functools import lru_cache
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.paginator import Paginator, InvalidPage
|
||||
from django.apps import apps
|
||||
|
@ -352,6 +353,16 @@ def get_history_queryset_by_model_instance(obj:object, types=(HistoryType.change
|
|||
return qs.order_by("created_at")
|
||||
|
||||
|
||||
def prefetch_owners_in_history_queryset(qs):
|
||||
user_ids = [u["pk"] for u in qs.values_list("user", flat=True)]
|
||||
users = get_user_model().objects.filter(id__in=user_ids)
|
||||
users_by_id = {u.id: u for u in users}
|
||||
for history_entry in qs:
|
||||
history_entry.prefetch_owner(users_by_id.get(history_entry.user["pk"], None))
|
||||
|
||||
return qs
|
||||
|
||||
|
||||
# Freeze implementatitions
|
||||
from .freeze_impl import project_freezer
|
||||
from .freeze_impl import milestone_freezer
|
||||
|
|
Loading…
Reference in New Issue