if something is changed back to original state, add a „restore“ change

This commit is contained in:
Laura Klünder 2017-06-22 23:49:45 +02:00
parent f1854c8b66
commit c24130f058
2 changed files with 53 additions and 17 deletions

View file

@ -13,7 +13,7 @@ from django.utils.translation import ungettext_lazy
from c3nav.editor.models.change import Change
from c3nav.editor.utils import is_created_pk
from c3nav.editor.wrappers import ModelWrapper
from c3nav.editor.wrappers import ModelInstanceWrapper, ModelWrapper
from c3nav.mapdata.models import LocationSlug
from c3nav.mapdata.models.locations import LocationRedirect
from c3nav.mapdata.utils.models import get_submodels
@ -184,11 +184,12 @@ class ChangeSet(models.Model):
name = change.field_name
if change.action == 'restore':
if change.action == 'restore' and change.field_value is None:
if is_created_pk(pk):
self.created_objects[model][pk].pop(name, None)
else:
self.updated_existing.setdefault(model, {}).setdefault(pk, {}).pop(name, None)
return
value = json.loads(change.field_value)
if change.action == 'update':
@ -197,7 +198,10 @@ class ChangeSet(models.Model):
else:
self.updated_existing.setdefault(model, {}).setdefault(pk, {})[name] = value
if change.action == 'm2m_add':
if change.action == 'restore':
self.m2m_removed.get(model, {}).get(pk, {}).get(name, set()).discard(value)
self.m2m_added.get(model, {}).get(pk, {}).get(name, set()).discard(value)
elif change.action == 'm2m_add':
m2m_removed = self.m2m_removed.get(model, {}).get(pk, {}).get(name, ())
if value in m2m_removed:
m2m_removed.remove(value)
@ -364,21 +368,33 @@ class ChangeSet(models.Model):
return self._new_change(author=author, action=action, obj=obj, field_name=name,
field_value=json.dumps(value, ensure_ascii=False, cls=DjangoJSONEncoder))
def add_restore(self, obj, name, value=None, author=None):
"""
Restore a models field value (= remove it from the changeset).
"""
return self._new_change(author=author, action='restore', obj=obj, field_name=name, field_value=value)
def add_update(self, obj, name, value, author=None):
"""
Update a models field value. Called when a ModelInstanceWrapper is saved.
"""
if isinstance(obj, ModelInstanceWrapper):
obj = obj._obj
model = type(obj)
field = model._meta.get_field('titles' if name.startswith('title_') else name)
with transaction.atomic():
change = self._add_value('update', obj, name, value, author)
change.other_changes().filter(field_name=name).update(discarded_by=change)
return change
current_obj = model.objects.only(field.name).get(pk=obj.pk)
try:
current_value = getattr(current_obj, field.attname)
except AttributeError:
current_value = field.to_prep_value(getattr(current_obj, field.name))
if name.startswith('title_'):
current_value = current_value.get(name[6:], '')
def add_restore(self, obj, name, author=None):
"""
Restore a models field value (= remove it from the changeset).
"""
with transaction.atomic():
change = self._new_change(author=author, action='restore', obj=obj, field_name=name)
if current_value != value:
change = self._add_value('update', obj, name, value, author)
else:
change = self.add_restore(obj, name, author)
change.other_changes().filter(field_name=name).update(discarded_by=change)
return change
@ -386,8 +402,13 @@ class ChangeSet(models.Model):
"""
Add an object to a m2m relation. Called by ManyRelatedManagerWrapper.
"""
if isinstance(obj, ModelInstanceWrapper):
obj = obj._obj
with transaction.atomic():
if is_created_pk(obj.pk) or is_created_pk(value) or not getattr(obj, name).filter(pk=value).exists():
change = self._add_value('m2m_add', obj, name, value, author)
else:
change = self.add_restore(obj, name, value, author)
change.other_changes().filter(field_name=name, field_value=change.field_value).update(discarded_by=change)
return change
@ -395,7 +416,12 @@ class ChangeSet(models.Model):
"""
Remove an object from a m2m reltation. Called by ManyRelatedManagerWrapper.
"""
if isinstance(obj, ModelInstanceWrapper):
obj = obj._obj
with transaction.atomic():
if is_created_pk(obj.pk) or is_created_pk(value) or not getattr(obj, name).filter(pk=value).exists():
change = self.add_restore(obj, name, value, author)
else:
change = self._add_value('m2m_remove', obj, name, value, author)
change.other_changes().filter(field_name=name, field_value=change.field_value).update(discarded_by=change)
return change

View file

@ -186,7 +186,7 @@ def group_changes(changeset, can_edit=False, show_history=False):
'title': field_title,
'value': field_value,
})
elif change.action == 'revert':
elif change.action == 'restore':
change_data.update({
'icon': 'share-alt',
'class': 'muted',
@ -196,12 +196,22 @@ def group_changes(changeset, can_edit=False, show_history=False):
'icon': 'map-marker',
'title': _('reverted geometry'),
})
else:
if change.field_name.startswith('title_'):
lang = change.field_name[6:]
field_title = _('Title (%(lang)s)') % {'lang': dict(settings.LANGUAGES).get(lang, lang)}
else:
field = obj.__class__._meta.get_field(change.field_name)
field_title = field.verbose_name
model = getattr(field, 'related_model', None)
if model is not None:
change_data.update({
'value': objects[model][json.loads(change.field_value)].title
})
change_data.update({
'title': _('reverted %(field_title)s') % {'field_title': field_title},
})
elif change.action in ('m2m_add', 'm2m_remove'):
change_data.update({
'icon': 'chevron-right' if change.action == 'm2m_add' else 'chevron-left',