Coverage for dcim/api/serializers_/racks.py: 99%
82 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
1from django.utils.translation import gettext as _
2from drf_spectacular.types import OpenApiTypes
3from drf_spectacular.utils import extend_schema_field
4from rest_framework import serializers
6from dcim.choices import *
7from dcim.constants import *
8from dcim.models import Rack, RackGroup, RackReservation, RackRole, RackType
9from netbox.api.fields import ChoiceField, RelatedObjectCountField
10from netbox.api.serializers import OrganizationalModelSerializer, PrimaryModelSerializer
11from netbox.choices import *
12from netbox.config import ConfigItem
13from tenancy.api.serializers_.tenants import TenantSerializer
14from users.api.serializers_.users import UserSerializer
16from .manufacturers import ManufacturerSerializer
17from .sites import LocationSerializer, SiteSerializer
19__all__ = (
20 'RackElevationDetailFilterSerializer',
21 'RackGroupSerializer',
22 'RackReservationSerializer',
23 'RackRoleSerializer',
24 'RackSerializer',
25 'RackTypeSerializer',
26)
29class RackGroupSerializer(OrganizationalModelSerializer):
31 # Related object counts
32 rack_count = RelatedObjectCountField('racks')
34 class Meta:
35 model = RackGroup
36 fields = [
37 'id', 'url', 'display_url', 'display', 'name', 'slug', 'description', 'owner', 'comments', 'tags',
38 'custom_fields', 'created', 'last_updated', 'rack_count',
39 ]
40 brief_fields = ('id', 'url', 'display', 'name', 'slug', 'description', 'rack_count')
43class RackRoleSerializer(OrganizationalModelSerializer):
45 # Related object counts
46 rack_count = RelatedObjectCountField('racks')
48 class Meta:
49 model = RackRole
50 fields = [
51 'id', 'url', 'display_url', 'display', 'name', 'slug', 'color', 'description', 'owner', 'comments', 'tags',
52 'custom_fields', 'created', 'last_updated', 'rack_count',
53 ]
54 brief_fields = ('id', 'url', 'display', 'name', 'slug', 'description', 'rack_count')
57class RackBaseSerializer(PrimaryModelSerializer):
58 form_factor = ChoiceField(
59 choices=RackFormFactorChoices,
60 allow_blank=True,
61 required=False,
62 allow_null=True
63 )
64 width = ChoiceField(
65 choices=RackWidthChoices,
66 required=False
67 )
68 outer_unit = ChoiceField(
69 choices=RackDimensionUnitChoices,
70 allow_blank=True,
71 required=False,
72 allow_null=True
73 )
74 weight_unit = ChoiceField(
75 choices=WeightUnitChoices,
76 allow_blank=True,
77 required=False,
78 allow_null=True
79 )
80 cooling_capability = ChoiceField(
81 choices=RackCoolingCapabilityChoices,
82 allow_blank=True,
83 required=False,
84 allow_null=True
85 )
88class RackTypeSerializer(RackBaseSerializer):
89 # Unlike Rack.form_factor (optional & nullable), RackType.form_factor is required
90 # (blank=False, no default), so override RackBaseSerializer's optional declaration.
91 form_factor = ChoiceField(choices=RackFormFactorChoices, required=True)
92 manufacturer = ManufacturerSerializer(nested=True)
93 rack_count = serializers.IntegerField(read_only=True)
95 class Meta:
96 model = RackType
97 fields = [
98 'id', 'url', 'display_url', 'display', 'manufacturer', 'model', 'slug', 'description', 'form_factor',
99 'width', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_height', 'outer_depth',
100 'outer_unit', 'weight', 'max_weight', 'weight_unit', 'mounting_depth', 'cooling_capability',
101 'cooling_capacity', 'description', 'owner', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
102 'rack_count',
103 ]
104 brief_fields = ('id', 'url', 'display', 'manufacturer', 'model', 'slug', 'description', 'rack_count')
107class RackSerializer(RackBaseSerializer):
108 site = SiteSerializer(
109 nested=True
110 )
111 location = LocationSerializer(
112 nested=True,
113 required=False,
114 allow_null=True,
115 default=None
116 )
117 group = RackGroupSerializer(
118 nested=True,
119 required=False,
120 allow_null=True
121 )
122 tenant = TenantSerializer(
123 nested=True,
124 required=False,
125 allow_null=True
126 )
127 status = ChoiceField(
128 choices=RackStatusChoices,
129 required=False
130 )
131 airflow = ChoiceField(
132 choices=RackAirflowChoices,
133 allow_blank=True,
134 required=False
135 )
136 role = RackRoleSerializer(
137 nested=True,
138 required=False,
139 allow_null=True
140 )
141 facility_id = serializers.CharField(
142 max_length=50,
143 allow_blank=True,
144 allow_null=True,
145 label=_('Facility ID'),
146 default=None
147 )
148 rack_type = RackTypeSerializer(
149 nested=True,
150 required=False,
151 allow_null=True,
152 default=None
153 )
155 # Related object counts
156 device_count = RelatedObjectCountField('devices')
157 powerfeed_count = RelatedObjectCountField('powerfeeds')
159 class Meta:
160 model = Rack
161 fields = [
162 'id', 'url', 'display_url', 'display', 'name', 'facility_id', 'site', 'location', 'group', 'tenant',
163 'status', 'role', 'serial', 'asset_tag', 'rack_type', 'form_factor', 'width', 'u_height', 'starting_unit',
164 'weight', 'max_weight', 'weight_unit', 'desc_units', 'outer_width', 'outer_height', 'outer_depth',
165 'outer_unit', 'mounting_depth', 'airflow', 'cooling_capability', 'cooling_capacity',
166 'description', 'owner', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'device_count',
167 'powerfeed_count',
168 ]
169 brief_fields = ('id', 'url', 'display', 'name', 'description', 'device_count')
172class RackReservationSerializer(PrimaryModelSerializer):
173 rack = RackSerializer(
174 nested=True,
175 )
176 status = ChoiceField(
177 choices=RackReservationStatusChoices,
178 required=False,
179 )
180 user = UserSerializer(
181 nested=True,
182 )
183 tenant = TenantSerializer(
184 nested=True,
185 required=False,
186 allow_null=True,
187 )
189 unit_count = serializers.SerializerMethodField()
191 @extend_schema_field(OpenApiTypes.INT32)
192 def get_unit_count(self, obj):
193 return len(obj.units)
195 class Meta:
196 model = RackReservation
197 fields = [
198 'id', 'url', 'display_url', 'display', 'rack', 'units', 'unit_count', 'status', 'created', 'last_updated',
199 'user', 'tenant', 'description', 'owner', 'comments', 'tags', 'custom_fields',
200 ]
201 brief_fields = ('id', 'url', 'display', 'status', 'user', 'description', 'units')
204class RackElevationDetailFilterSerializer(serializers.Serializer):
205 q = serializers.CharField(
206 required=False,
207 default=None
208 )
209 face = serializers.ChoiceField(
210 choices=DeviceFaceChoices,
211 default=DeviceFaceChoices.FACE_FRONT
212 )
213 render = serializers.ChoiceField(
214 choices=RackElevationDetailRenderChoices,
215 default=RackElevationDetailRenderChoices.RENDER_JSON
216 )
217 unit_width = serializers.IntegerField(
218 default=ConfigItem('RACK_ELEVATION_DEFAULT_UNIT_WIDTH')
219 )
220 unit_height = serializers.IntegerField(
221 default=ConfigItem('RACK_ELEVATION_DEFAULT_UNIT_HEIGHT')
222 )
223 legend_width = serializers.IntegerField(
224 default=RACK_ELEVATION_DEFAULT_LEGEND_WIDTH
225 )
226 margin_width = serializers.IntegerField(
227 default=RACK_ELEVATION_DEFAULT_MARGIN_WIDTH
228 )
229 exclude = serializers.IntegerField(
230 required=False,
231 default=None
232 )
233 expand_devices = serializers.BooleanField(
234 required=False,
235 default=True
236 )
237 include_images = serializers.BooleanField(
238 required=False,
239 default=True
240 )