nested_serializers.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. from drf_spectacular.utils import extend_schema_serializer
  2. from rest_framework import serializers
  3. from dcim import models
  4. from netbox.api.fields import RelatedObjectCountField
  5. from netbox.api.serializers import WritableNestedSerializer
  6. __all__ = [
  7. 'NestedCableSerializer',
  8. 'NestedConsolePortSerializer',
  9. 'NestedConsolePortTemplateSerializer',
  10. 'NestedConsoleServerPortSerializer',
  11. 'NestedConsoleServerPortTemplateSerializer',
  12. 'NestedDeviceBaySerializer',
  13. 'NestedDeviceBayTemplateSerializer',
  14. 'NestedDeviceRoleSerializer',
  15. 'NestedDeviceSerializer',
  16. 'NestedDeviceTypeSerializer',
  17. 'NestedFrontPortSerializer',
  18. 'NestedFrontPortTemplateSerializer',
  19. 'NestedInterfaceSerializer',
  20. 'NestedInterfaceTemplateSerializer',
  21. 'NestedInventoryItemSerializer',
  22. 'NestedInventoryItemRoleSerializer',
  23. 'NestedInventoryItemTemplateSerializer',
  24. 'NestedManufacturerSerializer',
  25. 'NestedModuleBaySerializer',
  26. 'NestedModuleBayTemplateSerializer',
  27. 'NestedModuleSerializer',
  28. 'NestedModuleTypeSerializer',
  29. 'NestedPlatformSerializer',
  30. 'NestedPowerFeedSerializer',
  31. 'NestedPowerOutletSerializer',
  32. 'NestedPowerOutletTemplateSerializer',
  33. 'NestedPowerPanelSerializer',
  34. 'NestedPowerPortSerializer',
  35. 'NestedPowerPortTemplateSerializer',
  36. 'NestedLocationSerializer',
  37. 'NestedRackReservationSerializer',
  38. 'NestedRackRoleSerializer',
  39. 'NestedRackSerializer',
  40. 'NestedRearPortSerializer',
  41. 'NestedRearPortTemplateSerializer',
  42. 'NestedRegionSerializer',
  43. 'NestedSiteSerializer',
  44. 'NestedSiteGroupSerializer',
  45. 'NestedVirtualChassisSerializer',
  46. 'NestedVirtualDeviceContextSerializer',
  47. ]
  48. #
  49. # Regions/sites
  50. #
  51. @extend_schema_serializer(
  52. exclude_fields=('site_count',),
  53. )
  54. class NestedRegionSerializer(WritableNestedSerializer):
  55. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:region-detail')
  56. site_count = serializers.IntegerField(read_only=True)
  57. _depth = serializers.IntegerField(source='level', read_only=True)
  58. class Meta:
  59. model = models.Region
  60. fields = ['id', 'url', 'display', 'name', 'slug', 'site_count', '_depth']
  61. @extend_schema_serializer(
  62. exclude_fields=('site_count',),
  63. )
  64. class NestedSiteGroupSerializer(WritableNestedSerializer):
  65. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:sitegroup-detail')
  66. site_count = serializers.IntegerField(read_only=True)
  67. _depth = serializers.IntegerField(source='level', read_only=True)
  68. class Meta:
  69. model = models.SiteGroup
  70. fields = ['id', 'url', 'display', 'name', 'slug', 'site_count', '_depth']
  71. class NestedSiteSerializer(WritableNestedSerializer):
  72. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:site-detail')
  73. class Meta:
  74. model = models.Site
  75. fields = ['id', 'url', 'display', 'name', 'slug']
  76. #
  77. # Racks
  78. #
  79. @extend_schema_serializer(
  80. exclude_fields=('rack_count',),
  81. )
  82. class NestedLocationSerializer(WritableNestedSerializer):
  83. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:location-detail')
  84. rack_count = serializers.IntegerField(read_only=True)
  85. _depth = serializers.IntegerField(source='level', read_only=True)
  86. class Meta:
  87. model = models.Location
  88. fields = ['id', 'url', 'display', 'name', 'slug', 'rack_count', '_depth']
  89. @extend_schema_serializer(
  90. exclude_fields=('rack_count',),
  91. )
  92. class NestedRackRoleSerializer(WritableNestedSerializer):
  93. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackrole-detail')
  94. rack_count = RelatedObjectCountField('racks')
  95. class Meta:
  96. model = models.RackRole
  97. fields = ['id', 'url', 'display', 'name', 'slug', 'rack_count']
  98. @extend_schema_serializer(
  99. exclude_fields=('device_count',),
  100. )
  101. class NestedRackSerializer(WritableNestedSerializer):
  102. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rack-detail')
  103. device_count = RelatedObjectCountField('devices')
  104. class Meta:
  105. model = models.Rack
  106. fields = ['id', 'url', 'display', 'name', 'device_count']
  107. class NestedRackReservationSerializer(WritableNestedSerializer):
  108. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackreservation-detail')
  109. user = serializers.SerializerMethodField(read_only=True)
  110. class Meta:
  111. model = models.RackReservation
  112. fields = ['id', 'url', 'display', 'user', 'units']
  113. def get_user(self, obj):
  114. return obj.user.username
  115. #
  116. # Device/module types
  117. #
  118. @extend_schema_serializer(
  119. exclude_fields=('devicetype_count',),
  120. )
  121. class NestedManufacturerSerializer(WritableNestedSerializer):
  122. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:manufacturer-detail')
  123. devicetype_count = RelatedObjectCountField('device_types')
  124. class Meta:
  125. model = models.Manufacturer
  126. fields = ['id', 'url', 'display', 'name', 'slug', 'devicetype_count']
  127. @extend_schema_serializer(
  128. exclude_fields=('device_count',),
  129. )
  130. class NestedDeviceTypeSerializer(WritableNestedSerializer):
  131. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicetype-detail')
  132. manufacturer = NestedManufacturerSerializer(read_only=True)
  133. device_count = RelatedObjectCountField('instances')
  134. class Meta:
  135. model = models.DeviceType
  136. fields = ['id', 'url', 'display', 'manufacturer', 'model', 'slug', 'device_count']
  137. class NestedModuleTypeSerializer(WritableNestedSerializer):
  138. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:moduletype-detail')
  139. manufacturer = NestedManufacturerSerializer(read_only=True)
  140. class Meta:
  141. model = models.ModuleType
  142. fields = ['id', 'url', 'display', 'manufacturer', 'model']
  143. #
  144. # Component templates
  145. #
  146. class NestedConsolePortTemplateSerializer(WritableNestedSerializer):
  147. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleporttemplate-detail')
  148. class Meta:
  149. model = models.ConsolePortTemplate
  150. fields = ['id', 'url', 'display', 'name']
  151. class NestedConsoleServerPortTemplateSerializer(WritableNestedSerializer):
  152. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleserverporttemplate-detail')
  153. class Meta:
  154. model = models.ConsoleServerPortTemplate
  155. fields = ['id', 'url', 'display', 'name']
  156. class NestedPowerPortTemplateSerializer(WritableNestedSerializer):
  157. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerporttemplate-detail')
  158. class Meta:
  159. model = models.PowerPortTemplate
  160. fields = ['id', 'url', 'display', 'name']
  161. class NestedPowerOutletTemplateSerializer(WritableNestedSerializer):
  162. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:poweroutlettemplate-detail')
  163. class Meta:
  164. model = models.PowerOutletTemplate
  165. fields = ['id', 'url', 'display', 'name']
  166. class NestedInterfaceTemplateSerializer(WritableNestedSerializer):
  167. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interfacetemplate-detail')
  168. class Meta:
  169. model = models.InterfaceTemplate
  170. fields = ['id', 'url', 'display', 'name']
  171. class NestedRearPortTemplateSerializer(WritableNestedSerializer):
  172. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearporttemplate-detail')
  173. class Meta:
  174. model = models.RearPortTemplate
  175. fields = ['id', 'url', 'display', 'name']
  176. class NestedFrontPortTemplateSerializer(WritableNestedSerializer):
  177. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:frontporttemplate-detail')
  178. class Meta:
  179. model = models.FrontPortTemplate
  180. fields = ['id', 'url', 'display', 'name']
  181. class NestedModuleBayTemplateSerializer(WritableNestedSerializer):
  182. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:modulebaytemplate-detail')
  183. class Meta:
  184. model = models.ModuleBayTemplate
  185. fields = ['id', 'url', 'display', 'name']
  186. class NestedDeviceBayTemplateSerializer(WritableNestedSerializer):
  187. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicebaytemplate-detail')
  188. class Meta:
  189. model = models.DeviceBayTemplate
  190. fields = ['id', 'url', 'display', 'name']
  191. class NestedInventoryItemTemplateSerializer(WritableNestedSerializer):
  192. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:inventoryitemtemplate-detail')
  193. _depth = serializers.IntegerField(source='level', read_only=True)
  194. class Meta:
  195. model = models.InventoryItemTemplate
  196. fields = ['id', 'url', 'display', 'name', '_depth']
  197. #
  198. # Devices
  199. #
  200. @extend_schema_serializer(
  201. exclude_fields=('device_count', 'virtualmachine_count'),
  202. )
  203. class NestedDeviceRoleSerializer(WritableNestedSerializer):
  204. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicerole-detail')
  205. device_count = RelatedObjectCountField('devices')
  206. virtualmachine_count = RelatedObjectCountField('virtual_machines')
  207. class Meta:
  208. model = models.DeviceRole
  209. fields = ['id', 'url', 'display', 'name', 'slug', 'device_count', 'virtualmachine_count']
  210. @extend_schema_serializer(
  211. exclude_fields=('device_count', 'virtualmachine_count'),
  212. )
  213. class NestedPlatformSerializer(WritableNestedSerializer):
  214. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:platform-detail')
  215. device_count = RelatedObjectCountField('devices')
  216. virtualmachine_count = RelatedObjectCountField('virtual_machines')
  217. class Meta:
  218. model = models.Platform
  219. fields = ['id', 'url', 'display', 'name', 'slug', 'device_count', 'virtualmachine_count']
  220. class NestedDeviceSerializer(WritableNestedSerializer):
  221. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:device-detail')
  222. class Meta:
  223. model = models.Device
  224. fields = ['id', 'url', 'display', 'name']
  225. class ModuleNestedModuleBaySerializer(WritableNestedSerializer):
  226. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:modulebay-detail')
  227. class Meta:
  228. model = models.ModuleBay
  229. fields = ['id', 'url', 'display', 'name']
  230. class ModuleBayNestedModuleSerializer(WritableNestedSerializer):
  231. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:module-detail')
  232. class Meta:
  233. model = models.Module
  234. fields = ['id', 'url', 'display', 'serial']
  235. class NestedModuleSerializer(WritableNestedSerializer):
  236. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:module-detail')
  237. device = NestedDeviceSerializer(read_only=True)
  238. module_bay = ModuleNestedModuleBaySerializer(read_only=True)
  239. module_type = NestedModuleTypeSerializer(read_only=True)
  240. class Meta:
  241. model = models.Module
  242. fields = ['id', 'url', 'display', 'device', 'module_bay', 'module_type']
  243. class NestedConsoleServerPortSerializer(WritableNestedSerializer):
  244. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleserverport-detail')
  245. device = NestedDeviceSerializer(read_only=True)
  246. _occupied = serializers.BooleanField(required=False, read_only=True)
  247. class Meta:
  248. model = models.ConsoleServerPort
  249. fields = ['id', 'url', 'display', 'device', 'name', 'cable', '_occupied']
  250. class NestedConsolePortSerializer(WritableNestedSerializer):
  251. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleport-detail')
  252. device = NestedDeviceSerializer(read_only=True)
  253. _occupied = serializers.BooleanField(required=False, read_only=True)
  254. class Meta:
  255. model = models.ConsolePort
  256. fields = ['id', 'url', 'display', 'device', 'name', 'cable', '_occupied']
  257. class NestedPowerOutletSerializer(WritableNestedSerializer):
  258. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:poweroutlet-detail')
  259. device = NestedDeviceSerializer(read_only=True)
  260. _occupied = serializers.BooleanField(required=False, read_only=True)
  261. class Meta:
  262. model = models.PowerOutlet
  263. fields = ['id', 'url', 'display', 'device', 'name', 'cable', '_occupied']
  264. class NestedPowerPortSerializer(WritableNestedSerializer):
  265. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerport-detail')
  266. device = NestedDeviceSerializer(read_only=True)
  267. _occupied = serializers.BooleanField(required=False, read_only=True)
  268. class Meta:
  269. model = models.PowerPort
  270. fields = ['id', 'url', 'display', 'device', 'name', 'cable', '_occupied']
  271. class NestedInterfaceSerializer(WritableNestedSerializer):
  272. device = NestedDeviceSerializer(read_only=True)
  273. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail')
  274. _occupied = serializers.BooleanField(required=False, read_only=True)
  275. class Meta:
  276. model = models.Interface
  277. fields = ['id', 'url', 'display', 'device', 'name', 'cable', '_occupied']
  278. class NestedRearPortSerializer(WritableNestedSerializer):
  279. device = NestedDeviceSerializer(read_only=True)
  280. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearport-detail')
  281. _occupied = serializers.BooleanField(required=False, read_only=True)
  282. class Meta:
  283. model = models.RearPort
  284. fields = ['id', 'url', 'display', 'device', 'name', 'cable', '_occupied']
  285. class NestedFrontPortSerializer(WritableNestedSerializer):
  286. device = NestedDeviceSerializer(read_only=True)
  287. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:frontport-detail')
  288. _occupied = serializers.BooleanField(required=False, read_only=True)
  289. class Meta:
  290. model = models.FrontPort
  291. fields = ['id', 'url', 'display', 'device', 'name', 'cable', '_occupied']
  292. class NestedModuleBaySerializer(WritableNestedSerializer):
  293. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:modulebay-detail')
  294. installed_module = ModuleBayNestedModuleSerializer(required=False, allow_null=True)
  295. class Meta:
  296. model = models.ModuleBay
  297. fields = ['id', 'url', 'display', 'installed_module', 'name']
  298. class NestedDeviceBaySerializer(WritableNestedSerializer):
  299. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicebay-detail')
  300. device = NestedDeviceSerializer(read_only=True)
  301. class Meta:
  302. model = models.DeviceBay
  303. fields = ['id', 'url', 'display', 'device', 'name']
  304. class NestedInventoryItemSerializer(WritableNestedSerializer):
  305. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:inventoryitem-detail')
  306. device = NestedDeviceSerializer(read_only=True)
  307. _depth = serializers.IntegerField(source='level', read_only=True)
  308. class Meta:
  309. model = models.InventoryItem
  310. fields = ['id', 'url', 'display', 'device', 'name', '_depth']
  311. @extend_schema_serializer(
  312. exclude_fields=('inventoryitem_count',),
  313. )
  314. class NestedInventoryItemRoleSerializer(WritableNestedSerializer):
  315. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:inventoryitemrole-detail')
  316. inventoryitem_count = RelatedObjectCountField('inventory_items')
  317. class Meta:
  318. model = models.InventoryItemRole
  319. fields = ['id', 'url', 'display', 'name', 'slug', 'inventoryitem_count']
  320. #
  321. # Cables
  322. #
  323. class NestedCableSerializer(WritableNestedSerializer):
  324. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:cable-detail')
  325. class Meta:
  326. model = models.Cable
  327. fields = ['id', 'url', 'display', 'label']
  328. #
  329. # Virtual chassis
  330. #
  331. @extend_schema_serializer(
  332. exclude_fields=('member_count',),
  333. )
  334. class NestedVirtualChassisSerializer(WritableNestedSerializer):
  335. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:virtualchassis-detail')
  336. master = NestedDeviceSerializer()
  337. member_count = serializers.IntegerField(read_only=True)
  338. class Meta:
  339. model = models.VirtualChassis
  340. fields = ['id', 'url', 'display', 'name', 'master', 'member_count']
  341. #
  342. # Power panels/feeds
  343. #
  344. @extend_schema_serializer(
  345. exclude_fields=('powerfeed_count',),
  346. )
  347. class NestedPowerPanelSerializer(WritableNestedSerializer):
  348. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerpanel-detail')
  349. powerfeed_count = RelatedObjectCountField('powerfeeds')
  350. class Meta:
  351. model = models.PowerPanel
  352. fields = ['id', 'url', 'display', 'name', 'powerfeed_count']
  353. class NestedPowerFeedSerializer(WritableNestedSerializer):
  354. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerfeed-detail')
  355. _occupied = serializers.BooleanField(required=False, read_only=True)
  356. class Meta:
  357. model = models.PowerFeed
  358. fields = ['id', 'url', 'display', 'name', 'cable', '_occupied']
  359. class NestedVirtualDeviceContextSerializer(WritableNestedSerializer):
  360. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:virtualdevicecontext-detail')
  361. device = NestedDeviceSerializer()
  362. class Meta:
  363. model = models.VirtualDeviceContext
  364. fields = ['id', 'url', 'display', 'name', 'identifier', 'device']