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

Add dynamic nesting support to SerializedPKRelatedField

This commit is contained in:
Jeremy Stretch
2024-02-27 14:00:42 -05:00
parent c382ba0ae0
commit ca56c8b9ef
19 changed files with 137 additions and 111 deletions

View File

@ -1,7 +1,7 @@
from rest_framework import serializers from rest_framework import serializers
from circuits.models import Provider, ProviderAccount, ProviderNetwork from circuits.models import Provider, ProviderAccount, ProviderNetwork
from ipam.api.nested_serializers import NestedASNSerializer from ipam.api.serializers_.asns import ASNSerializer
from ipam.models import ASN from ipam.models import ASN
from netbox.api.fields import RelatedObjectCountField, SerializedPKRelatedField from netbox.api.fields import RelatedObjectCountField, SerializedPKRelatedField
from netbox.api.serializers import NetBoxModelSerializer from netbox.api.serializers import NetBoxModelSerializer
@ -24,7 +24,8 @@ class ProviderSerializer(NetBoxModelSerializer):
) )
asns = SerializedPKRelatedField( asns = SerializedPKRelatedField(
queryset=ASN.objects.all(), queryset=ASN.objects.all(),
serializer=NestedASNSerializer, serializer=ASNSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )

View File

@ -10,21 +10,21 @@ from dcim.models import (
) )
from ipam.api.serializers_.vlans import VLANSerializer from ipam.api.serializers_.vlans import VLANSerializer
from ipam.api.serializers_.vrfs import VRFSerializer from ipam.api.serializers_.vrfs import VRFSerializer
from ipam.api.nested_serializers import NestedVLANSerializer
from ipam.models import VLAN from ipam.models import VLAN
from netbox.api.fields import ChoiceField, ContentTypeField, SerializedPKRelatedField from netbox.api.fields import ChoiceField, ContentTypeField, SerializedPKRelatedField
from netbox.api.serializers import NetBoxModelSerializer, WritableNestedSerializer from netbox.api.serializers import NetBoxModelSerializer, WritableNestedSerializer
from netbox.constants import NESTED_SERIALIZER_PREFIX from netbox.constants import NESTED_SERIALIZER_PREFIX
from utilities.api import get_serializer_for_model from utilities.api import get_serializer_for_model
from vpn.api.serializers_.l2vpn import L2VPNTerminationSerializer from vpn.api.serializers_.l2vpn import L2VPNTerminationSerializer
from wireless.api.nested_serializers import NestedWirelessLANSerializer, NestedWirelessLinkSerializer from wireless.api.nested_serializers import NestedWirelessLinkSerializer
from wireless.choices import * from wireless.choices import *
from wireless.models import WirelessLAN from wireless.models import WirelessLAN
from .base import ConnectedEndpointsSerializer from .base import ConnectedEndpointsSerializer
from .cables import CabledObjectSerializer from .cables import CabledObjectSerializer
from .devices import DeviceSerializer, ModuleSerializer from .devices import DeviceSerializer, ModuleSerializer, VirtualDeviceContextSerializer
from .manufacturers import ManufacturerSerializer from .manufacturers import ManufacturerSerializer
from .roles import InventoryItemRoleSerializer from .roles import InventoryItemRoleSerializer
from wireless.api.serializers_.wirelesslans import WirelessLANSerializer
from ..nested_serializers import * from ..nested_serializers import *
__all__ = ( __all__ = (
@ -173,7 +173,8 @@ class InterfaceSerializer(NetBoxModelSerializer, CabledObjectSerializer, Connect
device = DeviceSerializer(nested=True) device = DeviceSerializer(nested=True)
vdcs = SerializedPKRelatedField( vdcs = SerializedPKRelatedField(
queryset=VirtualDeviceContext.objects.all(), queryset=VirtualDeviceContext.objects.all(),
serializer=NestedVirtualDeviceContextSerializer, serializer=VirtualDeviceContextSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )
@ -196,7 +197,8 @@ class InterfaceSerializer(NetBoxModelSerializer, CabledObjectSerializer, Connect
untagged_vlan = VLANSerializer(nested=True, required=False, allow_null=True) untagged_vlan = VLANSerializer(nested=True, required=False, allow_null=True)
tagged_vlans = SerializedPKRelatedField( tagged_vlans = SerializedPKRelatedField(
queryset=VLAN.objects.all(), queryset=VLAN.objects.all(),
serializer=NestedVLANSerializer, serializer=VLANSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )
@ -205,7 +207,8 @@ class InterfaceSerializer(NetBoxModelSerializer, CabledObjectSerializer, Connect
wireless_link = NestedWirelessLinkSerializer(read_only=True, allow_null=True) wireless_link = NestedWirelessLinkSerializer(read_only=True, allow_null=True)
wireless_lans = SerializedPKRelatedField( wireless_lans = SerializedPKRelatedField(
queryset=WirelessLAN.objects.all(), queryset=WirelessLAN.objects.all(),
serializer=NestedWirelessLANSerializer, serializer=WirelessLANSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )

View File

@ -6,7 +6,7 @@ from rest_framework import serializers
from dcim.choices import * from dcim.choices import *
from dcim.models import Device, DeviceBay, Module, VirtualDeviceContext from dcim.models import Device, DeviceBay, Module, VirtualDeviceContext
from extras.api.serializers_.provisioning import ConfigTemplateSerializer from extras.api.serializers_.configtemplates import ConfigTemplateSerializer
from ipam.api.serializers_.ip import IPAddressSerializer from ipam.api.serializers_.ip import IPAddressSerializer
from netbox.api.fields import ChoiceField, RelatedObjectCountField from netbox.api.fields import ChoiceField, RelatedObjectCountField
from netbox.api.serializers import NetBoxModelSerializer from netbox.api.serializers import NetBoxModelSerializer

View File

@ -1,7 +1,7 @@
from rest_framework import serializers from rest_framework import serializers
from dcim.models import Platform from dcim.models import Platform
from extras.api.serializers_.provisioning import ConfigTemplateSerializer from extras.api.serializers_.configtemplates import ConfigTemplateSerializer
from netbox.api.fields import RelatedObjectCountField from netbox.api.fields import RelatedObjectCountField
from netbox.api.serializers import NetBoxModelSerializer from netbox.api.serializers import NetBoxModelSerializer
from .manufacturers import ManufacturerSerializer from .manufacturers import ManufacturerSerializer

View File

@ -1,7 +1,7 @@
from rest_framework import serializers from rest_framework import serializers
from dcim.models import DeviceRole, InventoryItemRole from dcim.models import DeviceRole, InventoryItemRole
from extras.api.serializers_.provisioning import ConfigTemplateSerializer from extras.api.serializers_.configtemplates import ConfigTemplateSerializer
from netbox.api.fields import RelatedObjectCountField from netbox.api.fields import RelatedObjectCountField
from netbox.api.serializers import NetBoxModelSerializer from netbox.api.serializers import NetBoxModelSerializer

View File

@ -3,7 +3,7 @@ from timezone_field.rest_framework import TimeZoneSerializerField
from dcim.choices import * from dcim.choices import *
from dcim.models import Location, Region, Site, SiteGroup from dcim.models import Location, Region, Site, SiteGroup
from ipam.api.nested_serializers import NestedASNSerializer from ipam.api.serializers_.asns import ASNSerializer
from ipam.models import ASN from ipam.models import ASN
from netbox.api.fields import ChoiceField, RelatedObjectCountField, SerializedPKRelatedField from netbox.api.fields import ChoiceField, RelatedObjectCountField, SerializedPKRelatedField
from netbox.api.serializers import NestedGroupModelSerializer, NetBoxModelSerializer from netbox.api.serializers import NestedGroupModelSerializer, NetBoxModelSerializer
@ -55,7 +55,8 @@ class SiteSerializer(NetBoxModelSerializer):
time_zone = TimeZoneSerializerField(required=False, allow_null=True) time_zone = TimeZoneSerializerField(required=False, allow_null=True)
asns = SerializedPKRelatedField( asns = SerializedPKRelatedField(
queryset=ASN.objects.all(), queryset=ASN.objects.all(),
serializer=NestedASNSerializer, serializer=ASNSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )

View File

@ -8,7 +8,8 @@ from .serializers_.dashboard import *
from .serializers_.events import * from .serializers_.events import *
from .serializers_.exporttemplates import * from .serializers_.exporttemplates import *
from .serializers_.journaling import * from .serializers_.journaling import *
from .serializers_.provisioning import * from .serializers_.configcontexts import *
from .serializers_.configtemplates import *
from .serializers_.savedfilters import * from .serializers_.savedfilters import *
from .serializers_.scripts import * from .serializers_.scripts import *
from .serializers_.tags import * from .serializers_.tags import *

View File

@ -1,25 +1,21 @@
from rest_framework import serializers from rest_framework import serializers
from core.api.serializers_.data import DataFileSerializer, DataSourceSerializer from core.api.serializers_.data import DataFileSerializer, DataSourceSerializer
from dcim.api.nested_serializers import ( from dcim.api.serializers_.devicetypes import DeviceTypeSerializer
NestedDeviceRoleSerializer, NestedDeviceTypeSerializer, NestedLocationSerializer, NestedPlatformSerializer, from dcim.api.serializers_.platforms import PlatformSerializer
NestedRegionSerializer, NestedSiteSerializer, NestedSiteGroupSerializer, from dcim.api.serializers_.roles import DeviceRoleSerializer
) from dcim.api.serializers_.sites import LocationSerializer, RegionSerializer, SiteSerializer, SiteGroupSerializer
from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site, SiteGroup from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site, SiteGroup
from extras.models import ConfigContext, ConfigTemplate, Tag from extras.models import ConfigContext, Tag
from netbox.api.fields import SerializedPKRelatedField from netbox.api.fields import SerializedPKRelatedField
from netbox.api.serializers import ValidatedModelSerializer from netbox.api.serializers import ValidatedModelSerializer
from netbox.api.serializers.features import TaggableModelSerializer from tenancy.api.serializers_.tenants import TenantSerializer, TenantGroupSerializer
from tenancy.api.nested_serializers import NestedTenantSerializer, NestedTenantGroupSerializer
from tenancy.models import Tenant, TenantGroup from tenancy.models import Tenant, TenantGroup
from virtualization.api.nested_serializers import ( from virtualization.api.serializers_.clusters import ClusterSerializer, ClusterGroupSerializer, ClusterTypeSerializer
NestedClusterGroupSerializer, NestedClusterSerializer, NestedClusterTypeSerializer,
)
from virtualization.models import Cluster, ClusterGroup, ClusterType from virtualization.models import Cluster, ClusterGroup, ClusterType
__all__ = ( __all__ = (
'ConfigContextSerializer', 'ConfigContextSerializer',
'ConfigTemplateSerializer',
) )
@ -27,73 +23,85 @@ class ConfigContextSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='extras-api:configcontext-detail') url = serializers.HyperlinkedIdentityField(view_name='extras-api:configcontext-detail')
regions = SerializedPKRelatedField( regions = SerializedPKRelatedField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
serializer=NestedRegionSerializer, serializer=RegionSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )
site_groups = SerializedPKRelatedField( site_groups = SerializedPKRelatedField(
queryset=SiteGroup.objects.all(), queryset=SiteGroup.objects.all(),
serializer=NestedSiteGroupSerializer, serializer=SiteGroupSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )
sites = SerializedPKRelatedField( sites = SerializedPKRelatedField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
serializer=NestedSiteSerializer, serializer=SiteSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )
locations = SerializedPKRelatedField( locations = SerializedPKRelatedField(
queryset=Location.objects.all(), queryset=Location.objects.all(),
serializer=NestedLocationSerializer, serializer=LocationSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )
device_types = SerializedPKRelatedField( device_types = SerializedPKRelatedField(
queryset=DeviceType.objects.all(), queryset=DeviceType.objects.all(),
serializer=NestedDeviceTypeSerializer, serializer=DeviceTypeSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )
roles = SerializedPKRelatedField( roles = SerializedPKRelatedField(
queryset=DeviceRole.objects.all(), queryset=DeviceRole.objects.all(),
serializer=NestedDeviceRoleSerializer, serializer=DeviceRoleSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )
platforms = SerializedPKRelatedField( platforms = SerializedPKRelatedField(
queryset=Platform.objects.all(), queryset=Platform.objects.all(),
serializer=NestedPlatformSerializer, serializer=PlatformSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )
cluster_types = SerializedPKRelatedField( cluster_types = SerializedPKRelatedField(
queryset=ClusterType.objects.all(), queryset=ClusterType.objects.all(),
serializer=NestedClusterTypeSerializer, serializer=ClusterTypeSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )
cluster_groups = SerializedPKRelatedField( cluster_groups = SerializedPKRelatedField(
queryset=ClusterGroup.objects.all(), queryset=ClusterGroup.objects.all(),
serializer=NestedClusterGroupSerializer, serializer=ClusterGroupSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )
clusters = SerializedPKRelatedField( clusters = SerializedPKRelatedField(
queryset=Cluster.objects.all(), queryset=Cluster.objects.all(),
serializer=NestedClusterSerializer, serializer=ClusterSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )
tenant_groups = SerializedPKRelatedField( tenant_groups = SerializedPKRelatedField(
queryset=TenantGroup.objects.all(), queryset=TenantGroup.objects.all(),
serializer=NestedTenantGroupSerializer, serializer=TenantGroupSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )
tenants = SerializedPKRelatedField( tenants = SerializedPKRelatedField(
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
serializer=NestedTenantSerializer, serializer=TenantSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )
@ -121,27 +129,3 @@ class ConfigContextSerializer(ValidatedModelSerializer):
'created', 'last_updated', 'created', 'last_updated',
] ]
brief_fields = ('id', 'url', 'display', 'name', 'description') brief_fields = ('id', 'url', 'display', 'name', 'description')
#
# Config templates
#
class ConfigTemplateSerializer(TaggableModelSerializer, ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='extras-api:configtemplate-detail')
data_source = DataSourceSerializer(
nested=True,
required=False
)
data_file = DataFileSerializer(
nested=True,
required=False
)
class Meta:
model = ConfigTemplate
fields = [
'id', 'url', 'display', 'name', 'description', 'environment_params', 'template_code', 'data_source',
'data_path', 'data_file', 'data_synced', 'tags', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name', 'description')

View File

@ -0,0 +1,30 @@
from rest_framework import serializers
from core.api.serializers_.data import DataFileSerializer, DataSourceSerializer
from extras.models import ConfigTemplate
from netbox.api.serializers import ValidatedModelSerializer
from netbox.api.serializers.features import TaggableModelSerializer
__all__ = (
'ConfigTemplateSerializer',
)
class ConfigTemplateSerializer(TaggableModelSerializer, ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='extras-api:configtemplate-detail')
data_source = DataSourceSerializer(
nested=True,
required=False
)
data_file = DataFileSerializer(
nested=True,
required=False
)
class Meta:
model = ConfigTemplate
fields = [
'id', 'url', 'display', 'name', 'description', 'environment_params', 'template_code', 'data_source',
'data_path', 'data_file', 'data_synced', 'tags', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name', 'description')

View File

@ -9,7 +9,7 @@ from netbox.api.fields import ChoiceField, ContentTypeField
from netbox.api.serializers import NetBoxModelSerializer from netbox.api.serializers import NetBoxModelSerializer
from netbox.constants import NESTED_SERIALIZER_PREFIX from netbox.constants import NESTED_SERIALIZER_PREFIX
from utilities.api import get_serializer_for_model from utilities.api import get_serializer_for_model
from ..nested_serializers import * from .scripts import ScriptSerializer
__all__ = ( __all__ = (
'EventRuleSerializer', 'EventRuleSerializer',
@ -49,7 +49,7 @@ class EventRuleSerializer(NetBoxModelSerializer):
if instance.action_type == EventRuleActionChoices.SCRIPT: if instance.action_type == EventRuleActionChoices.SCRIPT:
script = instance.action_object script = instance.action_object
instance = script.python_class() if script.python_class else None instance = script.python_class() if script.python_class else None
return NestedScriptSerializer(instance, context=context).data return ScriptSerializer(instance, nested=True, context=context).data
else: else:
serializer = get_serializer_for_model( serializer = get_serializer_for_model(
model=instance.action_object_type.model_class(), model=instance.action_object_type.model_class(),

View File

@ -7,7 +7,7 @@ from netbox.api.fields import ContentTypeField
from netbox.api.serializers import NetBoxModelSerializer from netbox.api.serializers import NetBoxModelSerializer
from netbox.constants import NESTED_SERIALIZER_PREFIX from netbox.constants import NESTED_SERIALIZER_PREFIX
from utilities.api import get_serializer_for_model from utilities.api import get_serializer_for_model
from ..nested_serializers import * from .ip import IPAddressSerializer
__all__ = ( __all__ = (
'FHRPGroupAssignmentSerializer', 'FHRPGroupAssignmentSerializer',
@ -17,7 +17,7 @@ __all__ = (
class FHRPGroupSerializer(NetBoxModelSerializer): class FHRPGroupSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:fhrpgroup-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:fhrpgroup-detail')
ip_addresses = NestedIPAddressSerializer(many=True, read_only=True) ip_addresses = IPAddressSerializer(nested=True, many=True, read_only=True)
class Meta: class Meta:
model = FHRPGroup model = FHRPGroup

View File

@ -6,7 +6,7 @@ from ipam.models import IPAddress, Service, ServiceTemplate
from netbox.api.fields import ChoiceField, SerializedPKRelatedField from netbox.api.fields import ChoiceField, SerializedPKRelatedField
from netbox.api.serializers import NetBoxModelSerializer from netbox.api.serializers import NetBoxModelSerializer
from virtualization.api.serializers_.virtualmachines import VirtualMachineSerializer from virtualization.api.serializers_.virtualmachines import VirtualMachineSerializer
from ..nested_serializers import * from .ip import IPAddressSerializer
__all__ = ( __all__ = (
'ServiceSerializer', 'ServiceSerializer',
@ -34,7 +34,8 @@ class ServiceSerializer(NetBoxModelSerializer):
protocol = ChoiceField(choices=ServiceProtocolChoices, required=False) protocol = ChoiceField(choices=ServiceProtocolChoices, required=False)
ipaddresses = SerializedPKRelatedField( ipaddresses = SerializedPKRelatedField(
queryset=IPAddress.objects.all(), queryset=IPAddress.objects.all(),
serializer=NestedIPAddressSerializer, serializer=IPAddressSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )

View File

@ -4,7 +4,6 @@ from ipam.models import RouteTarget, VRF
from netbox.api.fields import RelatedObjectCountField, SerializedPKRelatedField from netbox.api.fields import RelatedObjectCountField, SerializedPKRelatedField
from netbox.api.serializers import NetBoxModelSerializer from netbox.api.serializers import NetBoxModelSerializer
from tenancy.api.serializers_.tenants import TenantSerializer from tenancy.api.serializers_.tenants import TenantSerializer
from ..nested_serializers import *
__all__ = ( __all__ = (
'RouteTargetSerializer', 'RouteTargetSerializer',
@ -12,18 +11,31 @@ __all__ = (
) )
class RouteTargetSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:routetarget-detail')
tenant = TenantSerializer(nested=True, required=False, allow_null=True)
class Meta:
model = RouteTarget
fields = [
'id', 'url', 'display', 'name', 'tenant', 'description', 'comments', 'tags', 'custom_fields', 'created',
'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name', 'description')
class VRFSerializer(NetBoxModelSerializer): class VRFSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vrf-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vrf-detail')
tenant = TenantSerializer(nested=True, required=False, allow_null=True) tenant = TenantSerializer(nested=True, required=False, allow_null=True)
import_targets = SerializedPKRelatedField( import_targets = SerializedPKRelatedField(
queryset=RouteTarget.objects.all(), queryset=RouteTarget.objects.all(),
serializer=NestedRouteTargetSerializer, serializer=RouteTargetSerializer,
required=False, required=False,
many=True many=True
) )
export_targets = SerializedPKRelatedField( export_targets = SerializedPKRelatedField(
queryset=RouteTarget.objects.all(), queryset=RouteTarget.objects.all(),
serializer=NestedRouteTargetSerializer, serializer=RouteTargetSerializer,
required=False, required=False,
many=True many=True
) )
@ -40,16 +52,3 @@ class VRFSerializer(NetBoxModelSerializer):
'prefix_count', 'prefix_count',
] ]
brief_fields = ('id', 'url', 'display', 'name', 'rd', 'description', 'prefix_count') brief_fields = ('id', 'url', 'display', 'name', 'rd', 'description', 'prefix_count')
class RouteTargetSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:routetarget-detail')
tenant = TenantSerializer(nested=True, required=False, allow_null=True)
class Meta:
model = RouteTarget
fields = [
'id', 'url', 'display', 'name', 'tenant', 'description', 'comments', 'tags', 'custom_fields', 'created',
'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name', 'description')

View File

@ -132,13 +132,15 @@ class SerializedPKRelatedField(PrimaryKeyRelatedField):
Extends PrimaryKeyRelatedField to return a serialized object on read. This is useful for representing related Extends PrimaryKeyRelatedField to return a serialized object on read. This is useful for representing related
objects in a ManyToManyField while still allowing a set of primary keys to be written. objects in a ManyToManyField while still allowing a set of primary keys to be written.
""" """
def __init__(self, serializer, **kwargs): def __init__(self, serializer, nested=False, **kwargs):
self.serializer = serializer self.serializer = serializer
self.nested = nested
self.pk_field = kwargs.pop('pk_field', None) self.pk_field = kwargs.pop('pk_field', None)
super().__init__(**kwargs) super().__init__(**kwargs)
def to_representation(self, value): def to_representation(self, value):
return self.serializer(value, context={'request': self.context['request']}).data return self.serializer(value, nested=self.nested, context={'request': self.context['request']}).data
@extend_schema_field(OpenApiTypes.INT64) @extend_schema_field(OpenApiTypes.INT64)

View File

@ -6,7 +6,7 @@ from rest_framework import serializers
from netbox.api.fields import ContentTypeField, SerializedPKRelatedField from netbox.api.fields import ContentTypeField, SerializedPKRelatedField
from netbox.api.serializers import ValidatedModelSerializer from netbox.api.serializers import ValidatedModelSerializer
from users.models import ObjectPermission from users.models import ObjectPermission
from ..nested_serializers import * from .users import GroupSerializer, UserSerializer
__all__ = ( __all__ = (
'ObjectPermissionSerializer', 'ObjectPermissionSerializer',
@ -21,13 +21,15 @@ class ObjectPermissionSerializer(ValidatedModelSerializer):
) )
groups = SerializedPKRelatedField( groups = SerializedPKRelatedField(
queryset=Group.objects.all(), queryset=Group.objects.all(),
serializer=NestedGroupSerializer, serializer=GroupSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )
users = SerializedPKRelatedField( users = SerializedPKRelatedField(
queryset=get_user_model().objects.all(), queryset=get_user_model().objects.all(),
serializer=NestedUserSerializer, serializer=UserSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )

View File

@ -6,7 +6,6 @@ from rest_framework import serializers
from netbox.api.fields import SerializedPKRelatedField from netbox.api.fields import SerializedPKRelatedField
from netbox.api.serializers import ValidatedModelSerializer from netbox.api.serializers import ValidatedModelSerializer
from ..nested_serializers import *
__all__ = ( __all__ = (
'GroupSerializer', 'GroupSerializer',
@ -14,11 +13,22 @@ __all__ = (
) )
class GroupSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='users-api:group-detail')
user_count = serializers.IntegerField(read_only=True)
class Meta:
model = Group
fields = ('id', 'url', 'display', 'name', 'user_count')
brief_fields = ('id', 'url', 'display', 'name')
class UserSerializer(ValidatedModelSerializer): class UserSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='users-api:user-detail') url = serializers.HyperlinkedIdentityField(view_name='users-api:user-detail')
groups = SerializedPKRelatedField( groups = SerializedPKRelatedField(
queryset=Group.objects.all(), queryset=Group.objects.all(),
serializer=NestedGroupSerializer, serializer=GroupSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )
@ -60,13 +70,3 @@ class UserSerializer(ValidatedModelSerializer):
if full_name := obj.get_full_name(): if full_name := obj.get_full_name():
return f"{obj.username} ({full_name})" return f"{obj.username} ({full_name})"
return obj.username return obj.username
class GroupSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='users-api:group-detail')
user_count = serializers.IntegerField(read_only=True)
class Meta:
model = Group
fields = ('id', 'url', 'display', 'name', 'user_count')
brief_fields = ('id', 'url', 'display', 'name')

View File

@ -6,8 +6,7 @@ from dcim.api.serializers_.platforms import PlatformSerializer
from dcim.api.serializers_.roles import DeviceRoleSerializer from dcim.api.serializers_.roles import DeviceRoleSerializer
from dcim.api.serializers_.sites import SiteSerializer from dcim.api.serializers_.sites import SiteSerializer
from dcim.choices import InterfaceModeChoices from dcim.choices import InterfaceModeChoices
from extras.api.serializers_.provisioning import ConfigTemplateSerializer from extras.api.serializers_.configtemplates import ConfigTemplateSerializer
from ipam.api.nested_serializers import NestedVLANSerializer
from ipam.api.serializers_.ip import IPAddressSerializer from ipam.api.serializers_.ip import IPAddressSerializer
from ipam.api.serializers_.vlans import VLANSerializer from ipam.api.serializers_.vlans import VLANSerializer
from ipam.api.serializers_.vrfs import VRFSerializer from ipam.api.serializers_.vrfs import VRFSerializer
@ -18,9 +17,8 @@ from tenancy.api.serializers_.tenants import TenantSerializer
from virtualization.choices import * from virtualization.choices import *
from virtualization.models import VirtualDisk, VirtualMachine, VMInterface from virtualization.models import VirtualDisk, VirtualMachine, VMInterface
from vpn.api.serializers_.l2vpn import L2VPNTerminationSerializer from vpn.api.serializers_.l2vpn import L2VPNTerminationSerializer
from ..nested_serializers import *
from .clusters import ClusterSerializer from .clusters import ClusterSerializer
from ..nested_serializers import *
__all__ = ( __all__ = (
'VMInterfaceSerializer', 'VMInterfaceSerializer',
@ -89,7 +87,8 @@ class VMInterfaceSerializer(NetBoxModelSerializer):
untagged_vlan = VLANSerializer(nested=True, required=False, allow_null=True) untagged_vlan = VLANSerializer(nested=True, required=False, allow_null=True)
tagged_vlans = SerializedPKRelatedField( tagged_vlans = SerializedPKRelatedField(
queryset=VLAN.objects.all(), queryset=VLAN.objects.all(),
serializer=NestedVLANSerializer, serializer=VLANSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )

View File

@ -4,7 +4,6 @@ from netbox.api.fields import ChoiceField, SerializedPKRelatedField
from netbox.api.serializers import NetBoxModelSerializer from netbox.api.serializers import NetBoxModelSerializer
from vpn.choices import * from vpn.choices import *
from vpn.models import IKEPolicy, IKEProposal, IPSecPolicy, IPSecProfile, IPSecProposal from vpn.models import IKEPolicy, IKEProposal, IPSecPolicy, IPSecProfile, IPSecProposal
from ..nested_serializers import *
__all__ = ( __all__ = (
'IKEPolicySerializer', 'IKEPolicySerializer',
@ -54,7 +53,8 @@ class IKEPolicySerializer(NetBoxModelSerializer):
) )
proposals = SerializedPKRelatedField( proposals = SerializedPKRelatedField(
queryset=IKEProposal.objects.all(), queryset=IKEProposal.objects.all(),
serializer=NestedIKEProposalSerializer, serializer=IKEProposalSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )
@ -94,7 +94,8 @@ class IPSecPolicySerializer(NetBoxModelSerializer):
) )
proposals = SerializedPKRelatedField( proposals = SerializedPKRelatedField(
queryset=IPSecProposal.objects.all(), queryset=IPSecProposal.objects.all(),
serializer=NestedIPSecProposalSerializer, serializer=IPSecProposalSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )

View File

@ -2,7 +2,7 @@ from django.contrib.contenttypes.models import ContentType
from drf_spectacular.utils import extend_schema_field from drf_spectacular.utils import extend_schema_field
from rest_framework import serializers from rest_framework import serializers
from ipam.api.nested_serializers import NestedRouteTargetSerializer from ipam.api.serializers_.vrfs import RouteTargetSerializer
from ipam.models import RouteTarget from ipam.models import RouteTarget
from netbox.api.fields import ChoiceField, ContentTypeField, SerializedPKRelatedField from netbox.api.fields import ChoiceField, ContentTypeField, SerializedPKRelatedField
from netbox.api.serializers import NetBoxModelSerializer from netbox.api.serializers import NetBoxModelSerializer
@ -23,13 +23,15 @@ class L2VPNSerializer(NetBoxModelSerializer):
type = ChoiceField(choices=L2VPNTypeChoices, required=False) type = ChoiceField(choices=L2VPNTypeChoices, required=False)
import_targets = SerializedPKRelatedField( import_targets = SerializedPKRelatedField(
queryset=RouteTarget.objects.all(), queryset=RouteTarget.objects.all(),
serializer=NestedRouteTargetSerializer, serializer=RouteTargetSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )
export_targets = SerializedPKRelatedField( export_targets = SerializedPKRelatedField(
queryset=RouteTarget.objects.all(), queryset=RouteTarget.objects.all(),
serializer=NestedRouteTargetSerializer, serializer=RouteTargetSerializer,
nested=True,
required=False, required=False,
many=True many=True
) )