dont restore objects that have missing dependencies

This commit is contained in:
Laura Klünder 2017-07-07 16:02:42 +02:00
parent 4aed7098dc
commit b2158bb781
3 changed files with 46 additions and 5 deletions

View file

@ -253,6 +253,40 @@ class ChangedObject(models.Model):
return False
return True
def can_restore(self, force_query=False):
if not self.deleted:
return False
for field in self.model_class._meta.get_fields():
if not field.many_to_one:
continue
if field.name not in self.updated_fields:
continue
related_model = field.related_model
if related_model._meta.app_label != 'mapdata':
continue
pk = self.updated_fields[field.name]
if force_query:
# query here to avoid a race condition
related_content_type = ContentType.objects.get_for_model(related_model)
qs = self.changeset.changed_objects_set.filter(content_type=related_content_type)
if is_created_pk(pk):
if not qs.filter(pk=int(pk[2:]), deleted=False).exists():
return False
else:
if qs.filter(existing_object_pk=pk, deleted=True).exists():
return False
else:
if is_created_pk(pk):
if pk not in self.changeset.created_objects.get(related_model, ()):
return False
else:
if pk in self.changeset.deleted_existing.get(related_model, ()):
return False
return True
def mark_deleted(self):
if not self.can_delete():
return False
@ -310,6 +344,10 @@ class ChangedObject(models.Model):
self._m2m_added_cache.setdefault(name, set()).difference_update(pks)
self.m2m_set(name)
def restore(self):
self.deleted = False
self.save(standalone=True)
@property
def does_something(self):
return (self.updated_fields or self._m2m_added_cache or self._m2m_removed_cache or self.is_created or

View file

@ -90,7 +90,7 @@
<a class="btn btn-default btn-xs pull-right" data-force-next-zoom href="{{ obj.edit_url }}">
{% trans 'Edit' %}
</a>
{% elif obj.deleted and can_edit %}
{% elif obj.deleted and can_edit and obj.can_restore %}
<button type="submit" name="restore" value="{{ obj.pk }}" class="btn btn-warning btn-xs pull-right">
{% trans 'Restore' %}
</button>

View file

@ -43,10 +43,12 @@ def changeset_detail(request, pk):
except:
pass
else:
if changed_object.deleted:
changed_object.deleted = False
changed_object.save(standalone=True)
messages.success(request, _('Object has been successfully restored.'))
if changed_object.can_restore(force_query=True):
changed_object.restore()
messages.success(request, _('Object has been successfully restored.'))
else:
messages.error(request, _('You cannot restore this object, because '
'it depends on a deleted object.'))
else:
messages.error(request, _('You can not edit changes on this change set.'))
@ -235,6 +237,7 @@ def changeset_detail(request, pk):
'changes': changes,
'edit_url': edit_url,
'deleted': changed_object.deleted,
'can_restore': changed_object.can_restore(),
'order': (changed_object.deleted and changed_object.is_created, not changed_object.is_created),
}
changed_objects_data.append(changed_object_data)