1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Introduce NestedGroupModelSerializer

This commit is contained in:
Jeremy Stretch
2021-02-25 17:15:07 -05:00
parent ed059d80d6
commit 12fbd34962
8 changed files with 53 additions and 49 deletions

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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