Merge pull request #4181 from hSaria/2511-change-diff

Fixes #2511: Compare object change to the previous change
This commit is contained in:
Jeremy Stretch 2020-02-19 12:41:24 -05:00 committed by GitHub
commit 21473548a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 70 additions and 0 deletions

View File

@ -2,6 +2,7 @@
## Enhancements
* [#2511](https://github.com/netbox-community/netbox/issues/2511) - Compare object change to the previous change
* [#3840](https://github.com/netbox-community/netbox/issues/3840) - Enhance search function when selecting VLANs for interface assignment
* [#4170](https://github.com/netbox-community/netbox/issues/4170) - Improve color contrast in rack elevation drawings

View File

@ -12,6 +12,7 @@ from django_tables2 import RequestConfig
from utilities.forms import ConfirmationForm
from utilities.paginator import EnhancedPaginator
from utilities.utils import shallow_compare_dict
from utilities.views import BulkDeleteView, BulkEditView, ObjectDeleteView, ObjectEditView, ObjectListView
from . import filters, forms
from .models import ConfigContext, ImageAttachment, ObjectChange, ReportResult, Tag, TaggedItem
@ -207,8 +208,31 @@ class ObjectChangeView(PermissionRequiredMixin, View):
orderable=False
)
objectchanges = ObjectChange.objects.filter(
changed_object_type=objectchange.changed_object_type,
changed_object_id=objectchange.changed_object_id,
)
next_change = objectchanges.filter(time__gt=objectchange.time).order_by('time').first()
prev_change = objectchanges.filter(time__lt=objectchange.time).order_by('-time').first()
if prev_change:
diff_added = shallow_compare_dict(
prev_change.object_data,
objectchange.object_data,
exclude=['last_updated'],
)
diff_removed = {x: prev_change.object_data.get(x) for x in diff_added}
else:
# No previous change; this is the initial change that added the object
diff_added = diff_removed = objectchange.object_data
return render(request, 'extras/objectchange.html', {
'objectchange': objectchange,
'diff_added': diff_added,
'diff_removed': diff_removed,
'next_change': next_change,
'prev_change': prev_change,
'related_changes_table': related_changes_table,
'related_changes_count': related_changes.count()
})

View File

@ -83,6 +83,35 @@
</tr>
</table>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<strong>Difference</strong>
<div class="btn-group btn-group-xs pull-right noprint">
<a {% if prev_change %}href="{% url 'extras:objectchange' pk=prev_change.pk %}"{% else %}disabled{% endif %} class="btn btn-default">
<span class="fa fa-chevron-left" aria-hidden="true"></span> Previous
</a>
<a {% if next_change %}href="{% url 'extras:objectchange' pk=next_change.pk %}"{% else %}disabled{% endif %} class="btn btn-default">
Next <span class="fa fa-chevron-right" aria-hidden="true"></span>
</a>
</div>
</div>
<div class="panel-body">
{% if diff_added == diff_removed %}
<span class="text-muted" style="margin-left: 10px;">
{% if objectchange.action == 'create' %}
Object created
{% elif objectchange.action == 'delete' %}
Object deleted
{% else %}
No changes
{% endif %}
</span>
{% else %}
<pre style="background-color: #ffdce0;">{{ diff_removed|render_json }}</pre>
<pre style="background-color: #cdffd8;">{{ diff_added|render_json }}</pre>
{% endif %}
</div>
</div>
</div>
<div class="col-md-7">
<div class="panel panel-default">

View File

@ -222,3 +222,19 @@ def querydict_to_dict(querydict):
key: querydict.get(key) if len(value) == 1 and key != 'pk' else querydict.getlist(key)
for key, value in querydict.lists()
}
def shallow_compare_dict(source_dict, destination_dict, exclude=None):
"""
Return a new dictionary of the different keys. The values of `destination_dict` are returned. Only the equality of
the first layer of keys/values is checked. `exclude` is a list or tuple of keys to be ignored.
"""
difference = {}
for key in destination_dict:
if source_dict.get(key) != destination_dict[key]:
if isinstance(exclude, (list, tuple)) and key in exclude:
continue
difference[key] = destination_dict[key]
return difference