replace Change with ChangedObject (wrapper integration still missing)
This commit is contained in:
parent
0ef51ac147
commit
9d5811bc15
12 changed files with 457 additions and 855 deletions
|
@ -1,4 +1,3 @@
|
|||
import json
|
||||
from operator import itemgetter
|
||||
|
||||
from django.conf import settings
|
||||
|
@ -11,11 +10,10 @@ from django.utils.translation import ugettext_lazy as _
|
|||
from c3nav.editor.models import ChangeSet
|
||||
from c3nav.editor.utils import is_created_pk
|
||||
from c3nav.editor.views.base import sidebar_view
|
||||
from c3nav.mapdata.models.locations import LocationRedirect, LocationSlug
|
||||
|
||||
|
||||
@sidebar_view
|
||||
def changeset_detail(request, pk, show_history=False):
|
||||
def changeset_detail(request, pk):
|
||||
can_edit = True
|
||||
changeset = request.changeset
|
||||
if str(pk) != str(request.changeset.pk):
|
||||
|
@ -32,7 +30,7 @@ def changeset_detail(request, pk, show_history=False):
|
|||
change.restore(request.user if request.user.is_authenticated else None)
|
||||
messages.success(request, _('Original state has been restored!'))
|
||||
|
||||
if not show_history and request.POST.get('delete') == '1':
|
||||
elif request.POST.get('delete') == '1':
|
||||
if request.POST.get('delete_confirm') == '1':
|
||||
changeset.delete()
|
||||
return redirect(reverse('editor.index'))
|
||||
|
@ -42,48 +40,19 @@ def changeset_detail(request, pk, show_history=False):
|
|||
'obj_title': changeset.title,
|
||||
})
|
||||
|
||||
ctx = group_changes(changeset, can_edit=can_edit, show_history=show_history)
|
||||
|
||||
if show_history:
|
||||
return render(request, 'editor/changeset_history.html', ctx)
|
||||
|
||||
return render(request, 'editor/changeset.html', ctx)
|
||||
|
||||
|
||||
def group_changes(changeset, can_edit=False, show_history=False):
|
||||
changeset.parse_changes(get_history=show_history)
|
||||
changeset.fill_changes_cache(include_deleted_created=True)
|
||||
|
||||
objects = changeset.get_objects()
|
||||
if show_history:
|
||||
grouped_changes = []
|
||||
for obj in objects:
|
||||
if is_created_pk(obj.pk):
|
||||
obj.titles = {}
|
||||
|
||||
grouped_changes = [] if show_history else {}
|
||||
changes = []
|
||||
last_obj = None
|
||||
for change in changeset.changes_qs:
|
||||
pk = change.obj_pk
|
||||
obj = objects[change.model_class][pk]
|
||||
if change.model_class == LocationRedirect:
|
||||
if change.action not in ('create', 'delete'):
|
||||
continue
|
||||
change.action = 'm2m_add' if change.action == 'create' else 'm2m_remove'
|
||||
change.field_name = 'redirects'
|
||||
change.field_value = obj.slug
|
||||
pk = obj.target_id
|
||||
obj = objects[LocationSlug][pk]
|
||||
changed_objects_data = []
|
||||
|
||||
for model, changed_objects in changeset.changed_objects.items():
|
||||
for changed_object in changed_objects:
|
||||
pk = changed_object.obj_pk
|
||||
obj = objects[model][pk]
|
||||
|
||||
if obj != last_obj and not show_history and pk in grouped_changes:
|
||||
# noinspection PyTypeChecker
|
||||
changes = grouped_changes[pk]['changes']
|
||||
elif obj != last_obj:
|
||||
changes = []
|
||||
obj_desc = _('%(model)s #%(id)s') % {'model': obj.__class__._meta.verbose_name, 'id': pk}
|
||||
if is_created_pk(pk):
|
||||
if show_history:
|
||||
obj_desc = _('%s (created)') % obj_desc
|
||||
obj_still_exists = pk in changeset.created_objects[obj.__class__]
|
||||
else:
|
||||
obj_still_exists = pk not in changeset.deleted_existing.get(obj.__class__, ())
|
||||
|
@ -98,166 +67,112 @@ def group_changes(changeset, can_edit=False, show_history=False):
|
|||
edit_url = reverse('editor.' + obj.__class__._meta.default_related_name + '.edit',
|
||||
kwargs=reverse_kwargs)
|
||||
|
||||
change_group = {
|
||||
changes = []
|
||||
changed_object_data = {
|
||||
'model': obj.__class__,
|
||||
'model_title': obj.__class__._meta.verbose_name,
|
||||
'obj': obj_desc,
|
||||
'obj_title': obj.title if obj.titles else None,
|
||||
'changes': changes,
|
||||
'edit_url': edit_url,
|
||||
'order': changed_object.created,
|
||||
}
|
||||
if show_history:
|
||||
grouped_changes.append(change_group)
|
||||
else:
|
||||
change_group['order'] = (0, int(pk[1:])) if is_created_pk(pk) else (1, int(pk))
|
||||
grouped_changes[pk] = change_group
|
||||
changed_objects_data.append(changed_object_data)
|
||||
|
||||
last_obj = obj
|
||||
form_fields = changeset.wrap(type(obj)).EditorForm._meta.fields
|
||||
|
||||
form = changeset.wrap(type(obj)).EditorForm
|
||||
|
||||
change_data = {
|
||||
'pk': change.pk,
|
||||
'author': change.author,
|
||||
'discarded': change.discarded_by_id is not None,
|
||||
'apply_problem': change.check_apply_problem(),
|
||||
'has_no_effect': change.check_has_no_effect(),
|
||||
}
|
||||
if show_history:
|
||||
change_data.update({
|
||||
'created': _('created at %(datetime)s') % {'datetime': date_format(change.created, 'DATETIME_FORMAT')},
|
||||
})
|
||||
if not show_history or change.action == 'delete' and can_edit:
|
||||
change_data.update({
|
||||
'can_restore': change.can_restore,
|
||||
})
|
||||
changes.append(change_data)
|
||||
|
||||
if change.action == 'create':
|
||||
change_data.update({
|
||||
'icon': 'plus',
|
||||
'class': 'success',
|
||||
'title': _('created'),
|
||||
'order': (0, ),
|
||||
})
|
||||
elif change.action == 'delete':
|
||||
change_data.update({
|
||||
'icon': 'minus',
|
||||
'class': 'danger',
|
||||
'title': _('deleted'),
|
||||
'order': (9, ),
|
||||
})
|
||||
elif change.action == 'update':
|
||||
change_data.update({
|
||||
'icon': 'option-vertical',
|
||||
'class': 'muted',
|
||||
})
|
||||
if change.field_name == 'geometry':
|
||||
change_data.update({
|
||||
'icon': 'map-marker',
|
||||
'class': 'info',
|
||||
'title': _('edited geometry'),
|
||||
'order': (8, ),
|
||||
if changed_object.is_created:
|
||||
changes.append({
|
||||
'icon': 'plus',
|
||||
'class': 'success',
|
||||
'title': _('created'),
|
||||
})
|
||||
else:
|
||||
if change.field_name.startswith('title_'):
|
||||
lang = change.field_name[6:]
|
||||
field_title = _('Title (%(lang)s)') % {'lang': dict(settings.LANGUAGES).get(lang, lang)}
|
||||
field_value = str(json.loads(change.field_value))
|
||||
if field_value:
|
||||
obj.titles[lang] = field_value
|
||||
else:
|
||||
obj.titles.pop(lang, None)
|
||||
|
||||
update_changes = []
|
||||
|
||||
for name, value in changed_object.updated_fields:
|
||||
change_data = {
|
||||
'icon': 'option-vertical',
|
||||
'class': 'muted',
|
||||
}
|
||||
if name == 'geometry':
|
||||
change_data.update({
|
||||
'order': (4, tuple(code for code, title in settings.LANGUAGES).index(lang)),
|
||||
'icon': 'map-marker',
|
||||
'class': 'info',
|
||||
'title': _('edited geometry'),
|
||||
'order': (8,),
|
||||
})
|
||||
else:
|
||||
field = change.field
|
||||
field_title = field.verbose_name
|
||||
field_value = field.to_python(json.loads(change.field_value))
|
||||
if field.related_model is not None:
|
||||
field_value = objects[field.related_model][field_value].title
|
||||
order = 5
|
||||
if change.field_name == 'slug':
|
||||
order = 1
|
||||
if change.field_name not in form._meta.fields:
|
||||
order = 0
|
||||
change_data.update({
|
||||
'order': (order, form._meta.fields.index(change.field_name) if order else 1),
|
||||
})
|
||||
if not field_value:
|
||||
change_data.update({
|
||||
'title': _('remove %(field_title)s') % {'field_title': field_title},
|
||||
})
|
||||
else:
|
||||
change_data.update({
|
||||
'title': field_title,
|
||||
'value': field_value,
|
||||
})
|
||||
elif change.action == 'restore':
|
||||
change_data.update({
|
||||
'icon': 'share-alt',
|
||||
'class': 'muted',
|
||||
})
|
||||
if change.field_name == 'geometry':
|
||||
change_data.update({
|
||||
'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 = change.field
|
||||
field_title = field.verbose_name
|
||||
model = getattr(field, 'related_model', None)
|
||||
if model is not None:
|
||||
if name.startswith('title_'):
|
||||
lang = name[6:]
|
||||
field_title = _('Title (%(lang)s)') % {'lang': dict(settings.LANGUAGES).get(lang, lang)}
|
||||
field_value = str(value)
|
||||
if field_value:
|
||||
obj.titles[lang] = field_value
|
||||
else:
|
||||
obj.titles.pop(lang, None)
|
||||
change_data.update({
|
||||
'value': objects[model][json.loads(change.field_value)].title
|
||||
'order': (4, tuple(code for code, title in settings.LANGUAGES).index(lang)),
|
||||
})
|
||||
change_data.update({
|
||||
'title': _('reverted %(field_title)s') % {'field_title': field_title},
|
||||
else:
|
||||
field = model._meta.get_field(name)
|
||||
field_title = field.verbose_name
|
||||
field_value = field.to_python(value)
|
||||
if field.related_model is not None:
|
||||
field_value = objects[field.related_model][field_value].title
|
||||
order = 5
|
||||
if name == 'slug':
|
||||
order = 1
|
||||
if name not in form_fields:
|
||||
order = 0
|
||||
change_data.update({
|
||||
'order': (order, form_fields.index(name) if order else 1),
|
||||
})
|
||||
if not field_value:
|
||||
change_data.update({
|
||||
'title': _('remove %(field_title)s') % {'field_title': field_title},
|
||||
})
|
||||
else:
|
||||
change_data.update({
|
||||
'title': field_title,
|
||||
'value': field_value,
|
||||
})
|
||||
update_changes.append(change_data)
|
||||
|
||||
changes.extend(sorted(update_changes, key=itemgetter('order')))
|
||||
|
||||
for m2m_mode in ('m2m_added', 'm2m_removed'):
|
||||
m2m_list = getattr(changed_object, m2m_mode).items()
|
||||
for name, values in sorted(m2m_list, key=lambda name, value: form_fields.index(name)):
|
||||
field = model._meta.get_field(name)
|
||||
for value in values:
|
||||
change_data.update({
|
||||
'icon': 'chevron-right' if m2m_mode == 'm2m_added' else 'chevron-left',
|
||||
'class': 'info',
|
||||
'title': field.verbose_name,
|
||||
'value': objects[field.related_model][value].title,
|
||||
})
|
||||
|
||||
if changed_object.deleted:
|
||||
changes.append({
|
||||
'icon': 'minus',
|
||||
'class': 'danger',
|
||||
'title': _('deleted'),
|
||||
'order': (9,),
|
||||
})
|
||||
|
||||
elif change.action in ('m2m_add', 'm2m_remove'):
|
||||
change_data.update({
|
||||
'icon': 'chevron-right' if change.action == 'm2m_add' else 'chevron-left',
|
||||
'class': 'info',
|
||||
})
|
||||
if change.field_name == 'redirects':
|
||||
change_data.update({
|
||||
'title': _('Redirecting slugs'),
|
||||
'value': change.field_value,
|
||||
'order': (6, -1, (change.action == 'm2m_remove')),
|
||||
})
|
||||
else:
|
||||
field = obj.__class__._meta.get_field(change.field_name)
|
||||
change_data.update({
|
||||
'title': field.verbose_name,
|
||||
'value': objects[field.related_model][json.loads(change.field_value)].title,
|
||||
'order': (6, form._meta.fields.index(change.field_name),
|
||||
(change.action == 'm2m_remove')),
|
||||
})
|
||||
else:
|
||||
change_data.update({
|
||||
'title': '???',
|
||||
'order': (10, )
|
||||
})
|
||||
changed_objects_data = sorted(changed_objects_data, key=itemgetter('order'))
|
||||
|
||||
if changeset.author:
|
||||
desc = _('created at %(datetime)s by') % {'datetime': date_format(changeset.created, 'DATETIME_FORMAT')}
|
||||
else:
|
||||
desc = _('created at %(datetime)s') % {'datetime': date_format(changeset.created, 'DATETIME_FORMAT')}
|
||||
|
||||
if not show_history:
|
||||
grouped_changes = sorted(grouped_changes.values(), key=itemgetter('order'))
|
||||
for group in grouped_changes:
|
||||
group['changes'] = sorted(group['changes'], key=itemgetter('order'))
|
||||
|
||||
ctx = {
|
||||
'pk': changeset.pk,
|
||||
'changeset': changeset,
|
||||
'desc': desc,
|
||||
'grouped_changes': grouped_changes,
|
||||
'changed_objects': changed_objects_data,
|
||||
}
|
||||
return ctx
|
||||
|
||||
return render(request, 'editor/changeset.html', ctx)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue