cables.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. from drf_spectacular.types import OpenApiTypes
  2. from drf_spectacular.utils import extend_schema_field
  3. from rest_framework import serializers
  4. from dcim.choices import *
  5. from dcim.models import Cable, CablePath, CableTermination
  6. from netbox.api.fields import ChoiceField, ContentTypeField
  7. from netbox.api.serializers import BaseModelSerializer, GenericObjectSerializer, NetBoxModelSerializer
  8. from tenancy.api.serializers_.tenants import TenantSerializer
  9. from utilities.api import get_serializer_for_model
  10. __all__ = (
  11. 'CablePathSerializer',
  12. 'CableSerializer',
  13. 'CableTerminationSerializer',
  14. 'CabledObjectSerializer',
  15. 'TracedCableSerializer',
  16. )
  17. class CableSerializer(NetBoxModelSerializer):
  18. a_terminations = GenericObjectSerializer(many=True, required=False)
  19. b_terminations = GenericObjectSerializer(many=True, required=False)
  20. status = ChoiceField(choices=LinkStatusChoices, required=False)
  21. tenant = TenantSerializer(nested=True, required=False, allow_null=True)
  22. length_unit = ChoiceField(choices=CableLengthUnitChoices, allow_blank=True, required=False, allow_null=True)
  23. class Meta:
  24. model = Cable
  25. fields = [
  26. 'id', 'url', 'display_url', 'display', 'type', 'a_terminations', 'b_terminations', 'status', 'tenant',
  27. 'label', 'color', 'length', 'length_unit', 'description', 'comments', 'tags', 'custom_fields', 'created',
  28. 'last_updated',
  29. ]
  30. brief_fields = ('id', 'url', 'display', 'label', 'description')
  31. class TracedCableSerializer(BaseModelSerializer):
  32. """
  33. Used only while tracing a cable path.
  34. """
  35. class Meta:
  36. model = Cable
  37. fields = [
  38. 'id', 'url', 'display_url', 'type', 'status', 'label', 'color', 'length', 'length_unit', 'description',
  39. ]
  40. class CableTerminationSerializer(NetBoxModelSerializer):
  41. termination_type = ContentTypeField(
  42. read_only=True,
  43. )
  44. termination = serializers.SerializerMethodField(
  45. read_only=True,
  46. )
  47. class Meta:
  48. model = CableTermination
  49. fields = [
  50. 'id', 'url', 'display', 'cable', 'cable_end', 'termination_type', 'termination_id',
  51. 'termination', 'created', 'last_updated',
  52. ]
  53. read_only_fields = fields
  54. brief_fields = ('id', 'url', 'display', 'cable', 'cable_end', 'termination_type', 'termination_id')
  55. @extend_schema_field(serializers.JSONField(allow_null=True))
  56. def get_termination(self, obj):
  57. serializer = get_serializer_for_model(obj.termination)
  58. context = {'request': self.context['request']}
  59. return serializer(obj.termination, nested=True, context=context).data
  60. class CablePathSerializer(serializers.ModelSerializer):
  61. path = serializers.SerializerMethodField(read_only=True)
  62. class Meta:
  63. model = CablePath
  64. fields = ['id', 'path', 'is_active', 'is_complete', 'is_split']
  65. @extend_schema_field(serializers.ListField)
  66. def get_path(self, obj):
  67. ret = []
  68. for nodes in obj.path_objects:
  69. serializer = get_serializer_for_model(nodes[0])
  70. context = {'request': self.context['request']}
  71. ret.append(serializer(nodes, nested=True, many=True, context=context).data)
  72. return ret
  73. class CabledObjectSerializer(serializers.ModelSerializer):
  74. cable = CableSerializer(nested=True, read_only=True, allow_null=True)
  75. cable_end = serializers.CharField(read_only=True)
  76. link_peers_type = serializers.SerializerMethodField(read_only=True, allow_null=True)
  77. link_peers = serializers.SerializerMethodField(read_only=True)
  78. _occupied = serializers.SerializerMethodField(read_only=True)
  79. @extend_schema_field(OpenApiTypes.STR)
  80. def get_link_peers_type(self, obj):
  81. """
  82. Return the type of the peer link terminations, or None.
  83. """
  84. if not obj.cable:
  85. return None
  86. if obj.link_peers:
  87. return f'{obj.link_peers[0]._meta.app_label}.{obj.link_peers[0]._meta.model_name}'
  88. return None
  89. @extend_schema_field(serializers.ListField)
  90. def get_link_peers(self, obj):
  91. """
  92. Return the appropriate serializer for the link termination model.
  93. """
  94. if not obj.link_peers:
  95. return []
  96. # Return serialized peer termination objects
  97. serializer = get_serializer_for_model(obj.link_peers[0])
  98. context = {'request': self.context['request']}
  99. return serializer(obj.link_peers, nested=True, many=True, context=context).data
  100. @extend_schema_field(serializers.BooleanField)
  101. def get__occupied(self, obj):
  102. return obj._occupied