change model: discarded_by instead of deletes_change and reset updates

This commit is contained in:
Laura Klünder 2017-06-20 11:43:05 +02:00
parent 86511ceb93
commit 2ee650d6a4
2 changed files with 47 additions and 40 deletions

View file

@ -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'),
),
]

View file

@ -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)