Merge pull request #723 from taigaio/improving-performance-for-history-api

Improving performance for history api
remotes/origin/issue/4795/notification_even_they_are_disabled
David Barragán Merino 2016-05-12 15:02:08 +02:00
commit 7bbb90b61a
3 changed files with 31 additions and 9 deletions

View File

@ -102,8 +102,8 @@ class HistoryViewSet(ReadOnlyListViewSet):
def retrieve(self, request, pk): def retrieve(self, request, pk):
obj = self.get_object() obj = self.get_object()
self.check_permissions(request, "retrieve", obj) self.check_permissions(request, "retrieve", obj)
qs = services.get_history_queryset_by_model_instance(obj) qs = services.get_history_queryset_by_model_instance(obj)
qs = services.prefetch_owners_in_history_queryset(qs)
return self.response_for_queryset(qs) return self.response_for_queryset(qs)

View File

@ -78,6 +78,8 @@ class HistoryEntry(models.Model):
is_snapshot = models.BooleanField(default=False) is_snapshot = models.BooleanField(default=False)
_importing = None _importing = None
_owner = None
_prefetched_owner = False
@cached_property @cached_property
def is_change(self): def is_change(self):
@ -91,14 +93,23 @@ class HistoryEntry(models.Model):
def is_delete(self): def is_delete(self):
return self.type == HistoryType.delete return self.type == HistoryType.delete
@cached_property @property
def owner(self): def owner(self):
pk = self.user["pk"] if not self._prefetched_owner:
model = get_user_model() pk = self.user["pk"]
try: model = get_user_model()
return model.objects.get(pk=pk) try:
except model.DoesNotExist: owner = model.objects.get(pk=pk)
return None 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 @cached_property
def values_diff(self): def values_diff(self):

View File

@ -33,6 +33,7 @@ from functools import wraps
from functools import lru_cache from functools import lru_cache
from django.conf import settings from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core.paginator import Paginator, InvalidPage from django.core.paginator import Paginator, InvalidPage
from django.apps import apps from django.apps import apps
@ -331,7 +332,7 @@ def take_snapshot(obj:object, *, comment:str="", user=None, delete:bool=False):
"is_hidden": is_hidden, "is_hidden": is_hidden,
"is_snapshot": need_real_snapshot, "is_snapshot": need_real_snapshot,
} }
return entry_model.objects.create(**kwargs) return entry_model.objects.create(**kwargs)
@ -352,6 +353,16 @@ def get_history_queryset_by_model_instance(obj:object, types=(HistoryType.change
return qs.order_by("created_at") 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 # Freeze implementatitions
from .freeze_impl import project_freezer from .freeze_impl import project_freezer
from .freeze_impl import milestone_freezer from .freeze_impl import milestone_freezer