Просмотр исходного кода

Merge pull request #4269 from hSaria/4227-omit-private-changelog

Fixes #4227: Omit internal fields from the change log data
Jeremy Stretch 6 лет назад
Родитель
Сommit
161f03217e
3 измененных файлов с 28 добавлено и 6 удалено
  1. 3 2
      docs/release-notes/version-2.7.md
  2. 11 2
      netbox/dcim/models/__init__.py
  3. 14 2
      netbox/utilities/utils.py

+ 3 - 2
docs/release-notes/version-2.7.md

@@ -4,13 +4,14 @@
 
 * [#3145](https://github.com/netbox-community/netbox/issues/3145) - Add a "decommissioning" cable status
 * [#4173](https://github.com/netbox-community/netbox/issues/4173) - Return graceful error message when webhook queuing fails
+* [#4227](https://github.com/netbox-community/netbox/issues/4227) - Omit internal fields from the change log data
 * [#4237](https://github.com/netbox-community/netbox/issues/4237) - Support Jinja2 templating for webhook payload and headers
 
 ## Bug Fixes
 
 * [#4221](https://github.com/netbox-community/netbox/issues/4221) - Fix exception when deleting a device with interface connections when an interfaces webhook is defined
 * [#4222](https://github.com/netbox-community/netbox/issues/4222) - Escape double quotes on encapsulated values during CSV export
-* [#4224](https://github.com/netbox-community/netbox/issues/4224) - Fix display of rear device image if front image is not defined 
+* [#4224](https://github.com/netbox-community/netbox/issues/4224) - Fix display of rear device image if front image is not defined
 * [#4228](https://github.com/netbox-community/netbox/issues/4228) - Improve fit of device images in rack elevations
 * [#4230](https://github.com/netbox-community/netbox/issues/4230) - Fix rack units filtering on elevation endpoint
 * [#4232](https://github.com/netbox-community/netbox/issues/4232) - Enforce consistent background striping in rack elevations
@@ -30,7 +31,7 @@ NetBox, run the following management command to recalculate their naturalized va
 
 ```
 python3 manage.py renaturalize dcim.Interface
-``` 
+```
 
 ## Enhancements
 

+ 11 - 2
netbox/dcim/models/__init__.py

@@ -20,10 +20,10 @@ from dcim.choices import *
 from dcim.constants import *
 from dcim.fields import ASNField
 from dcim.elevations import RackElevationSVG
-from extras.models import ConfigContextModel, CustomFieldModel, TaggedItem
+from extras.models import ConfigContextModel, CustomFieldModel, ObjectChange, TaggedItem
 from utilities.fields import ColorField, NaturalOrderingField
 from utilities.models import ChangeLoggedModel
-from utilities.utils import to_meters
+from utilities.utils import serialize_object, to_meters
 from .device_component_templates import (
     ConsolePortTemplate, ConsoleServerPortTemplate, DeviceBayTemplate, FrontPortTemplate, InterfaceTemplate,
     PowerOutletTemplate, PowerPortTemplate, RearPortTemplate,
@@ -118,6 +118,15 @@ class Region(MPTTModel, ChangeLoggedModel):
             Q(region__in=self.get_descendants())
         ).count()
 
+    def to_objectchange(self, action):
+        # Remove MPTT-internal fields
+        return ObjectChange(
+            changed_object=self,
+            object_repr=str(self),
+            action=action,
+            object_data=serialize_object(self, exclude=['level', 'lft', 'rght', 'tree_id'])
+        )
+
 
 #
 # Sites

+ 14 - 2
netbox/utilities/utils.py

@@ -81,10 +81,12 @@ def get_subquery(model, field):
     return subquery
 
 
-def serialize_object(obj, extra=None):
+def serialize_object(obj, extra=None, exclude=None):
     """
     Return a generic JSON representation of an object using Django's built-in serializer. (This is used for things like
-    change logging, not the REST API.) Optionally include a dictionary to supplement the object data.
+    change logging, not the REST API.) Optionally include a dictionary to supplement the object data. A list of keys
+    can be provided to exclude them from the returned dictionary. Private fields (prefaced with an underscore) are
+    implicitly excluded.
     """
     json_str = serialize('json', [obj])
     data = json.loads(json_str)[0]['fields']
@@ -103,6 +105,16 @@ def serialize_object(obj, extra=None):
     if extra is not None:
         data.update(extra)
 
+    # Copy keys to list to avoid 'dictionary changed size during iteration' exception
+    for key in list(data):
+        # Private fields shouldn't be logged in the object change
+        if isinstance(key, str) and key.startswith('_'):
+            data.pop(key)
+
+        # Explicitly excluded keys
+        if isinstance(exclude, (list, tuple)) and key in exclude:
+            data.pop(key)
+
     return data