add ChangeSet.last_change with cache

This commit is contained in:
Laura Klünder 2017-06-29 15:06:14 +02:00
parent 15704762ed
commit 3923c08ac7
2 changed files with 25 additions and 6 deletions

View file

@ -2,6 +2,7 @@ import typing
from itertools import chain from itertools import chain
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core.cache import cache
from django.db import models from django.db import models
from django.db.models import Field from django.db.models import Field
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -275,6 +276,7 @@ class ChangedObject(models.Model):
self.update_changeset_cache() self.update_changeset_cache()
if not self.stale or self.pk is not None: if not self.stale or self.pk is not None:
super().save(*args, **kwargs) super().save(*args, **kwargs)
cache.set('changeset:%s:last_change' % self.changeset_id, self.last_update, 900)
def delete(self, **kwargs): def delete(self, **kwargs):
raise TypeError('changed objects can not be deleted directly.') raise TypeError('changed objects can not be deleted directly.')

View file

@ -3,6 +3,7 @@ from itertools import chain
from django.apps import apps from django.apps import apps
from django.conf import settings from django.conf import settings
from django.core.cache import cache
from django.db import models from django.db import models
from django.db.models import Max, Q from django.db.models import Max, Q
from django.urls import reverse from django.urls import reverse
@ -41,7 +42,8 @@ class ChangeSet(models.Model):
self.deleted_existing = {} self.deleted_existing = {}
self.m2m_added = {} self.m2m_added = {}
self.m2m_removed = {} self.m2m_removed = {}
self._last_change_pk = 0
self.last_change_cache = None
""" """
Get Changesets for Request/Session/User Get Changesets for Request/Session/User
@ -146,6 +148,8 @@ class ChangeSet(models.Model):
for change in qs: for change in qs:
change.update_changeset_cache() change.update_changeset_cache()
self._last_change_cache = max(change.last_update for change in qs)
return True return True
""" """
@ -281,17 +285,30 @@ class ChangeSet(models.Model):
return _('Changeset #%d') % self.pk return _('Changeset #%d') % self.pk
@property @property
def last_update(self): def last_change(self):
if self.changed_objects is None: last_change = cache.get('changeset:%s:last_change' % self.pk)
return self.changed_objects_set.aggregate(Max('last_update'))['last_update__max'] if last_change is None:
# was not in cache, calculate it
try:
last_change = self.changed_objects_set.aggregate(Max('last_update'))['last_update__max']
except ChangedObject.DoesNotExist:
last_change = self.created
elif self.last_change_cache is None or self.last_change_cache <= last_change:
# was in cache and our local value (if we had one) is not newer
return last_change
else:
# our local value is newer
last_change = self.last_change_cache
return max(chain(*self.changed_objects.values()), key=attrgetter('last_update')) # update cache
cache.set('changeset:%s:last_change' % self.pk, last_change, 900)
return last_change
@property @property
def cache_key(self): def cache_key(self):
if self.pk is None: if self.pk is None:
return None return None
return str(self.pk)+'-'+str(self.last_update) return str(self.pk)+'-'+str(self.last_change)
def get_absolute_url(self): def get_absolute_url(self):
if self.pk is None: if self.pk is None: