cables.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. from django.contrib.contenttypes.models import ContentType
  2. from drf_spectacular.types import OpenApiTypes
  3. from drf_spectacular.utils import extend_schema_field
  4. from rest_framework import serializers
  5. from dcim.choices import *
  6. from dcim.constants import *
  7. from dcim.models import Cable, CablePath, CableTermination
  8. from netbox.api.fields import ChoiceField, ContentTypeField
  9. from netbox.api.serializers import GenericObjectSerializer, NetBoxModelSerializer
  10. from tenancy.api.serializers_.tenants import TenantSerializer
  11. from utilities.api import get_serializer_for_model
  12. __all__ = (
  13. 'CablePathSerializer',
  14. 'CableSerializer',
  15. 'CableTerminationSerializer',
  16. 'CabledObjectSerializer',
  17. 'TracedCableSerializer',
  18. )
  19. class CableSerializer(NetBoxModelSerializer):
  20. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:cable-detail')
  21. a_terminations = GenericObjectSerializer(many=True, required=False)
  22. b_terminations = GenericObjectSerializer(many=True, required=False)
  23. status = ChoiceField(choices=LinkStatusChoices, required=False)
  24. tenant = TenantSerializer(nested=True, required=False, allow_null=True)
  25. length_unit = ChoiceField(choices=CableLengthUnitChoices, allow_blank=True, required=False, allow_null=True)
  26. class Meta:
  27. model = Cable
  28. fields = [
  29. 'id', 'url', 'display', 'type', 'a_terminations', 'b_terminations', 'status', 'tenant', 'label', 'color',
  30. 'length', 'length_unit', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
  31. ]
  32. brief_fields = ('id', 'url', 'display', 'label', 'description')
  33. class TracedCableSerializer(serializers.ModelSerializer):
  34. """
  35. Used only while tracing a cable path.
  36. """
  37. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:cable-detail')
  38. class Meta:
  39. model = Cable
  40. fields = [
  41. 'id', 'url', 'type', 'status', 'label', 'color', 'length', 'length_unit', 'description',
  42. ]
  43. class CableTerminationSerializer(NetBoxModelSerializer):
  44. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:cabletermination-detail')
  45. termination_type = ContentTypeField(
  46. queryset=ContentType.objects.filter(CABLE_TERMINATION_MODELS)
  47. )
  48. termination = serializers.SerializerMethodField(read_only=True)
  49. class Meta:
  50. model = CableTermination
  51. fields = [
  52. 'id', 'url', 'display', 'cable', 'cable_end', 'termination_type', 'termination_id', 'termination',
  53. 'created', 'last_updated',
  54. ]
  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