cables.py 4.6 KB

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