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

12278 add ipaddressfield serializer for OpenAPI spectacular typing (#12285)

* #12278 add serializer for ipaddressfield to remove spectacular warnings

* #12278 add ipaddressfieldserializer to nested serializers

* #12278 fix to_internal_value to_representation in serializer

* #12278 to_internal_value is called before validation! need to raise validation error if incorrect format

* #12278 to_internal_value needs to return value doh

* #12278 move IPAddressField to field_serializers

* #12278 remove old import

* 12278 remove validator
Arthur Hanson 2 лет назад
Родитель
Сommit
55385dd0db

+ 32 - 0
netbox/ipam/api/field_serializers.py

@@ -0,0 +1,32 @@
+from django.utils.translation import gettext_lazy as _
+from rest_framework import serializers
+
+from ipam import models
+from netaddr import AddrFormatError, IPNetwork
+
+__all__ = [
+    'IPAddressField',
+]
+
+
+#
+# IP address field
+#
+
+class IPAddressField(serializers.CharField):
+    """IPAddressField with mask"""
+
+    default_error_messages = {
+        'invalid': _('Enter a valid IPv4 or IPv6 address with optional mask.'),
+    }
+
+    def to_internal_value(self, data):
+        try:
+            return IPNetwork(data)
+        except AddrFormatError:
+            raise serializers.ValidationError("Invalid IP address format: {}".format(data))
+        except (TypeError, ValueError) as e:
+            raise serializers.ValidationError(e)
+
+    def to_representation(self, value):
+        return str(value)

+ 4 - 0
netbox/ipam/api/nested_serializers.py

@@ -4,6 +4,7 @@ from rest_framework import serializers
 from ipam import models
 from ipam import models
 from ipam.models.l2vpn import L2VPNTermination, L2VPN
 from ipam.models.l2vpn import L2VPNTermination, L2VPN
 from netbox.api.serializers import WritableNestedSerializer
 from netbox.api.serializers import WritableNestedSerializer
+from .field_serializers import IPAddressField
 
 
 __all__ = [
 __all__ = [
     'NestedAggregateSerializer',
     'NestedAggregateSerializer',
@@ -182,6 +183,8 @@ class NestedPrefixSerializer(WritableNestedSerializer):
 class NestedIPRangeSerializer(WritableNestedSerializer):
 class NestedIPRangeSerializer(WritableNestedSerializer):
     url = serializers.HyperlinkedIdentityField(view_name='ipam-api:iprange-detail')
     url = serializers.HyperlinkedIdentityField(view_name='ipam-api:iprange-detail')
     family = serializers.IntegerField(read_only=True)
     family = serializers.IntegerField(read_only=True)
+    start_address = IPAddressField()
+    end_address = IPAddressField()
 
 
     class Meta:
     class Meta:
         model = models.IPRange
         model = models.IPRange
@@ -195,6 +198,7 @@ class NestedIPRangeSerializer(WritableNestedSerializer):
 class NestedIPAddressSerializer(WritableNestedSerializer):
 class NestedIPAddressSerializer(WritableNestedSerializer):
     url = serializers.HyperlinkedIdentityField(view_name='ipam-api:ipaddress-detail')
     url = serializers.HyperlinkedIdentityField(view_name='ipam-api:ipaddress-detail')
     family = serializers.IntegerField(read_only=True)
     family = serializers.IntegerField(read_only=True)
+    address = IPAddressField()
 
 
     class Meta:
     class Meta:
         model = models.IPAddress
         model = models.IPAddress

+ 4 - 0
netbox/ipam/api/serializers.py

@@ -13,6 +13,7 @@ from tenancy.api.nested_serializers import NestedTenantSerializer
 from utilities.api import get_serializer_for_model
 from utilities.api import get_serializer_for_model
 from virtualization.api.nested_serializers import NestedVirtualMachineSerializer
 from virtualization.api.nested_serializers import NestedVirtualMachineSerializer
 from .nested_serializers import *
 from .nested_serializers import *
+from .field_serializers import IPAddressField
 
 
 
 
 #
 #
@@ -369,6 +370,8 @@ class AvailablePrefixSerializer(serializers.Serializer):
 class IPRangeSerializer(NetBoxModelSerializer):
 class IPRangeSerializer(NetBoxModelSerializer):
     url = serializers.HyperlinkedIdentityField(view_name='ipam-api:iprange-detail')
     url = serializers.HyperlinkedIdentityField(view_name='ipam-api:iprange-detail')
     family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
     family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
+    start_address = IPAddressField()
+    end_address = IPAddressField()
     vrf = NestedVRFSerializer(required=False, allow_null=True)
     vrf = NestedVRFSerializer(required=False, allow_null=True)
     tenant = NestedTenantSerializer(required=False, allow_null=True)
     tenant = NestedTenantSerializer(required=False, allow_null=True)
     status = ChoiceField(choices=IPRangeStatusChoices, required=False)
     status = ChoiceField(choices=IPRangeStatusChoices, required=False)
@@ -391,6 +394,7 @@ class IPRangeSerializer(NetBoxModelSerializer):
 class IPAddressSerializer(NetBoxModelSerializer):
 class IPAddressSerializer(NetBoxModelSerializer):
     url = serializers.HyperlinkedIdentityField(view_name='ipam-api:ipaddress-detail')
     url = serializers.HyperlinkedIdentityField(view_name='ipam-api:ipaddress-detail')
     family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
     family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
+    address = IPAddressField()
     vrf = NestedVRFSerializer(required=False, allow_null=True)
     vrf = NestedVRFSerializer(required=False, allow_null=True)
     tenant = NestedTenantSerializer(required=False, allow_null=True)
     tenant = NestedTenantSerializer(required=False, allow_null=True)
     status = ChoiceField(choices=IPAddressStatusChoices, required=False)
     status = ChoiceField(choices=IPAddressStatusChoices, required=False)