Explorar o código

Introduce NestedGroupModelSerializer

Jeremy Stretch %!s(int64=5) %!d(string=hai) anos
pai
achega
12fbd34962

+ 1 - 1
netbox/circuits/api/serializers.py

@@ -4,7 +4,7 @@ from circuits.choices import CircuitStatusChoices
 from circuits.models import Provider, Circuit, CircuitTermination, CircuitType
 from dcim.api.nested_serializers import NestedCableSerializer, NestedSiteSerializer
 from dcim.api.serializers import CableTerminationSerializer, ConnectedEndpointSerializer
-from extras.api.customfields import CustomFieldModelSerializer
+from netbox.api.serializers import CustomFieldModelSerializer
 from extras.api.serializers import TaggedObjectSerializer
 from netbox.api import ChoiceField
 from netbox.api.serializers import OrganizationalModelSerializer, WritableNestedSerializer

+ 6 - 6
netbox/dcim/api/serializers.py

@@ -13,12 +13,14 @@ from dcim.models import (
     PowerPortTemplate, Rack, RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site,
     VirtualChassis,
 )
-from extras.api.customfields import CustomFieldModelSerializer
+from netbox.api.serializers import CustomFieldModelSerializer
 from extras.api.serializers import TaggedObjectSerializer
 from ipam.api.nested_serializers import NestedIPAddressSerializer, NestedVLANSerializer
 from ipam.models import VLAN
 from netbox.api import ChoiceField, ContentTypeField, SerializedPKRelatedField, TimeZoneField
-from netbox.api.serializers import OrganizationalModelSerializer, ValidatedModelSerializer, WritableNestedSerializer
+from netbox.api.serializers import (
+    NestedGroupModelSerializer, OrganizationalModelSerializer, ValidatedModelSerializer, WritableNestedSerializer,
+)
 from tenancy.api.nested_serializers import NestedTenantSerializer
 from users.api.nested_serializers import NestedUserSerializer
 from utilities.api import get_serializer_for_model
@@ -79,11 +81,10 @@ class ConnectedEndpointSerializer(ValidatedModelSerializer):
 # Regions/sites
 #
 
-class RegionSerializer(CustomFieldModelSerializer):
+class RegionSerializer(NestedGroupModelSerializer):
     url = serializers.HyperlinkedIdentityField(view_name='dcim-api:region-detail')
     parent = NestedRegionSerializer(required=False, allow_null=True)
     site_count = serializers.IntegerField(read_only=True)
-    _depth = serializers.IntegerField(source='level', read_only=True)
 
     class Meta:
         model = Region
@@ -120,12 +121,11 @@ class SiteSerializer(TaggedObjectSerializer, CustomFieldModelSerializer):
 # Racks
 #
 
-class RackGroupSerializer(CustomFieldModelSerializer):
+class RackGroupSerializer(NestedGroupModelSerializer):
     url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackgroup-detail')
     site = NestedSiteSerializer()
     parent = NestedRackGroupSerializer(required=False, allow_null=True)
     rack_count = serializers.IntegerField(read_only=True)
-    _depth = serializers.IntegerField(source='level', read_only=True)
 
     class Meta:
         model = RackGroup

+ 1 - 34
netbox/extras/api/customfields.py

@@ -1,9 +1,7 @@
 from django.contrib.contenttypes.models import ContentType
-from rest_framework.fields import CreateOnlyDefault, Field
+from rest_framework.fields import Field
 
-from extras.choices import *
 from extras.models import CustomField
-from netbox.api import ValidatedModelSerializer
 
 
 #
@@ -56,34 +54,3 @@ class CustomFieldsDataField(Field):
             data = {**self.parent.instance.custom_field_data, **data}
 
         return data
-
-
-class CustomFieldModelSerializer(ValidatedModelSerializer):
-    """
-    Extends ModelSerializer to render any CustomFields and their values associated with an object.
-    """
-    custom_fields = CustomFieldsDataField(
-        source='custom_field_data',
-        default=CreateOnlyDefault(CustomFieldDefaultValues())
-    )
-
-    def __init__(self, *args, **kwargs):
-        super().__init__(*args, **kwargs)
-
-        if self.instance is not None:
-
-            # Retrieve the set of CustomFields which apply to this type of object
-            content_type = ContentType.objects.get_for_model(self.Meta.model)
-            fields = CustomField.objects.filter(content_types=content_type)
-
-            # Populate CustomFieldValues for each instance from database
-            if type(self.instance) in (list, tuple):
-                for obj in self.instance:
-                    self._populate_custom_fields(obj, fields)
-            else:
-                self._populate_custom_fields(self.instance, fields)
-
-    def _populate_custom_fields(self, instance, custom_fields):
-        instance.custom_fields = {}
-        for field in custom_fields:
-            instance.custom_fields[field.name] = instance.cf.get(field.name)

+ 1 - 1
netbox/ipam/api/serializers.py

