mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-25 01:48:38 -06:00
Merge pull request #4181 from hSaria/2511-change-diff
Fixes #2511: Compare object change to the previous change
This commit is contained in:
commit
21473548a5
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
## Enhancements
|
## 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
|
* [#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
|
* [#4170](https://github.com/netbox-community/netbox/issues/4170) - Improve color contrast in rack elevation drawings
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ from django_tables2 import RequestConfig
|
|||||||
|
|
||||||
from utilities.forms import ConfirmationForm
|
from utilities.forms import ConfirmationForm
|
||||||
from utilities.paginator import EnhancedPaginator
|
from utilities.paginator import EnhancedPaginator
|
||||||
|
from utilities.utils import shallow_compare_dict
|
||||||
from utilities.views import BulkDeleteView, BulkEditView, ObjectDeleteView, ObjectEditView, ObjectListView
|
from utilities.views import BulkDeleteView, BulkEditView, ObjectDeleteView, ObjectEditView, ObjectListView
|
||||||
from . import filters, forms
|
from . import filters, forms
|
||||||
from .models import ConfigContext, ImageAttachment, ObjectChange, ReportResult, Tag, TaggedItem
|
from .models import ConfigContext, ImageAttachment, ObjectChange, ReportResult, Tag, TaggedItem
|
||||||
@ -207,8 +208,31 @@ class ObjectChangeView(PermissionRequiredMixin, View):
|
|||||||
orderable=False
|
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', {
|
return render(request, 'extras/objectchange.html', {
|
||||||
'objectchange': objectchange,
|
'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_table': related_changes_table,
|
||||||
'related_changes_count': related_changes.count()
|
'related_changes_count': related_changes.count()
|
||||||
})
|
})
|
||||||
|
@ -83,6 +83,35 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</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>
|
||||||
<div class="col-md-7">
|
<div class="col-md-7">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
|
@ -222,3 +222,19 @@ def querydict_to_dict(querydict):
|
|||||||
key: querydict.get(key) if len(value) == 1 and key != 'pk' else querydict.getlist(key)
|
key: querydict.get(key) if len(value) == 1 and key != 'pk' else querydict.getlist(key)
|
||||||
for key, value in querydict.lists()
|
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
|
||||||
|
Loading…
Reference in New Issue
Block a user