cables.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. import django_tables2 as tables
  2. from django.utils.html import escape
  3. from django.utils.safestring import mark_safe
  4. from django.utils.translation import gettext_lazy as _
  5. from django_tables2.utils import Accessor
  6. from dcim.models import Cable, CableBundle
  7. from netbox.tables import PrimaryModelTable, columns
  8. from tenancy.tables import TenancyColumnsMixin
  9. from .template_code import CABLE_LENGTH
  10. __all__ = (
  11. 'CableBundleTable',
  12. 'CableTable',
  13. )
  14. class CableTerminationsColumn(tables.Column):
  15. """
  16. Args:
  17. cable_end: Which side of the cable to report on (A or B)
  18. attr: The CableTermination attribute to return for each instance (returns the termination object by default)
  19. """
  20. def __init__(self, cable_end, attr='termination', *args, **kwargs):
  21. self.cable_end = cable_end
  22. self.attr = attr
  23. super().__init__(accessor=Accessor('terminations'), *args, **kwargs)
  24. def _get_terminations(self, manager):
  25. terminations = set()
  26. for cabletermination in manager.all():
  27. if cabletermination.cable_end == self.cable_end:
  28. if termination := getattr(cabletermination, self.attr, None):
  29. terminations.add(termination)
  30. return terminations
  31. def render(self, value):
  32. links = [
  33. f'<a href="{term.get_absolute_url()}">{escape(term)}</a>' for term in self._get_terminations(value)
  34. ]
  35. return mark_safe('<br />'.join(links) or '&mdash;')
  36. def value(self, value):
  37. return ','.join([str(t) for t in self._get_terminations(value)])
  38. #
  39. # Cables
  40. #
  41. class CableTable(TenancyColumnsMixin, PrimaryModelTable):
  42. a_terminations = CableTerminationsColumn(
  43. cable_end='A',
  44. orderable=False,
  45. verbose_name=_('Termination A')
  46. )
  47. b_terminations = CableTerminationsColumn(
  48. cable_end='B',
  49. orderable=False,
  50. verbose_name=_('Termination B')
  51. )
  52. device_a = CableTerminationsColumn(
  53. cable_end='A',
  54. attr='_device',
  55. orderable=False,
  56. verbose_name=_('Device A')
  57. )
  58. device_b = CableTerminationsColumn(
  59. cable_end='B',
  60. attr='_device',
  61. orderable=False,
  62. verbose_name=_('Device B')
  63. )
  64. location_a = CableTerminationsColumn(
  65. cable_end='A',
  66. attr='_location',
  67. orderable=False,
  68. verbose_name=_('Location A')
  69. )
  70. location_b = CableTerminationsColumn(
  71. cable_end='B',
  72. attr='_location',
  73. orderable=False,
  74. verbose_name=_('Location B')
  75. )
  76. rack_a = CableTerminationsColumn(
  77. cable_end='A',
  78. attr='_rack',
  79. orderable=False,
  80. verbose_name=_('Rack A')
  81. )
  82. rack_b = CableTerminationsColumn(
  83. cable_end='B',
  84. attr='_rack',
  85. orderable=False,
  86. verbose_name=_('Rack B')
  87. )
  88. site_a = CableTerminationsColumn(
  89. cable_end='A',
  90. attr='_site',
  91. orderable=False,
  92. verbose_name=_('Site A')
  93. )
  94. site_b = CableTerminationsColumn(
  95. cable_end='B',
  96. attr='_site',
  97. orderable=False,
  98. verbose_name=_('Site B')
  99. )
  100. status = columns.ChoiceFieldColumn()
  101. profile = columns.ChoiceFieldColumn()
  102. length = columns.TemplateColumn(
  103. template_code=CABLE_LENGTH,
  104. order_by=('_abs_length')
  105. )
  106. color = columns.ColorColumn()
  107. color_name = tables.Column(
  108. verbose_name=_('Color Name'),
  109. orderable=False
  110. )
  111. bundle = tables.Column(
  112. verbose_name=_('Bundle'),
  113. linkify=True,
  114. )
  115. tags = columns.TagColumn(
  116. url_name='dcim:cable_list'
  117. )
  118. class Meta(PrimaryModelTable.Meta):
  119. model = Cable
  120. fields = (
  121. 'pk', 'id', 'label', 'a_terminations', 'b_terminations', 'device_a', 'device_b', 'rack_a', 'rack_b',
  122. 'location_a', 'location_b', 'site_a', 'site_b', 'status', 'profile', 'type', 'tenant', 'tenant_group',
  123. 'color', 'color_name', 'bundle', 'length', 'description', 'comments', 'tags', 'created', 'last_updated',
  124. )
  125. default_columns = (
  126. 'pk', 'id', 'label', 'a_terminations', 'b_terminations', 'status', 'type',
  127. )
  128. class CableBundleTable(PrimaryModelTable):
  129. name = tables.Column(
  130. verbose_name=_('Name'),
  131. linkify=True,
  132. )
  133. cable_count = tables.Column(
  134. verbose_name=_('Cables'),
  135. )
  136. tags = columns.TagColumn(
  137. url_name='dcim:cablebundle_list'
  138. )
  139. class Meta(PrimaryModelTable.Meta):
  140. model = CableBundle
  141. fields = (
  142. 'pk', 'id', 'name', 'cable_count', 'description', 'tags', 'created', 'last_updated',
  143. )
  144. default_columns = (
  145. 'pk', 'id', 'name', 'cable_count', 'description',
  146. )