@@ -6,7 +6,7 @@ from rest_framework import serializers
 from rest_framework.validators import UniqueTogetherValidator
 
 from dcim.api.nested_serializers import NestedDeviceSerializer, NestedSiteSerializer
-from extras.api.customfields import CustomFieldModelSerializer
+from netbox.api.serializers import CustomFieldModelSerializer
 from extras.api.serializers import TaggedObjectSerializer
 from ipam.choices import *
 from ipam.constants import IPADDRESS_ASSIGNMENT_MODELS

+ 40 - 1
netbox/netbox/api/serializers.py

@@ -1,8 +1,12 @@
+from django.contrib.contenttypes.models import ContentType
 from django.core.exceptions import FieldError, MultipleObjectsReturned, ObjectDoesNotExist
 from django.db.models import ManyToManyField
 from rest_framework import serializers
 from rest_framework.exceptions import ValidationError
+from rest_framework.fields import CreateOnlyDefault
 
+from extras.api.customfields import CustomFieldsDataField, CustomFieldDefaultValues
+from extras.models import CustomField
 from utilities.utils import dict_to_filter_params
 
 
@@ -35,10 +39,45 @@ class ValidatedModelSerializer(serializers.ModelSerializer):
         return data
 
 
-class OrganizationalModelSerializer(ValidatedModelSerializer):
+class CustomFieldModelSerializer(ValidatedModelSerializer):
+    """
+    Extends ModelSerializer to render any CustomFields and their values associated with an object.
+    """
+    custom_fields = CustomFieldsDataField(
+        source='custom_field_data',
+        default=CreateOnlyDefault(CustomFieldDefaultValues())
+    )
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        if self.instance is not None:
+
+            # Retrieve the set of CustomFields which apply to this type of object
+            content_type = ContentType.objects.get_for_model(self.Meta.model)
+            fields = CustomField.objects.filter(content_types=content_type)
+
+            # Populate CustomFieldValues for each instance from database
+            if type(self.instance) in (list, tuple):
+                for obj in self.instance:
+                    self._populate_custom_fields(obj, fields)
+            else:
+                self._populate_custom_fields(self.instance, fields)
+
+    def _populate_custom_fields(self, instance, custom_fields):
+        instance.custom_fields = {}
+        for field in custom_fields:
+            instance.custom_fields[field.name] = instance.cf.get(field.name)
+
+
+class OrganizationalModelSerializer(CustomFieldModelSerializer):
     pass
 
 
+class NestedGroupModelSerializer(CustomFieldModelSerializer):
+    _depth = serializers.IntegerField(source='level', read_only=True)
+
+
 class WritableNestedSerializer(serializers.ModelSerializer):
     """
     Returns a nested representation of an object on read, but accepts only a primary key on write.

+ 1 - 1
netbox/secrets/api/serializers.py

@@ -2,7 +2,7 @@ from django.contrib.contenttypes.models import ContentType
 from drf_yasg.utils import swagger_serializer_method
 from rest_framework import serializers
 
-from extras.api.customfields import CustomFieldModelSerializer
+from netbox.api.serializers import CustomFieldModelSerializer
 from extras.api.serializers import TaggedObjectSerializer
 from secrets.constants import SECRET_ASSIGNMENT_MODELS
 from secrets.models import Secret, SecretRole

+ 2 - 4
netbox/tenancy/api/serializers.py

@@ -1,8 +1,7 @@
 from rest_framework import serializers
 
-from extras.api.customfields import CustomFieldModelSerializer
+from netbox.api.serializers import CustomFieldModelSerializer, NestedGroupModelSerializer
 from extras.api.serializers import TaggedObjectSerializer
-from netbox.api import ValidatedModelSerializer
 from tenancy.models import Tenant, TenantGroup
 from .nested_serializers import *
 
@@ -11,11 +10,10 @@ from .nested_serializers import *
 # Tenants
 #
 
-class TenantGroupSerializer(CustomFieldModelSerializer):
+class TenantGroupSerializer(NestedGroupModelSerializer):
     url = serializers.HyperlinkedIdentityField(view_name='tenancy-api:tenantgroup-detail')
     parent = NestedTenantGroupSerializer(required=False, allow_null=True)
     tenant_count = serializers.IntegerField(read_only=True)
-    _depth = serializers.IntegerField(source='level', read_only=True)
 
     class Meta:
         model = TenantGroup

+ 1 - 1
netbox/virtualization/api/serializers.py

@@ -3,7 +3,7 @@ from rest_framework import serializers
 
 from dcim.api.nested_serializers import NestedDeviceRoleSerializer, NestedPlatformSerializer, NestedSiteSerializer
 from dcim.choices import InterfaceModeChoices
-from extras.api.customfields import CustomFieldModelSerializer
+from netbox.api.serializers import CustomFieldModelSerializer
 from extras.api.serializers import TaggedObjectSerializer
 from ipam.api.nested_serializers import NestedIPAddressSerializer, NestedVLANSerializer
 from ipam.models import VLAN