change model: discarded_by instead of deletes_change and reset updates
This commit is contained in:
parent
86511ceb93
commit
2ee650d6a4
2 changed files with 47 additions and 40 deletions
35
src/c3nav/editor/migrations/0004_auto_20170620_0934.py
Normal file
35
src/c3nav/editor/migrations/0004_auto_20170620_0934.py
Normal 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'),
|
||||
),
|
||||
]
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue