connections.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. from django import forms
  2. from circuits.models import Circuit, CircuitTermination, Provider
  3. from dcim.models import *
  4. from utilities.forms import DynamicModelChoiceField, DynamicModelMultipleChoiceField
  5. from .models import CableForm
  6. def get_cable_form(a_type, b_type):
  7. class FormMetaclass(forms.models.ModelFormMetaclass):
  8. def __new__(mcs, name, bases, attrs):
  9. for cable_end, term_cls in (('a', a_type), ('b', b_type)):
  10. attrs[f'termination_{cable_end}_region'] = DynamicModelChoiceField(
  11. queryset=Region.objects.all(),
  12. label='Region',
  13. required=False,
  14. initial_params={
  15. 'sites': f'$termination_{cable_end}_site'
  16. }
  17. )
  18. attrs[f'termination_{cable_end}_sitegroup'] = DynamicModelChoiceField(
  19. queryset=SiteGroup.objects.all(),
  20. label='Site group',
  21. required=False,
  22. initial_params={
  23. 'sites': f'$termination_{cable_end}_site'
  24. }
  25. )
  26. attrs[f'termination_{cable_end}_site'] = DynamicModelChoiceField(
  27. queryset=Site.objects.all(),
  28. label='Site',
  29. required=False,
  30. query_params={
  31. 'region_id': f'$termination_{cable_end}_region',
  32. 'group_id': f'$termination_{cable_end}_sitegroup',
  33. }
  34. )
  35. attrs[f'termination_{cable_end}_location'] = DynamicModelChoiceField(
  36. queryset=Location.objects.all(),
  37. label='Location',
  38. required=False,
  39. null_option='None',
  40. query_params={
  41. 'site_id': f'$termination_{cable_end}_site'
  42. }
  43. )
  44. # Device component
  45. if hasattr(term_cls, 'device'):
  46. attrs[f'termination_{cable_end}_rack'] = DynamicModelChoiceField(
  47. queryset=Rack.objects.all(),
  48. label='Rack',
  49. required=False,
  50. null_option='None',
  51. initial_params={
  52. 'devices': f'$termination_{cable_end}_device'
  53. },
  54. query_params={
  55. 'site_id': f'$termination_{cable_end}_site',
  56. 'location_id': f'$termination_{cable_end}_location',
  57. }
  58. )
  59. attrs[f'termination_{cable_end}_device'] = DynamicModelChoiceField(
  60. queryset=Device.objects.all(),
  61. label='Device',
  62. required=False,
  63. initial_params={
  64. f'{term_cls._meta.model_name}s__in': f'${cable_end}_terminations'
  65. },
  66. query_params={
  67. 'site_id': f'$termination_{cable_end}_site',
  68. 'location_id': f'$termination_{cable_end}_location',
  69. 'rack_id': f'$termination_{cable_end}_rack',
  70. }
  71. )
  72. attrs[f'{cable_end}_terminations'] = DynamicModelMultipleChoiceField(
  73. queryset=term_cls.objects.all(),
  74. label=term_cls._meta.verbose_name.title(),
  75. disabled_indicator='_occupied',
  76. query_params={
  77. 'device_id': f'$termination_{cable_end}_device',
  78. }
  79. )
  80. # PowerFeed
  81. elif term_cls == PowerFeed:
  82. attrs[f'termination_{cable_end}_powerpanel'] = DynamicModelChoiceField(
  83. queryset=PowerPanel.objects.all(),
  84. label='Power Panel',
  85. required=False,
  86. initial_params={
  87. 'powerfeeds__in': f'${cable_end}_terminations'
  88. },
  89. query_params={
  90. 'site_id': f'$termination_{cable_end}_site',
  91. 'location_id': f'$termination_{cable_end}_location',
  92. }
  93. )
  94. attrs[f'{cable_end}_terminations'] = DynamicModelMultipleChoiceField(
  95. queryset=term_cls.objects.all(),
  96. label='Power Feed',
  97. disabled_indicator='_occupied',
  98. query_params={
  99. 'powerpanel_id': f'$termination_{cable_end}_powerpanel',
  100. }
  101. )
  102. # CircuitTermination
  103. elif term_cls == CircuitTermination:
  104. attrs[f'termination_{cable_end}_provider'] = DynamicModelChoiceField(
  105. queryset=Provider.objects.all(),
  106. label='Provider',
  107. initial_params={
  108. 'circuits': f'$termination_{cable_end}_circuit'
  109. },
  110. required=False
  111. )
  112. attrs[f'termination_{cable_end}_circuit'] = DynamicModelChoiceField(
  113. queryset=Circuit.objects.all(),
  114. label='Circuit',
  115. initial_params={
  116. 'terminations__in': f'${cable_end}_terminations'
  117. },
  118. query_params={
  119. 'provider_id': f'$termination_{cable_end}_provider',
  120. 'site_id': f'$termination_{cable_end}_site',
  121. }
  122. )
  123. attrs[f'{cable_end}_terminations'] = DynamicModelMultipleChoiceField(
  124. queryset=term_cls.objects.all(),
  125. label='Side',
  126. disabled_indicator='_occupied',
  127. query_params={
  128. 'circuit_id': f'termination_{cable_end}_circuit',
  129. }
  130. )
  131. return super().__new__(mcs, name, bases, attrs)
  132. class _CableForm(CableForm, metaclass=FormMetaclass):
  133. def __init__(self, *args, **kwargs):
  134. # TODO: Temporary hack to work around list handling limitations with utils.normalize_querydict()
  135. for field_name in ('a_terminations', 'b_terminations'):
  136. if field_name in kwargs.get('initial', {}) and type(kwargs['initial'][field_name]) is not list:
  137. kwargs['initial'][field_name] = [kwargs['initial'][field_name]]
  138. super().__init__(*args, **kwargs)
  139. if self.instance and self.instance.pk:
  140. # Initialize A/B terminations when modifying an existing Cable instance
  141. self.initial['a_terminations'] = self.instance.a_terminations
  142. self.initial['b_terminations'] = self.instance.b_terminations
  143. def clean(self):
  144. super().clean()
  145. # Set the A/B terminations on the Cable instance
  146. self.instance.a_terminations = self.cleaned_data['a_terminations']
  147. self.instance.b_terminations = self.cleaned_data['b_terminations']
  148. return _CableForm