From 2ee650d6a4ea300b264e3b4ff20c7d1508b7b5fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Kl=C3=BCnder?= Date: Tue, 20 Jun 2017 11:43:05 +0200 Subject: [PATCH] change model: discarded_by instead of deletes_change and reset updates --- .../migrations/0004_auto_20170620_0934.py | 35 +++++++++++++ src/c3nav/editor/models.py | 52 +++++-------------- 2 files changed, 47 insertions(+), 40 deletions(-) create mode 100644 src/c3nav/editor/migrations/0004_auto_20170620_0934.py diff --git a/src/c3nav/editor/migrations/0004_auto_20170620_0934.py b/src/c3nav/editor/migrations/0004_auto_20170620_0934.py new file mode 100644 index 00000000..28c9fa25 --- /dev/null +++ b/src/c3nav/editor/migrations/0004_auto_20170620_0934.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.2 on 2017-06-20 09:34 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('editor', '0003_auto_20170618_1942'), + ] + + operations = [ + migrations.RemoveField( + model_name='change', + name='deletes_change', + ), + migrations.AddField( + model_name='change', + name='discarded_by', + field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='discards', to='editor.Change', verbose_name='discarded by other change'), + ), + migrations.AlterField( + model_name='change', + name='action', + field=models.CharField(choices=[('create', 'create object'), ('delete', 'delete object'), ('update', 'update attribute'), ('m2m_add', 'add many to many relation'), ('m2m_remove', 'add many to many relation')], max_length=16, verbose_name='action'), + ), + migrations.AlterField( + model_name='change', + name='model_name', + field=models.CharField(max_length=50, verbose_name='model name'), + ), + ] diff --git a/src/c3nav/editor/models.py b/src/c3nav/editor/models.py index bacad13b..ff2d5b68 100644 --- a/src/c3nav/editor/models.py +++ b/src/c3nav/editor/models.py @@ -4,7 +4,6 @@ from collections import OrderedDict from django.apps import apps from django.conf import settings -from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.db import models from django.db.models import Q from django.db.models.fields.related_descriptors import ForwardManyToOneDescriptor, ManyToManyDescriptor @@ -87,11 +86,17 @@ class ChangeSet(models.Model): if change.existing_object_pk is None: if change.action == 'update': - self.created_objects[model][change.created_object_id][name] = value + if value is None: + self.created_objects[model][change.created_object_id].pop(name) + else: + self.created_objects[model][change.created_object_id][name] = value return if change.action == 'update': - self.updated_existing.setdefault(model, {}).setdefault(pk, {})[name] = value + if value is None: + self.updated_existing.setdefault(model, {}).setdefault(pk, {}).pop(name) + else: + self.updated_existing.setdefault(model, {}).setdefault(pk, {})[name] = value def get_changed_values(self, model, name): r = tuple((pk, values[name]) for pk, values in self.updated_existing.get(model, {}).items() if name in values) @@ -305,7 +310,6 @@ class ChangeSet(models.Model): class Change(models.Model): ACTIONS = ( - ('delchange', _('delete change')), ('create', _('create object')), ('delete', _('delete object')), ('update', _('update attribute')), @@ -316,9 +320,9 @@ class Change(models.Model): author = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.PROTECT, verbose_name=_('Author')) created = models.DateTimeField(auto_now_add=True, verbose_name=_('created')) action = models.CharField(max_length=16, choices=ACTIONS, verbose_name=_('action')) - deletes_change = models.OneToOneField('Change', null=True, on_delete=models.CASCADE, related_name='deleted_by', - verbose_name=_('deletes change')) - model_name = models.CharField(max_length=50, null=True, verbose_name=_('model name')) + discarded_by = models.OneToOneField('Change', null=True, on_delete=models.CASCADE, related_name='discards', + verbose_name=_('discarded by other change')) + model_name = models.CharField(max_length=50, verbose_name=_('model name')) existing_object_pk = models.PositiveIntegerField(null=True, verbose_name=_('id of existing object')) created_object = models.ForeignKey('Change', null=True, on_delete=models.CASCADE, related_name='changed_by', verbose_name=_('changed object')) @@ -409,41 +413,9 @@ class Change(models.Model): self.created_object = None self._set_object = value - def clean(self): - if self.action == 'delchange': - if self.deletes_change is None: - raise ValidationError('deletes_change has to be set if action is delchange.') - if self.deletes_change.changeset_id != self.changeset_id: - raise ValidationError('deletes_change refers to a change from a different changeset.') - - for field_name in ('model_name', 'existing_object_pk', 'created_object', 'field_name', 'field_value'): - if getattr(self, field_name) is not None: - raise ValidationError('%s must not be set if action is delchange.' % field_name) - return - - if self.deletes_change is not None: - raise ValidationError('deletes_change can only be set if action is delchange.') - - if self.model_name is None: - raise ValidationError('model_name has to be set if action is not delchange.') - - try: - # noinspection PyUnusedLocal - tmp = self.model_class if self.action == 'create' else self.obj # noqa - except TypeError as e: - raise ValidationError(str(e)) - except ObjectDoesNotExist: - raise ValidationError('existing object does not exist.') - - if self.action in ('create', 'delete'): - for field_name in ('field_name', 'field_value'): - if getattr(self, field_name) is not None: - raise ValidationError('%s must not be set if action is create or delete.' % field_name) - def save(self, *args, **kwargs): - self.clean() if self.pk is not None: - raise TypeError('change objects can not be edited.') + raise TypeError('change objects can not be edited (use update to set discarded_by)') if self.changeset.proposed is not None or self.changeset.applied is not None: raise TypeError('can not add change object to uneditable changeset.') super().save(*args, **kwargs)