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.apps import apps
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.exceptions import ObjectDoesNotExist, ValidationError
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.db.models.fields.related_descriptors import ForwardManyToOneDescriptor, ManyToManyDescriptor
|
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.existing_object_pk is None:
|
||||||
if change.action == 'update':
|
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
|
return
|
||||||
|
|
||||||
if change.action == 'update':
|
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):
|
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)
|
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):
|
class Change(models.Model):
|
||||||
ACTIONS = (
|
ACTIONS = (
|
||||||
('delchange', _('delete change')),
|
|
||||||
('create', _('create object')),
|
('create', _('create object')),
|
||||||
('delete', _('delete object')),
|
('delete', _('delete object')),
|
||||||
('update', _('update attribute')),
|
('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'))
|
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'))
|
created = models.DateTimeField(auto_now_add=True, verbose_name=_('created'))
|
||||||
action = models.CharField(max_length=16, choices=ACTIONS, verbose_name=_('action'))
|
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',
|
discarded_by = models.OneToOneField('Change', null=True, on_delete=models.CASCADE, related_name='discards',
|
||||||
verbose_name=_('deletes change'))
|
verbose_name=_('discarded by other change'))
|
||||||
model_name = models.CharField(max_length=50, null=True, verbose_name=_('model name'))
|
model_name = models.CharField(max_length=50, verbose_name=_('model name'))
|
||||||
existing_object_pk = models.PositiveIntegerField(null=True, verbose_name=_('id of existing object'))
|
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',
|
created_object = models.ForeignKey('Change', null=True, on_delete=models.CASCADE, related_name='changed_by',
|
||||||
verbose_name=_('changed object'))
|
verbose_name=_('changed object'))
|
||||||
|
@ -409,41 +413,9 @@ class Change(models.Model):
|
||||||
self.created_object = None
|
self.created_object = None
|
||||||
self._set_object = value
|
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):
|
def save(self, *args, **kwargs):
|
||||||
self.clean()
|
|
||||||
if self.pk is not None:
|
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:
|
if self.changeset.proposed is not None or self.changeset.applied is not None:
|
||||||
raise TypeError('can not add change object to uneditable changeset.')
|
raise TypeError('can not add change object to uneditable changeset.')
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue