From e9332cfb75ba2f69e76433cc7e8a9386df455b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Kl=C3=BCnder?= Date: Fri, 7 Jul 2017 15:32:41 +0200 Subject: [PATCH] fix cache invalidation --- src/c3nav/editor/models/changeset.py | 19 +++++++++++++------ src/c3nav/editor/views/changes.py | 27 +++++++++++++-------------- src/c3nav/editor/views/edit.py | 24 ++++++++++++------------ 3 files changed, 38 insertions(+), 32 deletions(-) diff --git a/src/c3nav/editor/models/changeset.py b/src/c3nav/editor/models/changeset.py index 3dc0f02b..74f07895 100644 --- a/src/c3nav/editor/models/changeset.py +++ b/src/c3nav/editor/models/changeset.py @@ -16,7 +16,6 @@ from django.utils.http import int_to_base36 from django.utils.timezone import make_naive from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ungettext_lazy -from rest_framework.exceptions import PermissionDenied from c3nav.editor.models.changedobject import ChangedObject from c3nav.editor.utils import is_created_pk @@ -381,19 +380,27 @@ class ChangeSet(models.Model): def can_see(self, request): return self.is_author(request) + object_changed_cache = {} + + @property + def _object_changed(self): + return self.object_changed_cache.get(self.pk, None) + + @_object_changed.setter + def _object_changed(self, value): + self.object_changed_cache[self.pk] = value + @contextmanager def lock_to_edit(self, request=None): with transaction.atomic(): if self.pk is not None: changeset = ChangeSet.objects.select_for_update().get(pk=self.pk) - if request is not None and not changeset.can_edit(request): - raise PermissionDenied self._object_changed = False yield changeset - if self._object_changed and request is not None: - update = changeset.updates.create(user=request.user if request.user.is_authenticated else None, - objects_changed=True) + user = request.user if request is not None and request.user.is_authenticated else None + if self._object_changed: + update = changeset.updates.create(user=user, objects_changed=True) changeset.last_update = update changeset.last_change = update changeset.save() diff --git a/src/c3nav/editor/views/changes.py b/src/c3nav/editor/views/changes.py index a3ca1fee..91bf4015 100644 --- a/src/c3nav/editor/views/changes.py +++ b/src/c3nav/editor/views/changes.py @@ -4,7 +4,6 @@ from operator import itemgetter from django.conf import settings from django.contrib import messages from django.core.cache import cache -from django.core.exceptions import PermissionDenied from django.http import Http404 from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse @@ -37,8 +36,8 @@ def changeset_detail(request, pk): if request.method == 'POST': restore = request.POST.get('restore') if restore and restore.isdigit(): - try: - with changeset.lock_to_edit(request): + with changeset.lock_to_edit(request) as changeset: + if changeset.can_edit(request): try: changed_object = changeset.changed_objects_set.get(pk=restore) except: @@ -48,13 +47,13 @@ def changeset_detail(request, pk): changed_object.deleted = False changed_object.save(standalone=True) messages.success(request, _('Object has been successfully restored.')) - except PermissionDenied: - messages.error(request, _('You can not edit changes on this change set.')) + else: + messages.error(request, _('You can not edit changes on this change set.')) return redirect(reverse('editor.changesets.detail', kwargs={'pk': changeset.pk})) elif request.POST.get('activate') == '1': - with changeset.lock_to_edit() as changeset: + with changeset.lock_to_edit(request) as changeset: if not changeset.closed: changeset.activate(request) messages.success(request, _('You activated this change set.')) @@ -68,7 +67,7 @@ def changeset_detail(request, pk): messages.info(request, _('You need to log in to propose changes.')) return redirect(reverse('editor.login')+'?r='+request.path) - with changeset.lock_to_edit() as changeset: + with changeset.lock_to_edit(request) as changeset: if not changeset.title or not changeset.description: messages.warning(request, _('You need to add a title an a description to propose this change set.')) return redirect(reverse('editor.changesets.edit', kwargs={'pk': changeset.pk})) @@ -82,7 +81,7 @@ def changeset_detail(request, pk): return redirect(reverse('editor.changesets.detail', kwargs={'pk': changeset.pk})) elif request.POST.get('unpropose') == '1': - with changeset.lock_to_edit() as changeset: + with changeset.lock_to_edit(request) as changeset: if changeset.can_unpropose(request): changeset.unpropose(request.user) messages.success(request, _('You unproposed your changes.')) @@ -92,7 +91,7 @@ def changeset_detail(request, pk): return redirect(reverse('editor.changesets.detail', kwargs={'pk': changeset.pk})) elif request.POST.get('review') == '1': - with changeset.lock_to_edit() as changeset: + with changeset.lock_to_edit(request) as changeset: if changeset.can_start_review(request): changeset.start_review(request.user) messages.success(request, _('You are not reviewing these changes.')) @@ -102,7 +101,7 @@ def changeset_detail(request, pk): return redirect(reverse('editor.changesets.detail', kwargs={'pk': changeset.pk})) elif request.POST.get('reject') == '1': - with changeset.lock_to_edit() as changeset: + with changeset.lock_to_edit(request) as changeset: if not changeset.can_end_review(request): messages.error(request, _('You cannot reject these changes.')) return redirect(reverse('editor.changesets.detail', kwargs={'pk': changeset.pk})) @@ -122,7 +121,7 @@ def changeset_detail(request, pk): }) elif request.POST.get('unreject') == '1': - with changeset.lock_to_edit() as changeset: + with changeset.lock_to_edit(request) as changeset: if not changeset.can_unreject(request): messages.error(request, _('You cannot unreject these changes.')) return redirect(reverse('editor.changesets.detail', kwargs={'pk': changeset.pk})) @@ -133,7 +132,7 @@ def changeset_detail(request, pk): return redirect(reverse('editor.changesets.detail', kwargs={'pk': changeset.pk})) elif request.POST.get('apply') == '1': - with changeset.lock_to_edit() as changeset: + with changeset.lock_to_edit(request) as changeset: if not changeset.can_end_review(request): messages.error(request, _('You cannot accept and apply these changes.')) return redirect(reverse('editor.changesets.detail', kwargs={'pk': changeset.pk})) @@ -146,7 +145,7 @@ def changeset_detail(request, pk): return render(request, 'editor/changeset_apply.html', {}) elif request.POST.get('delete') == '1': - with changeset.lock_to_edit() as changeset: + with changeset.lock_to_edit(request) as changeset: if not changeset.can_delete(request): messages.error(request, _('You cannot delete this change set.')) @@ -352,7 +351,7 @@ def changeset_edit(request, pk): if str(pk) != str(request.changeset.pk): changeset = get_object_or_404(ChangeSet.qs_for_request(request), pk=pk) - with changeset.lock_to_edit() as changeset: + with changeset.lock_to_edit(request) as changeset: if not changeset.can_edit(request): messages.error(request, _('You cannot edit this change set.')) return redirect(reverse('editor.changesets.detail', kwargs={'pk': changeset.pk})) diff --git a/src/c3nav/editor/views/edit.py b/src/c3nav/editor/views/edit.py index 0ddc700e..309f0741 100644 --- a/src/c3nav/editor/views/edit.py +++ b/src/c3nav/editor/views/edit.py @@ -181,12 +181,12 @@ def edit(request, pk=None, model=None, level=None, space=None, on_top_of=None, e return redirect(request.path) if request.POST.get('delete_confirm') == '1': - try: - with request.changeset.lock_to_edit(request): + with request.changeset.lock_to_edit(request) as changeset: + if changeset.can_edit(request): obj.delete() - except PermissionDenied: - messages.error(request, _('You can not edit changes on this changeset.')) - return redirect(request.path) + else: + messages.error(request, _('You can not edit changes on this changeset.')) + return redirect(request.path) messages.success(request, _('Object was successfully deleted.')) if model == Level: if obj.on_top_of_id is not None: @@ -218,8 +218,8 @@ def edit(request, pk=None, model=None, level=None, space=None, on_top_of=None, e if on_top_of is not None: obj.on_top_of = on_top_of - try: - with request.changeset.lock_to_edit(request): + with request.changeset.lock_to_edit(request) as changeset: + if changeset.can_edit(request): obj.save() if form.redirect_slugs is not None: @@ -230,11 +230,11 @@ def edit(request, pk=None, model=None, level=None, space=None, on_top_of=None, e obj.redirects.filter(slug=slug).delete() form.save_m2m() - except PermissionDenied: - messages.error(request, _('You can not edit changes on this changeset.')) - else: - messages.success(request, _('Object was successfully saved.')) - return redirect(ctx['back_url']) + messages.success(request, _('Object was successfully saved.')) + return redirect(ctx['back_url']) + else: + messages.error(request, _('You can not edit changes on this changeset.')) + else: form = model.EditorForm(instance=obj, request=request)