From f5132c65528cd7f1cb6125890a8294e805971be6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Kl=C3=BCnder?= Date: Thu, 29 Nov 2018 01:45:25 +0100 Subject: [PATCH] restore objects using editor API --- src/c3nav/editor/api.py | 32 ++++++++++++++++++++++++ src/c3nav/editor/models/changedobject.py | 3 ++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/c3nav/editor/api.py b/src/c3nav/editor/api.py index 35149986..4c9b37c7 100644 --- a/src/c3nav/editor/api.py +++ b/src/c3nav/editor/api.py @@ -344,6 +344,7 @@ class ChangeSetViewSet(ReadOnlyModelViewSet): /{id}/changes/ list all changes of a given changeset. /{id}/activate/ POST to activate given changeset. /{id}/edit/ POST to edit given changeset (provide title and description in POST data). + /{id}/restore_object/ POST to restore an object deleted by this changeset (provide change id as id in POST data). /{id}/delete/ POST to delete given changeset. /{id}/propose/ POST to propose given changeset. /{id}/unpropose/ POST to unpropose given changeset. @@ -472,6 +473,37 @@ class ChangeSetViewSet(ReadOnlyModelViewSet): changeset.save() return Response({'success': True}) + @action(detail=True, methods=['post']) + def restore_object(self, request, *args, **kwargs): + data = get_api_post_data(request) + if 'id' not in data: + raise ParseError('Missing id.') + + restore_id = data['id'] + if isinstance(restore_id, str) and restore_id.isdigit(): + restore_id = int(restore_id) + + if not isinstance(restore_id, int): + raise ParseError('id needs to be an integer.') + + changeset = self.get_object() + with changeset.lock_to_edit(request) as changeset: + if not changeset.can_edit(request): + raise PermissionDenied(_('You can not edit changes on this change set.')) + + try: + changed_object = changeset.changed_objects_set.get(pk=restore_id) + except Exception: + raise NotFound('could not find object.') + + try: + changed_object.restore() + except PermissionError: + raise PermissionDenied(_('You cannot restore this object, because it depends on ' + 'a deleted object or it would violate a unique contraint.')) + + return Response({'success': True}) + @action(detail=True, methods=['post']) def propose(self, request, *args, **kwargs): if not request.user.is_authenticated: diff --git a/src/c3nav/editor/models/changedobject.py b/src/c3nav/editor/models/changedobject.py index 3a8b8a0f..0d5314e9 100644 --- a/src/c3nav/editor/models/changedobject.py +++ b/src/c3nav/editor/models/changedobject.py @@ -438,8 +438,9 @@ class ChangedObject(models.Model): def serialize(self): return OrderedDict(( + ('pk', self.pk), ('type', self.model_class.__name__.lower()), - ('pk', self.obj_pk), + ('object_pk', self.obj_pk), ('is_created', self.is_created), ('deleted', self.deleted), ('updated_fields', self.updated_fields),