Coverage for dcim/tables/devicetypes.py: 100%
125 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 18:35 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 18:35 +0000
1import django_tables2 as tables
2from django.utils.translation import gettext_lazy as _
4from dcim import models
5from netbox.tables import NetBoxTable, OrganizationalModelTable, PrimaryModelTable, columns
6from tenancy.tables import ContactsColumnMixin
8from .template_code import MODULAR_COMPONENT_TEMPLATE_BUTTONS, WEIGHT
10__all__ = (
11 'ConsolePortTemplateTable',
12 'ConsoleServerPortTemplateTable',
13 'DeviceBayTemplateTable',
14 'DeviceTypeTable',
15 'FrontPortTemplateTable',
16 'InterfaceTemplateTable',
17 'InventoryItemTemplateTable',
18 'ManufacturerTable',
19 'ModuleBayTemplateTable',
20 'PowerOutletTemplateTable',
21 'PowerPortTemplateTable',
22 'RearPortTemplateTable',
23)
26#
27# Manufacturers
28#
30class ManufacturerTable(ContactsColumnMixin, OrganizationalModelTable):
31 name = tables.Column(
32 verbose_name=_('Name'),
33 linkify=True
34 )
35 racktype_count = columns.LinkedCountColumn(
36 viewname='dcim:racktype_list',
37 url_params={'manufacturer_id': 'pk'},
38 verbose_name=_('Rack Types')
39 )
40 devicetype_count = columns.LinkedCountColumn(
41 viewname='dcim:devicetype_list',
42 url_params={'manufacturer_id': 'pk'},
43 verbose_name=_('Device Types')
44 )
45 moduletype_count = columns.LinkedCountColumn(
46 viewname='dcim:moduletype_list',
47 url_params={'manufacturer_id': 'pk'},
48 verbose_name=_('Module Types')
49 )
50 inventoryitem_count = columns.LinkedCountColumn(
51 viewname='dcim:inventoryitem_list',
52 url_params={'manufacturer_id': 'pk'},
53 verbose_name=_('Inventory Items')
54 )
55 platform_count = columns.LinkedCountColumn(
56 viewname='dcim:platform_list',
57 url_params={'manufacturer_id': 'pk'},
58 verbose_name=_('Platforms')
59 )
60 tags = columns.TagColumn(
61 url_name='dcim:manufacturer_list'
62 )
64 class Meta(OrganizationalModelTable.Meta):
65 model = models.Manufacturer
66 fields = (
67 'pk', 'id', 'name', 'racktype_count', 'devicetype_count', 'moduletype_count', 'inventoryitem_count',
68 'platform_count', 'description', 'slug', 'comments', 'tags', 'contacts', 'actions', 'created',
69 'last_updated',
70 )
71 default_columns = (
72 'pk', 'name', 'racktype_count', 'devicetype_count', 'moduletype_count', 'inventoryitem_count',
73 'platform_count', 'description', 'slug',
74 )
77#
78# Device types
79#
81class DeviceTypeTable(PrimaryModelTable):
82 model = tables.Column(
83 linkify=True,
84 verbose_name=_('Device Type')
85 )
86 manufacturer = tables.Column(
87 verbose_name=_('Manufacturer'),
88 linkify=True
89 )
90 default_platform = tables.Column(
91 verbose_name=_('Default Platform'),
92 linkify=True
93 )
94 is_full_depth = columns.BooleanColumn(
95 verbose_name=_('Full Depth'),
96 false_mark=None
97 )
98 tags = columns.TagColumn(
99 url_name='dcim:devicetype_list'
100 )
101 u_height = columns.TemplateColumn(
102 verbose_name=_('U Height'),
103 template_code='{{ value|floatformat }}'
104 )
105 exclude_from_utilization = columns.BooleanColumn(
106 verbose_name=_('Exclude from utilization'),
107 false_mark=None
108 )
109 weight = columns.TemplateColumn(
110 verbose_name=_('Weight'),
111 template_code=WEIGHT,
112 order_by=('_abs_weight', 'weight_unit')
113 )
114 device_count = columns.LinkedCountColumn(
115 viewname='dcim:device_list',
116 url_params={'device_type_id': 'pk'},
117 verbose_name=_('Device Count'),
118 )
119 console_port_template_count = tables.Column(
120 verbose_name=_('Console Ports')
121 )
122 console_server_port_template_count = tables.Column(
123 verbose_name=_('Console Server Ports')
124 )
125 power_port_template_count = tables.Column(
126 verbose_name=_('Power Ports')
127 )
128 power_outlet_template_count = tables.Column(
129 verbose_name=_('Power Outlets')
130 )
131 cooling_intake_template_count = tables.Column(
132 verbose_name=_('Cooling Intakes')
133 )
134 cooling_outflow_template_count = tables.Column(
135 verbose_name=_('Cooling Outflows')
136 )
137 interface_template_count = tables.Column(
138 verbose_name=_('Interfaces')
139 )
140 front_port_template_count = tables.Column(
141 verbose_name=_('Front Ports')
142 )
143 rear_port_template_count = tables.Column(
144 verbose_name=_('Rear Ports')
145 )
146 device_bay_template_count = tables.Column(
147 verbose_name=_('Device Bays')
148 )
149 module_bay_template_count = tables.Column(
150 verbose_name=_('Module Bays')
151 )
152 inventory_item_template_count = tables.Column(
153 verbose_name=_('Inventory Items')
154 )
155 cooling_method = columns.ChoiceFieldColumn(
156 verbose_name=_('Cooling Method'),
157 )
159 class Meta(PrimaryModelTable.Meta):
160 model = models.DeviceType
161 fields = (
162 'pk', 'id', 'model', 'manufacturer', 'default_platform', 'slug', 'part_number', 'u_height',
163 'exclude_from_utilization', 'is_full_depth', 'subdevice_role', 'airflow', 'cooling_method', 'weight',
164 'end_of_life',
165 'description', 'comments', 'device_count', 'tags', 'created', 'last_updated',
166 )
167 default_columns = (
168 'pk', 'model', 'manufacturer', 'part_number', 'u_height', 'is_full_depth', 'device_count',
169 )
172#
173# Device type components
174#
176class ComponentTemplateTable(NetBoxTable):
177 id = tables.Column(
178 verbose_name=_('ID')
179 )
180 name = tables.Column()
182 class Meta(NetBoxTable.Meta):
183 exclude = ('id', )
186class ConsolePortTemplateTable(ComponentTemplateTable):
187 actions = columns.ActionsColumn(
188 actions=('edit', 'delete'),
189 extra_buttons=MODULAR_COMPONENT_TEMPLATE_BUTTONS
190 )
192 class Meta(ComponentTemplateTable.Meta):
193 model = models.ConsolePortTemplate
194 fields = ('pk', 'name', 'label', 'type', 'description', 'actions')
195 empty_text = "None"
198class ConsoleServerPortTemplateTable(ComponentTemplateTable):
199 actions = columns.ActionsColumn(
200 actions=('edit', 'delete'),
201 extra_buttons=MODULAR_COMPONENT_TEMPLATE_BUTTONS
202 )
204 class Meta(ComponentTemplateTable.Meta):
205 model = models.ConsoleServerPortTemplate
206 fields = ('pk', 'name', 'label', 'type', 'description', 'actions')
207 empty_text = "None"
210class PowerPortTemplateTable(ComponentTemplateTable):
211 actions = columns.ActionsColumn(
212 actions=('edit', 'delete'),
213 extra_buttons=MODULAR_COMPONENT_TEMPLATE_BUTTONS
214 )
216 class Meta(ComponentTemplateTable.Meta):
217 model = models.PowerPortTemplate
218 fields = ('pk', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description', 'actions')
219 empty_text = "None"
222class PowerOutletTemplateTable(ComponentTemplateTable):
223 color = columns.ColorColumn(
224 verbose_name=_('Color'),
225 )
226 actions = columns.ActionsColumn(
227 actions=('edit', 'delete'),
228 extra_buttons=MODULAR_COMPONENT_TEMPLATE_BUTTONS
229 )
231 class Meta(ComponentTemplateTable.Meta):
232 model = models.PowerOutletTemplate
233 fields = ('pk', 'name', 'label', 'type', 'color', 'power_port', 'feed_leg', 'description', 'actions')
234 empty_text = "None"
237class InterfaceTemplateTable(ComponentTemplateTable):
238 name = tables.Column(
239 verbose_name=_('Name'),
240 order_by=('_name',)
241 )
242 enabled = columns.BooleanColumn(
243 verbose_name=_('Enabled'),
244 )
245 mgmt_only = columns.BooleanColumn(
246 verbose_name=_('Management Only'),
247 false_mark=None
248 )
249 actions = columns.ActionsColumn(
250 actions=('edit', 'delete'),
251 extra_buttons=MODULAR_COMPONENT_TEMPLATE_BUTTONS
252 )
254 class Meta(ComponentTemplateTable.Meta):
255 model = models.InterfaceTemplate
256 fields = (
257 'pk', 'name', 'label', 'enabled', 'mgmt_only', 'type', 'channels', 'channel_id', 'description', 'parent',
258 'bridge', 'poe_mode', 'poe_type', 'rf_role', 'actions',
259 )
260 empty_text = "None"
263class FrontPortTemplateTable(ComponentTemplateTable):
264 color = columns.ColorColumn(
265 verbose_name=_('Color'),
266 )
267 mappings = columns.ManyToManyColumn(
268 verbose_name=_('Mappings'),
269 transform=lambda obj: f'{obj.rear_port}:{obj.rear_port_position}'
270 )
271 actions = columns.ActionsColumn(
272 actions=('edit', 'delete'),
273 extra_buttons=MODULAR_COMPONENT_TEMPLATE_BUTTONS
274 )
276 class Meta(ComponentTemplateTable.Meta):
277 model = models.FrontPortTemplate
278 fields = ('pk', 'name', 'label', 'type', 'color', 'positions', 'mappings', 'description', 'actions')
279 empty_text = "None"
282class RearPortTemplateTable(ComponentTemplateTable):
283 color = columns.ColorColumn(
284 verbose_name=_('Color'),
285 )
286 mappings = columns.ManyToManyColumn(
287 verbose_name=_('Mappings'),
288 transform=lambda obj: f'{obj.front_port}:{obj.front_port_position}'
289 )
290 actions = columns.ActionsColumn(
291 actions=('edit', 'delete'),
292 extra_buttons=MODULAR_COMPONENT_TEMPLATE_BUTTONS
293 )
295 class Meta(ComponentTemplateTable.Meta):
296 model = models.RearPortTemplate
297 fields = ('pk', 'name', 'label', 'type', 'color', 'positions', 'mappings', 'description', 'actions')
298 empty_text = "None"
301class ModuleBayTemplateTable(ComponentTemplateTable):
302 enabled = columns.BooleanColumn(
303 verbose_name=_('Enabled'),
304 )
305 module_bay_types = columns.ManyToManyColumn(
306 verbose_name=_('Bay Types'),
307 linkify_item=True,
308 )
309 actions = columns.ActionsColumn(
310 actions=('edit', 'delete')
311 )
313 class Meta(ComponentTemplateTable.Meta):
314 model = models.ModuleBayTemplate
315 fields = ('pk', 'name', 'label', 'position', 'enabled', 'module_bay_types', 'description', 'actions')
316 empty_text = "None"
319class DeviceBayTemplateTable(ComponentTemplateTable):
320 enabled = columns.BooleanColumn(
321 verbose_name=_('Enabled'),
322 )
323 actions = columns.ActionsColumn(
324 actions=('edit', 'delete')
325 )
327 class Meta(ComponentTemplateTable.Meta):
328 model = models.DeviceBayTemplate
329 fields = ('pk', 'name', 'label', 'enabled', 'description', 'actions')
330 empty_text = "None"
333class InventoryItemTemplateTable(ComponentTemplateTable):
334 actions = columns.ActionsColumn(
335 actions=('edit', 'delete')
336 )
337 role = tables.Column(
338 verbose_name=_('Role'),
339 linkify=True
340 )
341 manufacturer = tables.Column(
342 verbose_name=_('Manufacturer'),
343 linkify=True
344 )
345 component = tables.Column(
346 verbose_name=_('Component'),
347 orderable=False
348 )
350 class Meta(ComponentTemplateTable.Meta):
351 model = models.InventoryItemTemplate
352 fields = (
353 'pk', 'name', 'label', 'parent', 'role', 'manufacturer', 'part_id', 'component', 'description', 'actions',
354 )
355 empty_text = "None"