nautobot 2.4.0__py3-none-any.whl → 2.4.0b1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of nautobot might be problematic. Click here for more details.

Files changed (592) hide show
  1. nautobot/apps/__init__.py +1 -1
  2. nautobot/apps/api.py +8 -8
  3. nautobot/apps/change_logging.py +2 -2
  4. nautobot/apps/choices.py +4 -4
  5. nautobot/apps/events.py +3 -3
  6. nautobot/apps/factory.py +2 -2
  7. nautobot/apps/filters.py +1 -1
  8. nautobot/apps/forms.py +20 -20
  9. nautobot/apps/graphql.py +2 -2
  10. nautobot/apps/jobs.py +8 -8
  11. nautobot/apps/models.py +19 -19
  12. nautobot/apps/tables.py +1 -1
  13. nautobot/apps/testing.py +10 -10
  14. nautobot/apps/ui.py +2 -2
  15. nautobot/apps/utils.py +7 -7
  16. nautobot/apps/views.py +7 -7
  17. nautobot/circuits/api/serializers.py +0 -1
  18. nautobot/circuits/api/views.py +8 -4
  19. nautobot/circuits/tables.py +1 -2
  20. nautobot/circuits/templates/circuits/circuit_create.html +7 -1
  21. nautobot/circuits/views.py +3 -3
  22. nautobot/cloud/api/views.py +10 -6
  23. nautobot/cloud/models.py +1 -1
  24. nautobot/cloud/views.py +16 -0
  25. nautobot/core/api/fields.py +5 -5
  26. nautobot/core/api/filter_backends.py +9 -3
  27. nautobot/core/api/schema.py +2 -13
  28. nautobot/core/api/serializers.py +34 -40
  29. nautobot/core/api/views.py +4 -56
  30. nautobot/core/celery/log.py +4 -4
  31. nautobot/core/celery/schedulers.py +1 -1
  32. nautobot/core/choices.py +2 -2
  33. nautobot/core/events/__init__.py +3 -3
  34. nautobot/core/filters.py +16 -21
  35. nautobot/core/fixtures/user-data.json +59 -0
  36. nautobot/core/forms/__init__.py +19 -19
  37. nautobot/core/forms/fields.py +11 -14
  38. nautobot/core/forms/forms.py +2 -33
  39. nautobot/core/graphql/types.py +1 -1
  40. nautobot/core/jobs/__init__.py +7 -28
  41. nautobot/core/jobs/cleanup.py +12 -48
  42. nautobot/core/jobs/groups.py +1 -1
  43. nautobot/core/management/commands/validate_models.py +1 -1
  44. nautobot/core/models/__init__.py +1 -1
  45. nautobot/core/models/query_functions.py +2 -2
  46. nautobot/core/models/tree_queries.py +3 -6
  47. nautobot/core/settings.py +2 -29
  48. nautobot/core/settings.yaml +0 -21
  49. nautobot/core/tables.py +60 -74
  50. nautobot/core/templates/inc/media.html +0 -3
  51. nautobot/core/templates/inc/nav_menu.html +0 -1
  52. nautobot/core/templates/nautobot_config.py.j2 +0 -13
  53. nautobot/core/templates/search.html +0 -7
  54. nautobot/core/templates/utilities/render_jinja2.html +1 -1
  55. nautobot/core/templates/utilities/templatetags/tag.html +1 -1
  56. nautobot/core/templates/utilities/theme_preview.html +0 -7
  57. nautobot/core/templatetags/helpers.py +2 -11
  58. nautobot/core/testing/__init__.py +8 -8
  59. nautobot/core/testing/api.py +15 -170
  60. nautobot/core/testing/filters.py +2 -25
  61. nautobot/core/testing/forms.py +0 -2
  62. nautobot/core/testing/mixins.py +2 -7
  63. nautobot/core/testing/views.py +29 -44
  64. nautobot/core/tests/integration/test_app_home.py +1 -0
  65. nautobot/core/tests/integration/test_app_navbar.py +1 -0
  66. nautobot/core/tests/integration/test_filters.py +2 -0
  67. nautobot/core/tests/integration/test_home.py +1 -0
  68. nautobot/core/tests/integration/test_navbar.py +1 -0
  69. nautobot/core/tests/integration/test_view_authentication.py +0 -1
  70. nautobot/core/tests/runner.py +1 -1
  71. nautobot/core/tests/test_api.py +1 -98
  72. nautobot/core/tests/test_csv.py +3 -25
  73. nautobot/core/tests/test_forms.py +0 -1
  74. nautobot/core/tests/test_jobs.py +1 -303
  75. nautobot/core/tests/test_settings_schema.py +0 -7
  76. nautobot/core/tests/test_tables.py +0 -100
  77. nautobot/core/tests/test_utils.py +1 -63
  78. nautobot/core/tests/test_views.py +3 -30
  79. nautobot/core/ui/nav.py +0 -1
  80. nautobot/core/ui/object_detail.py +1 -15
  81. nautobot/core/urls.py +0 -11
  82. nautobot/core/utils/lookup.py +8 -11
  83. nautobot/core/utils/requests.py +9 -24
  84. nautobot/core/views/__init__.py +0 -42
  85. nautobot/core/views/generic.py +176 -78
  86. nautobot/core/views/mixins.py +34 -94
  87. nautobot/core/views/renderers.py +6 -6
  88. nautobot/dcim/api/serializers.py +62 -54
  89. nautobot/dcim/api/views.py +113 -47
  90. nautobot/dcim/filters/__init__.py +2 -31
  91. nautobot/dcim/forms.py +17 -36
  92. nautobot/dcim/graphql/types.py +2 -2
  93. nautobot/dcim/models/__init__.py +1 -1
  94. nautobot/dcim/models/device_component_templates.py +2 -2
  95. nautobot/dcim/models/device_components.py +20 -22
  96. nautobot/dcim/models/devices.py +1 -10
  97. nautobot/dcim/models/locations.py +3 -3
  98. nautobot/dcim/models/power.py +5 -6
  99. nautobot/dcim/models/racks.py +4 -4
  100. nautobot/dcim/tables/__init__.py +3 -3
  101. nautobot/dcim/tables/devices.py +5 -7
  102. nautobot/dcim/tables/devicetypes.py +2 -2
  103. nautobot/dcim/tables/racks.py +1 -1
  104. nautobot/dcim/templates/dcim/controller_create.html +7 -1
  105. nautobot/dcim/templates/dcim/controller_retrieve.html +9 -1
  106. nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +0 -2
  107. nautobot/dcim/templates/dcim/controllermanageddevicegroup_retrieve.html +0 -5
  108. nautobot/dcim/templates/dcim/device.html +9 -1
  109. nautobot/dcim/templates/dcim/device_edit.html +37 -36
  110. nautobot/dcim/templates/dcim/location.html +9 -1
  111. nautobot/dcim/templates/dcim/location_edit.html +7 -1
  112. nautobot/dcim/templates/dcim/rack.html +9 -1
  113. nautobot/dcim/templates/dcim/rack_edit.html +7 -1
  114. nautobot/dcim/templates/dcim/rackreservation.html +9 -1
  115. nautobot/dcim/templates/dcim/virtualdevicecontext_retrieve.html +9 -1
  116. nautobot/dcim/templates/dcim/virtualdevicecontext_update.html +7 -1
  117. nautobot/dcim/tests/test_api.py +3 -16
  118. nautobot/dcim/tests/test_filters.py +0 -33
  119. nautobot/dcim/tests/test_forms.py +2 -51
  120. nautobot/dcim/tests/test_graphql.py +0 -52
  121. nautobot/dcim/tests/test_models.py +5 -34
  122. nautobot/dcim/tests/test_views.py +83 -21
  123. nautobot/dcim/views.py +13 -1
  124. nautobot/extras/api/customfields.py +2 -2
  125. nautobot/extras/api/serializers.py +85 -90
  126. nautobot/extras/api/views.py +27 -22
  127. nautobot/extras/constants.py +0 -2
  128. nautobot/extras/filters/__init__.py +6 -8
  129. nautobot/extras/forms/base.py +2 -2
  130. nautobot/extras/forms/forms.py +31 -139
  131. nautobot/extras/forms/mixins.py +5 -13
  132. nautobot/extras/group_sync.py +3 -3
  133. nautobot/extras/health_checks.py +2 -1
  134. nautobot/extras/jobs.py +12 -70
  135. nautobot/extras/managers.py +1 -3
  136. nautobot/extras/migrations/0018_joblog_data_migration.py +9 -7
  137. nautobot/extras/models/__init__.py +1 -1
  138. nautobot/extras/models/contacts.py +1 -1
  139. nautobot/extras/models/customfields.py +11 -12
  140. nautobot/extras/models/groups.py +9 -11
  141. nautobot/extras/models/jobs.py +4 -23
  142. nautobot/extras/models/models.py +2 -2
  143. nautobot/extras/plugins/__init__.py +2 -13
  144. nautobot/extras/plugins/marketplace_manifest.yml +79 -84
  145. nautobot/extras/plugins/tables.py +14 -16
  146. nautobot/extras/plugins/views.py +69 -65
  147. nautobot/extras/registry.py +1 -1
  148. nautobot/extras/secrets/__init__.py +2 -2
  149. nautobot/extras/tables.py +5 -7
  150. nautobot/extras/templates/extras/dynamicgroup.html +9 -1
  151. nautobot/extras/templates/extras/job_detail.html +0 -16
  152. nautobot/extras/templates/extras/job_edit.html +0 -1
  153. nautobot/extras/templates/extras/jobqueue_retrieve.html +9 -1
  154. nautobot/extras/templates/extras/marketplace.html +11 -29
  155. nautobot/extras/templates/extras/plugin_detail.html +15 -32
  156. nautobot/extras/templates/extras/plugins_tiles.html +10 -21
  157. nautobot/extras/test_jobs/api_test_job.py +1 -1
  158. nautobot/extras/test_jobs/atomic_transaction.py +2 -2
  159. nautobot/extras/test_jobs/dry_run.py +1 -1
  160. nautobot/extras/test_jobs/fail.py +5 -5
  161. nautobot/extras/test_jobs/file_output.py +1 -1
  162. nautobot/extras/test_jobs/file_upload_fail.py +1 -1
  163. nautobot/extras/test_jobs/file_upload_pass.py +1 -1
  164. nautobot/extras/test_jobs/ipaddress_vars.py +1 -3
  165. nautobot/extras/test_jobs/jobs_module/jobs_submodule/jobs.py +1 -1
  166. nautobot/extras/test_jobs/location_with_custom_field.py +1 -1
  167. nautobot/extras/test_jobs/log_redaction.py +1 -1
  168. nautobot/extras/test_jobs/log_skip_db_logging.py +1 -1
  169. nautobot/extras/test_jobs/modify_db.py +1 -1
  170. nautobot/extras/test_jobs/object_var_optional.py +1 -1
  171. nautobot/extras/test_jobs/object_var_required.py +1 -1
  172. nautobot/extras/test_jobs/object_vars.py +1 -1
  173. nautobot/extras/test_jobs/pass.py +3 -3
  174. nautobot/extras/test_jobs/profiling.py +1 -1
  175. nautobot/extras/test_jobs/relative_import.py +3 -3
  176. nautobot/extras/test_jobs/soft_time_limit_greater_than_time_limit.py +1 -1
  177. nautobot/extras/test_jobs/task_queues.py +1 -1
  178. nautobot/extras/tests/integration/test_plugin_banner.py +2 -0
  179. nautobot/extras/tests/test_api.py +13 -13
  180. nautobot/extras/tests/test_customfields.py +1 -1
  181. nautobot/extras/tests/test_datasources.py +1 -2
  182. nautobot/extras/tests/test_dynamicgroups.py +1 -1
  183. nautobot/extras/tests/test_filters.py +6 -6
  184. nautobot/extras/tests/test_forms.py +1 -20
  185. nautobot/extras/tests/test_jobs.py +19 -160
  186. nautobot/extras/tests/test_models.py +10 -10
  187. nautobot/extras/tests/test_plugins.py +9 -62
  188. nautobot/extras/tests/test_relationships.py +9 -120
  189. nautobot/extras/tests/test_views.py +191 -52
  190. nautobot/extras/utils.py +2 -3
  191. nautobot/extras/views.py +98 -30
  192. nautobot/ipam/api/fields.py +3 -3
  193. nautobot/ipam/api/serializers.py +33 -41
  194. nautobot/ipam/api/views.py +117 -68
  195. nautobot/ipam/factory.py +1 -1
  196. nautobot/ipam/filters.py +2 -3
  197. nautobot/ipam/lookups.py +62 -101
  198. nautobot/ipam/models.py +16 -66
  199. nautobot/ipam/querysets.py +2 -2
  200. nautobot/ipam/tables.py +7 -23
  201. nautobot/ipam/templates/ipam/ipaddress.html +9 -1
  202. nautobot/ipam/templates/ipam/ipaddress_bulk_add.html +7 -1
  203. nautobot/ipam/templates/ipam/ipaddress_edit.html +7 -1
  204. nautobot/ipam/templates/ipam/prefix.html +9 -1
  205. nautobot/ipam/templates/ipam/prefix_edit.html +7 -1
  206. nautobot/ipam/templates/ipam/vlan.html +9 -1
  207. nautobot/ipam/templates/ipam/vlan_edit.html +7 -1
  208. nautobot/ipam/templates/ipam/vrf_edit.html +7 -1
  209. nautobot/ipam/tests/test_api.py +3 -416
  210. nautobot/ipam/tests/test_forms.py +47 -49
  211. nautobot/ipam/tests/test_migrations.py +30 -30
  212. nautobot/ipam/tests/test_models.py +34 -95
  213. nautobot/ipam/tests/test_querysets.py +1 -63
  214. nautobot/ipam/tests/test_views.py +0 -3
  215. nautobot/ipam/utils/__init__.py +6 -36
  216. nautobot/ipam/views.py +87 -61
  217. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css.map +1 -1
  218. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css.map +1 -1
  219. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css +2 -40
  220. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css.map +1 -1
  221. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css +1 -1
  222. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css.map +1 -1
  223. nautobot/project-static/docs/404.html +4 -46
  224. nautobot/project-static/docs/apps/index.html +4 -46
  225. nautobot/project-static/docs/apps/nautobot-apps.html +6 -47
  226. nautobot/project-static/docs/assets/_mkdocstrings.css +1 -25
  227. nautobot/project-static/docs/assets/javascripts/{bundle.88dd0f4e.min.js → bundle.83f73b43.min.js} +2 -2
  228. nautobot/project-static/docs/assets/javascripts/{bundle.88dd0f4e.min.js.map → bundle.83f73b43.min.js.map} +2 -2
  229. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +10 -62
  230. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +7 -59
  231. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +122 -374
  232. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +18 -90
  233. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +21 -95
  234. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +6 -53
  235. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +5 -52
  236. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +17 -79
  237. nautobot/project-static/docs/code-reference/nautobot/apps/events.html +28 -102
  238. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +21 -108
  239. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +38 -131
  240. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +65 -239
  241. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +165 -581
  242. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +36 -109
  243. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +167 -453
  244. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +211 -493
  245. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +8 -60
  246. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +15 -71
  247. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +55 -407
  248. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +205 -585
  249. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +412 -858
  250. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +7 -59
  251. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +186 -448
  252. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +147 -365
  253. nautobot/project-static/docs/development/apps/api/configuration-view.html +4 -46
  254. nautobot/project-static/docs/development/apps/api/database-backend-config.html +4 -46
  255. nautobot/project-static/docs/development/apps/api/models/django-admin.html +4 -46
  256. nautobot/project-static/docs/development/apps/api/models/global-search.html +4 -46
  257. nautobot/project-static/docs/development/apps/api/models/graphql.html +4 -46
  258. nautobot/project-static/docs/development/apps/api/models/index.html +4 -46
  259. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +4 -46
  260. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +4 -46
  261. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +4 -46
  262. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +4 -46
  263. nautobot/project-static/docs/development/apps/api/platform-features/index.html +4 -46
  264. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +4 -46
  265. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +4 -46
  266. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +4 -46
  267. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +4 -46
  268. nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +7 -68
  269. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +4 -46
  270. nautobot/project-static/docs/development/apps/api/prometheus.html +4 -46
  271. nautobot/project-static/docs/development/apps/api/setup.html +4 -46
  272. nautobot/project-static/docs/development/apps/api/testing.html +4 -46
  273. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +4 -46
  274. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +4 -46
  275. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +4 -46
  276. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +4 -46
  277. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +4 -46
  278. nautobot/project-static/docs/development/apps/api/views/base-template.html +4 -46
  279. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +4 -46
  280. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +4 -46
  281. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +4 -46
  282. nautobot/project-static/docs/development/apps/api/views/index.html +4 -46
  283. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +4 -46
  284. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +4 -46
  285. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +4 -46
  286. nautobot/project-static/docs/development/apps/api/views/notes.html +4 -46
  287. nautobot/project-static/docs/development/apps/api/views/rest-api.html +6 -52
  288. nautobot/project-static/docs/development/apps/api/views/urls.html +4 -46
  289. nautobot/project-static/docs/development/apps/index.html +4 -46
  290. nautobot/project-static/docs/development/apps/migration/code-updates.html +4 -46
  291. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +4 -46
  292. nautobot/project-static/docs/development/apps/migration/from-v1.html +4 -46
  293. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +4 -46
  294. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +4 -46
  295. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +4 -46
  296. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +4 -46
  297. nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +8 -50
  298. nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +4 -46
  299. nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +14 -211
  300. nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +4 -46
  301. nautobot/project-static/docs/development/apps/porting-from-netbox.html +4 -46
  302. nautobot/project-static/docs/development/core/application-registry.html +4 -46
  303. nautobot/project-static/docs/development/core/best-practices.html +4 -46
  304. nautobot/project-static/docs/development/core/bootstrap-ui.html +4 -46
  305. nautobot/project-static/docs/development/core/caching.html +4 -46
  306. nautobot/project-static/docs/development/core/controllers.html +4 -46
  307. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +74 -73
  308. nautobot/project-static/docs/development/core/generic-views.html +4 -46
  309. nautobot/project-static/docs/development/core/getting-started.html +224 -249
  310. nautobot/project-static/docs/development/core/homepage.html +7 -49
  311. nautobot/project-static/docs/development/core/index.html +4 -46
  312. nautobot/project-static/docs/development/core/{minikube-dev-environment-for-k8s-jobs.html → local-k8s.html} +168 -469
  313. nautobot/project-static/docs/development/core/model-checklist.html +12 -56
  314. nautobot/project-static/docs/development/core/model-features.html +4 -46
  315. nautobot/project-static/docs/development/core/natural-keys.html +4 -46
  316. nautobot/project-static/docs/development/core/navigation-menu.html +4 -46
  317. nautobot/project-static/docs/development/core/release-checklist.html +7 -49
  318. nautobot/project-static/docs/development/core/role-internals.html +4 -46
  319. nautobot/project-static/docs/development/core/settings.html +4 -46
  320. nautobot/project-static/docs/development/core/style-guide.html +7 -49
  321. nautobot/project-static/docs/development/core/templates.html +4 -46
  322. nautobot/project-static/docs/development/core/testing.html +4 -46
  323. nautobot/project-static/docs/development/core/ui-component-framework.html +273 -369
  324. nautobot/project-static/docs/development/core/user-preferences.html +4 -46
  325. nautobot/project-static/docs/development/index.html +4 -46
  326. nautobot/project-static/docs/development/jobs/index.html +122 -216
  327. nautobot/project-static/docs/development/jobs/migration/from-v1.html +4 -46
  328. nautobot/project-static/docs/index.html +23 -54
  329. nautobot/project-static/docs/objects.inv +0 -0
  330. nautobot/project-static/docs/overview/application_stack.html +7 -47
  331. nautobot/project-static/docs/overview/design_philosophy.html +4 -46
  332. nautobot/project-static/docs/release-notes/index.html +12 -52
  333. nautobot/project-static/docs/release-notes/version-1.0.html +193 -234
  334. nautobot/project-static/docs/release-notes/version-1.1.html +190 -231
  335. nautobot/project-static/docs/release-notes/version-1.2.html +265 -306
  336. nautobot/project-static/docs/release-notes/version-1.3.html +291 -332
  337. nautobot/project-static/docs/release-notes/version-1.4.html +377 -417
  338. nautobot/project-static/docs/release-notes/version-1.5.html +566 -605
  339. nautobot/project-static/docs/release-notes/version-1.6.html +447 -904
  340. nautobot/project-static/docs/release-notes/version-2.0.html +489 -528
  341. nautobot/project-static/docs/release-notes/version-2.1.html +324 -363
  342. nautobot/project-static/docs/release-notes/version-2.2.html +317 -356
  343. nautobot/project-static/docs/release-notes/version-2.3.html +352 -997
  344. nautobot/project-static/docs/release-notes/version-2.4.html +101 -417
  345. nautobot/project-static/docs/requirements.txt +2 -2
  346. nautobot/project-static/docs/search/search_index.json +1 -1
  347. nautobot/project-static/docs/sitemap.xml +287 -295
  348. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  349. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +4 -46
  350. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +4 -46
  351. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +6 -48
  352. nautobot/project-static/docs/user-guide/administration/configuration/index.html +4 -46
  353. nautobot/project-static/docs/user-guide/administration/configuration/redis.html +4 -46
  354. nautobot/project-static/docs/user-guide/administration/configuration/settings.html +8 -110
  355. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +4 -46
  356. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +4 -46
  357. nautobot/project-static/docs/user-guide/administration/guides/docker.html +4 -46
  358. nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +4 -46
  359. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +4 -46
  360. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +4 -46
  361. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +4 -46
  362. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +4 -46
  363. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +6 -48
  364. nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +4 -46
  365. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +4 -46
  366. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +4 -46
  367. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +8 -66
  368. nautobot/project-static/docs/user-guide/administration/installation/index.html +4 -46
  369. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +5 -47
  370. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +4 -46
  371. nautobot/project-static/docs/user-guide/administration/installation/services.html +4 -46
  372. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +4 -46
  373. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +4 -46
  374. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +4 -46
  375. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +4 -46
  376. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +4 -46
  377. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +4 -46
  378. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +4 -46
  379. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +4 -46
  380. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +4 -46
  381. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +8 -49
  382. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +4 -46
  383. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +4 -46
  384. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +4 -46
  385. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +4 -46
  386. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +4 -46
  387. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +4 -46
  388. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +4 -46
  389. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +4 -46
  390. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +4 -46
  391. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +4 -46
  392. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +4 -46
  393. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +4 -46
  394. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +4 -46
  395. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +4 -46
  396. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +4 -46
  397. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +4 -46
  398. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +4 -46
  399. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +4 -46
  400. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +4 -46
  401. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +4 -46
  402. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +4 -46
  403. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +4 -46
  404. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +4 -46
  405. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +4 -46
  406. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +4 -46
  407. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +4 -46
  408. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +4 -46
  409. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +4 -46
  410. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +4 -46
  411. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +4 -46
  412. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +4 -46
  413. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +4 -46
  414. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +4 -46
  415. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +4 -46
  416. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +4 -46
  417. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +4 -46
  418. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +4 -46
  419. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +4 -46
  420. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +4 -46
  421. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +4 -46
  422. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +4 -46
  423. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +4 -46
  424. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +4 -46
  425. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +4 -46
  426. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +4 -46
  427. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +4 -46
  428. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +4 -46
  429. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +4 -46
  430. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +4 -46
  431. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +4 -46
  432. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +4 -46
  433. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +4 -46
  434. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +4 -46
  435. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +4 -46
  436. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +4 -46
  437. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +4 -46
  438. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +4 -46
  439. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +12 -50
  440. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +4 -46
  441. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +4 -46
  442. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +4 -46
  443. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +4 -46
  444. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +4 -46
  445. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +4 -46
  446. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +4 -46
  447. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +4 -46
  448. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +4 -46
  449. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +4 -46
  450. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +4 -46
  451. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +4 -46
  452. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +7 -49
  453. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +4 -46
  454. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +4 -46
  455. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +4 -46
  456. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +4 -46
  457. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +4 -46
  458. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +4 -46
  459. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +4 -46
  460. nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +4 -46
  461. nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +4 -46
  462. nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +4 -46
  463. nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +4 -46
  464. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +4 -46
  465. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +4 -46
  466. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +4 -46
  467. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +4 -46
  468. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +4 -46
  469. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +4 -46
  470. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +4 -46
  471. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +4 -46
  472. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +4 -46
  473. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +4 -46
  474. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +4 -46
  475. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +7 -51
  476. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +4 -46
  477. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +4 -46
  478. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +4 -46
  479. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +7 -49
  480. nautobot/project-static/docs/user-guide/index.html +4 -46
  481. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +4 -46
  482. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +8 -50
  483. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +4 -46
  484. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +4 -46
  485. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +4 -46
  486. nautobot/project-static/docs/user-guide/platform-functionality/events.html +4 -46
  487. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +4 -46
  488. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +4 -46
  489. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +4 -46
  490. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +4 -46
  491. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +4 -46
  492. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +4 -46
  493. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +7 -50
  494. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +4 -46
  495. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +7 -49
  496. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +4 -46
  497. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +4 -46
  498. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +4 -46
  499. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +4 -46
  500. nautobot/project-static/docs/user-guide/platform-functionality/note.html +4 -46
  501. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +4 -46
  502. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +5 -47
  503. nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +4 -46
  504. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +4 -46
  505. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +25 -94
  506. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +5 -74
  507. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +4 -46
  508. nautobot/project-static/docs/user-guide/platform-functionality/role.html +4 -46
  509. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +4 -46
  510. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +4 -46
  511. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +4 -46
  512. nautobot/project-static/docs/user-guide/platform-functionality/status.html +4 -46
  513. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +4 -46
  514. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +4 -46
  515. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +4 -46
  516. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +4 -46
  517. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +4 -46
  518. nautobot/project-static/js/forms.js +1 -1
  519. nautobot/tenancy/api/views.py +13 -9
  520. nautobot/tenancy/views.py +2 -4
  521. nautobot/users/admin.py +1 -1
  522. nautobot/users/api/serializers.py +4 -5
  523. nautobot/users/api/views.py +3 -3
  524. nautobot/virtualization/api/serializers.py +4 -4
  525. nautobot/virtualization/api/views.py +24 -5
  526. nautobot/virtualization/filters.py +3 -20
  527. nautobot/virtualization/models.py +1 -1
  528. nautobot/virtualization/tables.py +2 -2
  529. nautobot/virtualization/templates/virtualization/cluster_edit.html +7 -1
  530. nautobot/virtualization/templates/virtualization/virtualmachine.html +9 -1
  531. nautobot/virtualization/templates/virtualization/virtualmachine_edit.html +8 -2
  532. nautobot/virtualization/tests/test_filters.py +0 -17
  533. nautobot/wireless/filters.py +2 -2
  534. nautobot/wireless/forms.py +1 -1
  535. nautobot/wireless/templates/wireless/wirelessnetwork_retrieve.html +9 -1
  536. nautobot/wireless/tests/test_filters.py +1 -29
  537. nautobot/wireless/views.py +10 -0
  538. {nautobot-2.4.0.dist-info → nautobot-2.4.0b1.dist-info}/METADATA +6 -6
  539. {nautobot-2.4.0.dist-info → nautobot-2.4.0b1.dist-info}/RECORD +543 -591
  540. {nautobot-2.4.0.dist-info → nautobot-2.4.0b1.dist-info}/WHEEL +1 -1
  541. nautobot/core/api/constants.py +0 -11
  542. nautobot/core/jobs/bulk_actions.py +0 -248
  543. nautobot/core/templates/about.html +0 -67
  544. nautobot/core/templates/inc/tenancy_form_panel.html +0 -9
  545. nautobot/core/templates/inc/tenant_table_row.html +0 -11
  546. nautobot/core/utils/querysets.py +0 -64
  547. nautobot/dcim/migrations/0067_controllermanageddevicegroup_tenant.py +0 -25
  548. nautobot/dcim/tests/integration/test_controller.py +0 -62
  549. nautobot/dcim/tests/integration/test_controller_managed_device_group.py +0 -71
  550. nautobot/dcim/tests/test_jobs.py +0 -118
  551. nautobot/extras/migrations/0120_job_is_singleton_job_is_singleton_override.py +0 -22
  552. nautobot/extras/migrations/0121_alter_team_contacts.py +0 -17
  553. nautobot/extras/test_jobs/singleton.py +0 -16
  554. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_edit.png +0 -0
  555. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_edit_button.png +0 -0
  556. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_list_nav.png +0 -0
  557. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_list_view.png +0 -0
  558. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue.png +0 -0
  559. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue_add.png +0 -0
  560. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue_config.png +0 -0
  561. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_completed.png +0 -0
  562. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_nav.png +0 -0
  563. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_pending.png +0 -0
  564. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_run_form.png +0 -0
  565. nautobot/project-static/docs/media/development/core/kubernetes/k8s_nautobot_login.png +0 -0
  566. nautobot/project-static/docs/media/development/core/kubernetes/k8s_run_job.png +0 -0
  567. nautobot/project-static/docs/media/development/core/kubernetes/k8s_run_scheduled_job_form.png +0 -0
  568. nautobot/project-static/docs/media/development/core/kubernetes/k8s_scheduled_job_result.png +0 -0
  569. nautobot/project-static/docs/media/development/core/ui-component-framework/buttons-example.png +0 -0
  570. nautobot/project-static/docs/media/development/core/ui-component-framework/cluster-type-before-after-example.png +0 -0
  571. nautobot/project-static/docs/media/development/core/ui-component-framework/object-fields-panel-example_2.png +0 -0
  572. nautobot/project-static/docs/media/development/core/ui-component-framework/stats-panel-example-code.png +0 -0
  573. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/central-mode.png +0 -0
  574. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-add.png +0 -0
  575. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-create-1.png +0 -0
  576. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-create-2.png +0 -0
  577. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/radio-profile-add.png +0 -0
  578. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/radio-profile-create.png +0 -0
  579. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/supported-data-rate-add.png +0 -0
  580. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/supported-data-rate-create.png +0 -0
  581. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-add.png +0 -0
  582. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-create-1.png +0 -0
  583. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-create-2.png +0 -0
  584. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-network-add.png +0 -0
  585. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-network-create.png +0 -0
  586. nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +0 -9444
  587. nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +0 -9722
  588. nautobot/wireless/tests/integration/__init__.py +0 -0
  589. nautobot/wireless/tests/integration/test_radio_profile.py +0 -42
  590. {nautobot-2.4.0.dist-info → nautobot-2.4.0b1.dist-info}/LICENSE.txt +0 -0
  591. {nautobot-2.4.0.dist-info → nautobot-2.4.0b1.dist-info}/NOTICE +0 -0
  592. {nautobot-2.4.0.dist-info → nautobot-2.4.0b1.dist-info}/entry_points.txt +0 -0
@@ -1,5 +1,4 @@
1
1
  import logging
2
- from typing import ClassVar, Optional
3
2
 
4
3
  from django.contrib import messages
5
4
  from django.contrib.auth.mixins import AccessMixin
@@ -23,7 +22,6 @@ from django.utils.encoding import iri_to_uri
23
22
  from django.utils.html import format_html
24
23
  from django.utils.http import url_has_allowed_host_and_scheme
25
24
  from django.views.generic.edit import FormView
26
- from django_filters import FilterSet
27
25
  from drf_spectacular.utils import extend_schema
28
26
  from rest_framework import exceptions, mixins
29
27
  from rest_framework.decorators import action as drf_action
@@ -39,7 +37,6 @@ from nautobot.core.forms import (
39
37
  CSVFileField,
40
38
  restrict_form_fields,
41
39
  )
42
- from nautobot.core.jobs import BulkDeleteObjects, BulkEditObjects
43
40
  from nautobot.core.utils import lookup, permissions
44
41
  from nautobot.core.utils.requests import get_filterable_params_from_filter_params, normalize_querydict
45
42
  from nautobot.core.views.renderers import NautobotHTMLRenderer
@@ -51,7 +48,7 @@ from nautobot.core.views.utils import (
51
48
  )
52
49
  from nautobot.extras.context_managers import deferred_change_logging_for_bulk_operation
53
50
  from nautobot.extras.forms import NoteForm
54
- from nautobot.extras.models import ExportTemplate, Job, JobResult, SavedView, UserSavedViewAssociation
51
+ from nautobot.extras.models import ExportTemplate, SavedView, UserSavedViewAssociation
55
52
  from nautobot.extras.tables import NoteTable, ObjectChangeTable
56
53
  from nautobot.extras.utils import bulk_delete_with_bulk_change_logging, get_base_template, remove_prefix_from_cf_key
57
54
 
@@ -226,7 +223,7 @@ class NautobotViewSetMixin(GenericViewSet, AccessMixin, GetReturnURLMixin, FormV
226
223
  # filterset and filter_params will be initialized in filter_queryset() in ObjectListViewMixin
227
224
  filter_params = None
228
225
  filterset = None
229
- filterset_class: Optional[type[FilterSet]] = None
226
+ filterset_class = None
230
227
  filterset_form_class = None
231
228
  form_class = None
232
229
  create_form_class = None
@@ -476,11 +473,7 @@ class NautobotViewSetMixin(GenericViewSet, AccessMixin, GetReturnURLMixin, FormV
476
473
  def get_filter_params(self, request):
477
474
  """Helper function - take request.GET and discard any parameters that are not used for queryset filtering."""
478
475
  params = request.GET.copy()
479
- filter_params = get_filterable_params_from_filter_params(
480
- params,
481
- self.non_filter_params,
482
- self.filterset_class(), # pylint: disable=not-callable # only called if filterset_class is not None
483
- )
476
+ filter_params = get_filterable_params_from_filter_params(params, self.non_filter_params, self.filterset_class())
484
477
  if params.get("saved_view") and not filter_params and not params.get("all_filters_removed"):
485
478
  return SavedView.objects.get(pk=params.get("saved_view")).config.get("filter_params", {})
486
479
  return filter_params
@@ -586,11 +579,11 @@ class NautobotViewSetMixin(GenericViewSet, AccessMixin, GetReturnURLMixin, FormV
586
579
  if self.action == "bulk_destroy":
587
580
  queryset = self.get_queryset()
588
581
  bulk_delete_all = bool(self.request.POST.get("_all"))
582
+ if bulk_delete_all:
583
+ return ConfirmationForm
589
584
 
590
585
  class BulkDestroyForm(ConfirmationForm):
591
- pk = ModelMultipleChoiceField(
592
- queryset=queryset, widget=MultipleHiddenInput, required=not bulk_delete_all
593
- )
586
+ pk = ModelMultipleChoiceField(queryset=queryset, widget=MultipleHiddenInput)
594
587
 
595
588
  return BulkDestroyForm
596
589
  else:
@@ -636,8 +629,8 @@ class ObjectListViewMixin(NautobotViewSetMixin, mixins.ListModelMixin):
636
629
  """
637
630
 
638
631
  action_buttons = ("add", "import", "export")
639
- filterset_class: Optional[type[FilterSet]] = None
640
- filterset_form_class: Optional[type[Form]] = None
632
+ filterset_class = None
633
+ filterset_form_class = None
641
634
  hide_hierarchy_ui = False
642
635
  non_filter_params = (
643
636
  "export", # trigger for CSV/export-template/YAML export # 3.0 TODO: remove, irrelevant after #4746
@@ -787,8 +780,7 @@ class ObjectDestroyViewMixin(NautobotViewSetMixin, mixins.DestroyModelMixin):
787
780
  return self.perform_destroy(request, **kwargs)
788
781
  return Response(context)
789
782
 
790
- # TODO: this conflicts with DRF's DestroyModelMixin.perform_destroy(self, instance) API
791
- def perform_destroy(self, request, **kwargs): # pylint:disable=arguments-renamed
783
+ def perform_destroy(self, request, **kwargs):
792
784
  """
793
785
  Function to validate the ObjectDeleteConfirmationForm and to delete the object.
794
786
  """
@@ -920,9 +912,9 @@ class ObjectEditViewMixin(NautobotViewSetMixin, mixins.CreateModelMixin, mixins.
920
912
  return self.form_invalid(form)
921
913
 
922
914
 
923
- class BulkEditAndBulkDeleteModelMixin:
915
+ class EditAndDeleteAllModelMixin:
924
916
  """
925
- UI mixin to bulk destroy and bulk edit all model instances.
917
+ UI mixin to bulk destroy all and bulk edit all model instances.
926
918
  """
927
919
 
928
920
  def _get_bulk_edit_delete_all_queryset(self, request):
@@ -942,7 +934,7 @@ class BulkEditAndBulkDeleteModelMixin:
942
934
  filterset_class = getattr(self, "filterset_class", None)
943
935
 
944
936
  if request.GET and filterset_class is not None:
945
- queryset = filterset_class(request.GET, model.objects.all()).qs # pylint: disable=not-callable
937
+ queryset = filterset_class(request.GET, model.objects.all()).qs
946
938
  # We take this approach because filterset.qs has already applied .distinct(),
947
939
  # and performing a .delete directly on a queryset with .distinct applied is not allowed.
948
940
  queryset = self.queryset.filter(pk__in=queryset)
@@ -950,67 +942,24 @@ class BulkEditAndBulkDeleteModelMixin:
950
942
  queryset = model.objects.all()
951
943
  return queryset
952
944
 
953
- def send_bulk_delete_objects_to_job(self, request, pk_list, model, delete_all):
954
- """Prepare and enqueue bulk delete job."""
955
- job_model = Job.objects.get_for_class_path(BulkDeleteObjects.class_path)
956
-
957
- if filterset_class := lookup.get_filterset_for_model(model):
958
- filter_query_params = normalize_querydict(request.GET, filterset=filterset_class())
959
- else:
960
- filter_query_params = None
961
-
962
- job_form = BulkDeleteObjects.as_form(
963
- data={
964
- "pk_list": pk_list,
965
- "content_type": ContentType.objects.get_for_model(model),
966
- "delete_all": delete_all,
967
- "filter_query_params": filter_query_params,
968
- }
969
- )
970
- # BulkDeleteObjects job form cannot be invalid; Hence no handling of invalid case.
971
- job_form.is_valid()
972
- job_kwargs = BulkDeleteObjects.prepare_job_kwargs(job_form.cleaned_data)
973
- job_result = JobResult.enqueue_job(
974
- job_model,
975
- request.user,
976
- **BulkDeleteObjects.serialize_data(job_kwargs),
977
- )
978
- return redirect("extras:jobresult", pk=job_result.pk)
979
-
980
- def send_bulk_edit_objects_to_job(self, request, form, model):
981
- """Prepare and enqueue a bulk edit job."""
982
- job_model = Job.objects.get_for_class_path(BulkEditObjects.class_path)
983
- form_data = normalize_querydict(request.POST, form)
984
- if filterset_class := lookup.get_filterset_for_model(model):
985
- filter_query_params = normalize_querydict(request.GET, filterset=filterset_class())
986
- else:
987
- filter_query_params = None
988
- job_form = BulkEditObjects.as_form(
989
- data={
990
- "form_data": form_data,
991
- "content_type": ContentType.objects.get_for_model(model),
992
- "edit_all": request.POST.get("_all") is not None,
993
- "filter_query_params": filter_query_params,
994
- }
995
- )
996
- # NOTE: BulkEditObjects cant be invalid, so there is no need for handling invalid error
997
- job_form.is_valid()
998
- job_kwargs = BulkEditObjects.prepare_job_kwargs(job_form.cleaned_data)
999
- job_result = JobResult.enqueue_job(
1000
- job_model,
1001
- request.user,
1002
- **BulkEditObjects.serialize_data(job_kwargs),
1003
- )
1004
- return redirect("extras:jobresult", pk=job_result.pk)
945
+ def _bulk_delete_all_context(self, request, queryset):
946
+ model = queryset.model
947
+ return {
948
+ "obj_type_plural": model._meta.verbose_name_plural,
949
+ "return_url": self.get_return_url(request),
950
+ "total_objs_to_delete": queryset.count(),
951
+ "delete_all": True,
952
+ "table": None,
953
+ }
1005
954
 
1006
955
 
1007
- class ObjectBulkDestroyViewMixin(NautobotViewSetMixin, BulkDestroyModelMixin, BulkEditAndBulkDeleteModelMixin):
956
+ class ObjectBulkDestroyViewMixin(NautobotViewSetMixin, BulkDestroyModelMixin, EditAndDeleteAllModelMixin):
1008
957
  """
1009
958
  UI mixin to bulk destroy model instances.
1010
959
  """
1011
960
 
1012
- bulk_destroy_form_class: Optional[type[Form]] = None
1013
- filterset_class: Optional[type[FilterSet]] = None
961
+ bulk_destroy_form_class = None
962
+ filterset_class = None
1014
963
 
1015
964
  def _process_bulk_destroy_form(self, form):
1016
965
  request = self.request
@@ -1043,8 +992,7 @@ class ObjectBulkDestroyViewMixin(NautobotViewSetMixin, BulkDestroyModelMixin, Bu
1043
992
  """
1044
993
  return self.perform_bulk_destroy(request, **kwargs)
1045
994
 
1046
- # TODO: this conflicts with BulkDestroyModelMixin.perform_bulk_destroy(self, objects)
1047
- def perform_bulk_destroy(self, request, **kwargs): # pylint:disable=arguments-renamed
995
+ def perform_bulk_destroy(self, request, **kwargs):
1048
996
  """
1049
997
  request.POST "_delete": Function to render the user selection of objects in a table form/BulkDestroyConfirmationForm via Response that is passed to NautobotHTMLRenderer.
1050
998
  request.POST "_confirm": Function to validate the table form/BulkDestroyConfirmationForm and to perform the action of bulk destroy. Render the form with errors if exceptions are raised.
@@ -1054,23 +1002,21 @@ class ObjectBulkDestroyViewMixin(NautobotViewSetMixin, BulkDestroyModelMixin, Bu
1054
1002
  data = {}
1055
1003
  # Are we deleting *all* objects in the queryset or just a selected subset?
1056
1004
  if delete_all:
1057
- self.pk_list = []
1058
1005
  queryset = self._get_bulk_edit_delete_all_queryset(self.request)
1006
+ data = self._bulk_delete_all_context(request, queryset)
1059
1007
  else:
1060
1008
  self.pk_list = list(request.POST.getlist("pk"))
1061
- queryset = queryset.filter(pk__in=self.pk_list)
1062
1009
 
1010
+ form_class = self.get_form_class(**kwargs)
1063
1011
  if "_confirm" in request.POST:
1064
- form_class = self.get_form_class(**kwargs)
1065
1012
  form = form_class(request.POST, initial=normalize_querydict(request.GET, form_class=form_class))
1066
1013
  if form.is_valid():
1067
- return self.send_bulk_delete_objects_to_job(request, self.pk_list, queryset.model, delete_all)
1014
+ return self.form_valid(form)
1068
1015
  else:
1069
1016
  return self.form_invalid(form)
1070
- table = None
1071
1017
  if not delete_all:
1072
1018
  table_class = self.get_table_class()
1073
- table = table_class(queryset, orderable=False)
1019
+ table = table_class(queryset.filter(pk__in=self.pk_list), orderable=False)
1074
1020
  if not table.rows:
1075
1021
  messages.warning(
1076
1022
  request,
@@ -1078,13 +1024,7 @@ class ObjectBulkDestroyViewMixin(NautobotViewSetMixin, BulkDestroyModelMixin, Bu
1078
1024
  )
1079
1025
  return redirect(self.get_return_url(request))
1080
1026
 
1081
- data.update(
1082
- {
1083
- "table": table,
1084
- "total_objs_to_delete": queryset.count(),
1085
- "delete_all": delete_all,
1086
- }
1087
- )
1027
+ data.update({"table": table})
1088
1028
  return Response(data)
1089
1029
 
1090
1030
 
@@ -1142,14 +1082,14 @@ class ObjectBulkCreateViewMixin(NautobotViewSetMixin): # 3.0 TODO: remove, unus
1142
1082
  return self.form_invalid(form)
1143
1083
 
1144
1084
 
1145
- class ObjectBulkUpdateViewMixin(NautobotViewSetMixin, BulkUpdateModelMixin, BulkEditAndBulkDeleteModelMixin):
1085
+ class ObjectBulkUpdateViewMixin(NautobotViewSetMixin, BulkUpdateModelMixin, EditAndDeleteAllModelMixin):
1146
1086
  """
1147
1087
  UI mixin to bulk update model instances.
1148
1088
  """
1149
1089
 
1150
- filterset_class: ClassVar[Optional[type[FilterSet]]] = None
1090
+ filterset_class = None
1091
+ bulk_update_form_class = None
1151
1092
 
1152
- # NOTE: Performing BulkEdit Objects has been moved to a system job, but the logic remains here to ensure backward compatibility.
1153
1093
  def _process_bulk_update_form(self, form):
1154
1094
  request = self.request
1155
1095
  queryset = self.get_queryset()
@@ -1260,7 +1200,7 @@ class ObjectBulkUpdateViewMixin(NautobotViewSetMixin, BulkUpdateModelMixin, Bulk
1260
1200
  form = form_class(queryset.model, request.POST, edit_all=edit_all)
1261
1201
  restrict_form_fields(form, request.user)
1262
1202
  if form.is_valid():
1263
- return self.send_bulk_edit_objects_to_job(self.request, form, queryset.model)
1203
+ return self.form_valid(form)
1264
1204
  else:
1265
1205
  return self.form_invalid(form)
1266
1206
  table = None
@@ -244,11 +244,12 @@ class NautobotHTMLRenderer(renderers.BrowsableAPIRenderer):
244
244
  restrict_form_fields(form, request.user)
245
245
  elif view.action == "bulk_destroy":
246
246
  pk_list = getattr(view, "pk_list", [])
247
- initial = {
248
- "pk": pk_list,
249
- "return_url": return_url,
250
- }
251
- form = form_class(initial=initial)
247
+ if pk_list:
248
+ initial = {
249
+ "pk": pk_list,
250
+ "return_url": return_url,
251
+ }
252
+ form = form_class(initial=initial)
252
253
  delete_all = request.POST.get("_all")
253
254
  if not delete_all:
254
255
  table = self.construct_table(view, pk_list=pk_list)
@@ -346,7 +347,6 @@ class NautobotHTMLRenderer(renderers.BrowsableAPIRenderer):
346
347
  # Ensure the proper inheritance of context variables is applied: the view's returned data takes priority over the viewset's get_extra_context
347
348
  context.update(view.get_extra_context(request, instance))
348
349
  context.update(self.get_template_context(data, renderer_context))
349
-
350
350
  return context
351
351
 
352
352
  def render(self, data, accepted_media_type=None, renderer_context=None):
@@ -247,15 +247,15 @@ class LocationSerializer(
247
247
  # https://www.django-rest-framework.org/api-guide/validators/#optional-fields
248
248
  validators = []
249
249
 
250
- def validate(self, attrs):
250
+ def validate(self, data):
251
251
  # Validate uniqueness of (parent, name) since we omitted the automatically created validator from Meta.
252
- if attrs.get("parent") and attrs.get("name"):
252
+ if data.get("parent") and data.get("name"):
253
253
  validator = UniqueTogetherValidator(queryset=Location.objects.all(), fields=("parent", "name"))
254
- validator(attrs, self)
254
+ validator(data, self)
255
255
 
256
- super().validate(attrs)
256
+ super().validate(data)
257
257
 
258
- return attrs
258
+ return data
259
259
 
260
260
 
261
261
  #
@@ -285,20 +285,20 @@ class RackSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
285
285
  # This prevents facility_id and rack_group from being interpreted as required fields.
286
286
  validators = []
287
287
 
288
- def validate(self, attrs):
288
+ def validate(self, data):
289
289
  # Validate uniqueness of (rack_group, name) since we omitted the automatically-created validator above.
290
- if attrs.get("rack_group", None):
290
+ if data.get("rack_group", None):
291
291
  validator = UniqueTogetherValidator(queryset=Rack.objects.all(), fields=("rack_group", "name"))
292
- validator(attrs, self)
292
+ validator(data, self)
293
293
  # Validate uniqueness of (rack_group, facility_id) since we omitted the automatically-created validator above.
294
- if attrs.get("facility_id", None) and attrs.get("rack_group", None):
294
+ if data.get("facility_id", None) and data.get("rack_group", None):
295
295
  validator = UniqueTogetherValidator(queryset=Rack.objects.all(), fields=("rack_group", "facility_id"))
296
- validator(attrs, self)
296
+ validator(data, self)
297
297
 
298
298
  # Enforce model validation
299
- super().validate(attrs)
299
+ super().validate(data)
300
300
 
301
- return attrs
301
+ return data
302
302
 
303
303
 
304
304
  class RackUnitSerializer(serializers.Serializer):
@@ -369,7 +369,7 @@ class ManufacturerSerializer(NautobotModelSerializer):
369
369
  fields = "__all__"
370
370
 
371
371
 
372
- class DeviceFamilySerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
372
+ class DeviceFamilySerializer(NautobotModelSerializer):
373
373
  device_type_count = serializers.IntegerField(read_only=True)
374
374
 
375
375
  class Meta:
@@ -534,6 +534,14 @@ class DeviceSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
534
534
  "vc_priority": {"label": "Virtual chassis priority"},
535
535
  }
536
536
 
537
+ def get_additional_detail_view_tabs(self):
538
+ """Add "Virtual Chassis" as a separate detail tab."""
539
+ tabs = super().get_additional_detail_view_tabs()
540
+ tabs["Virtual Chassis"] = [
541
+ {"Virtual Chassis": {"fields": ["virtual_chassis", "vc_position", "vc_priority"]}},
542
+ ]
543
+ return tabs
544
+
537
545
  def get_field_names(self, declared_fields, info):
538
546
  """
539
547
  Add a couple of special fields to the serializer.
@@ -550,20 +558,20 @@ class DeviceSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
550
558
  def get_config_context(self, obj):
551
559
  return obj.get_config_context()
552
560
 
553
- def validate(self, attrs):
561
+ def validate(self, data):
554
562
  # Validate uniqueness of (rack, position, face) since we omitted the automatically-created validator from Meta.
555
- if attrs.get("rack") and attrs.get("position") and attrs.get("face"):
563
+ if data.get("rack") and data.get("position") and data.get("face"):
556
564
  validator = UniqueTogetherValidator(
557
565
  queryset=Device.objects.all(),
558
566
  fields=("rack", "position", "face"),
559
567
  message=f"The position and face is already occupied on this rack. {UniqueTogetherValidator.message}",
560
568
  )
561
- validator(attrs, self)
569
+ validator(data, self)
562
570
 
563
571
  # Enforce model validation
564
- super().validate(attrs)
572
+ super().validate(data)
565
573
 
566
- return attrs
574
+ return data
567
575
 
568
576
 
569
577
  class DeviceNAPALMSerializer(serializers.Serializer):
@@ -636,22 +644,22 @@ class PowerPortSerializer(
636
644
 
637
645
 
638
646
  class InterfaceCommonSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
639
- def validate(self, attrs):
647
+ def validate(self, data):
640
648
  # Validate many-to-many VLAN assignments
641
- mode = attrs.get("mode", getattr(self.instance, "mode", None))
649
+ mode = data.get("mode", getattr(self.instance, "mode", None))
642
650
 
643
651
  if mode != InterfaceModeChoices.MODE_TAGGED:
644
- if attrs.get("tagged_vlans"):
652
+ if data.get("tagged_vlans"):
645
653
  raise serializers.ValidationError(
646
654
  {
647
655
  "tagged_vlans": f"Mode must be set to {InterfaceModeChoices.MODE_TAGGED} when specifying tagged_vlans"
648
656
  }
649
657
  )
650
658
 
651
- if attrs.get("tagged_vlans") != [] and self.instance and self.instance.tagged_vlans.exists():
659
+ if data.get("tagged_vlans") != [] and self.instance and self.instance.tagged_vlans.exists():
652
660
  raise serializers.ValidationError({"tagged_vlans": f"Clear tagged_vlans to set mode to {mode}"})
653
661
 
654
- return super().validate(attrs)
662
+ return super().validate(data)
655
663
 
656
664
 
657
665
  class InterfaceSerializer(
@@ -663,7 +671,7 @@ class InterfaceSerializer(
663
671
  type = ChoiceField(choices=InterfaceTypeChoices)
664
672
  mode = ChoiceField(choices=InterfaceModeChoices, allow_blank=True, required=False)
665
673
  mac_address = serializers.CharField(allow_blank=True, allow_null=True, required=False)
666
- ip_address_count = serializers.IntegerField(read_only=True, source="_ip_address_count")
674
+ ip_address_count = serializers.IntegerField(read_only=True)
667
675
 
668
676
  class Meta:
669
677
  model = Interface
@@ -752,18 +760,18 @@ class InventoryItemSerializer(TaggedModelSerializerMixin, TreeModelSerializerMix
752
760
  # https://www.django-rest-framework.org/api-guide/validators/#optional-fields
753
761
  validators = []
754
762
 
755
- def validate(self, attrs):
763
+ def validate(self, data):
756
764
  # Validate uniqueness of (device, parent, name) since we omitted the automatically created validator from Meta.
757
- if attrs.get("device") and attrs.get("parent") and attrs.get("name"):
765
+ if data.get("device") and data.get("parent") and data.get("name"):
758
766
  validator = UniqueTogetherValidator(
759
767
  queryset=InventoryItem.objects.all(),
760
768
  fields=("device", "parent", "name"),
761
769
  )
762
- validator(attrs, self)
770
+ validator(data, self)
763
771
 
764
- super().validate(attrs)
772
+ super().validate(data)
765
773
 
766
- return attrs
774
+ return data
767
775
 
768
776
 
769
777
  #
@@ -1010,21 +1018,21 @@ class ModuleBaySerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
1010
1018
  fields = "__all__"
1011
1019
  validators = []
1012
1020
 
1013
- def validate(self, attrs):
1021
+ def validate(self, data):
1014
1022
  """Validate device and module field constraints for module bay."""
1015
- if attrs.get("parent_device") and attrs.get("parent_module"):
1023
+ if data.get("parent_device") and data.get("parent_module"):
1016
1024
  raise serializers.ValidationError("Only one of parent_device or parent_module must be set")
1017
- if attrs.get("parent_device"):
1025
+ if data.get("parent_device"):
1018
1026
  validator = UniqueTogetherValidator(
1019
1027
  queryset=self.Meta.model.objects.all(), fields=("parent_device", "name")
1020
1028
  )
1021
- validator(attrs, self)
1022
- if attrs.get("parent_module"):
1029
+ validator(data, self)
1030
+ if data.get("parent_module"):
1023
1031
  validator = UniqueTogetherValidator(
1024
1032
  queryset=self.Meta.model.objects.all(), fields=("parent_module", "name")
1025
1033
  )
1026
- validator(attrs, self)
1027
- return super().validate(attrs)
1034
+ validator(data, self)
1035
+ return super().validate(data)
1028
1036
 
1029
1037
 
1030
1038
  class ModuleBayTemplateSerializer(NautobotModelSerializer):
@@ -1033,17 +1041,17 @@ class ModuleBayTemplateSerializer(NautobotModelSerializer):
1033
1041
  fields = "__all__"
1034
1042
  validators = []
1035
1043
 
1036
- def validate(self, attrs):
1044
+ def validate(self, data):
1037
1045
  """Validate device_type and module_type field constraints for module bay template."""
1038
- if attrs.get("device_type") and attrs.get("module_type"):
1046
+ if data.get("device_type") and data.get("module_type"):
1039
1047
  raise serializers.ValidationError("Only one of device_type or module_type must be set")
1040
- if attrs.get("device_type"):
1048
+ if data.get("device_type"):
1041
1049
  validator = UniqueTogetherValidator(queryset=self.Meta.model.objects.all(), fields=("device_type", "name"))
1042
- validator(attrs, self)
1043
- if attrs.get("module_type"):
1050
+ validator(data, self)
1051
+ if data.get("module_type"):
1044
1052
  validator = UniqueTogetherValidator(queryset=self.Meta.model.objects.all(), fields=("module_type", "name"))
1045
- validator(attrs, self)
1046
- return super().validate(attrs)
1053
+ validator(data, self)
1054
+ return super().validate(data)
1047
1055
 
1048
1056
 
1049
1057
  class ModuleSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
@@ -1053,17 +1061,17 @@ class ModuleSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
1053
1061
 
1054
1062
  validators = []
1055
1063
 
1056
- def validate(self, attrs):
1064
+ def validate(self, data):
1057
1065
  """Validate asset_Tag, serial, parent_module_bay and location field constraints for module."""
1058
- if attrs.get("parent_module_bay") and attrs.get("location"):
1066
+ if data.get("parent_module_bay") and data.get("location"):
1059
1067
  raise serializers.ValidationError("Only one of parent_module_bay or location must be set")
1060
- if attrs.get("serial"):
1068
+ if data.get("serial"):
1061
1069
  validator = UniqueTogetherValidator(queryset=Module.objects.all(), fields=("module_type", "serial"))
1062
- validator(attrs, self)
1063
- if attrs.get("asset_tag"):
1070
+ validator(data, self)
1071
+ if data.get("asset_tag"):
1064
1072
  validator = UniqueValidator(queryset=Module.objects.all())
1065
- validator(attrs["asset_tag"], self.fields["asset_tag"])
1066
- return super().validate(attrs)
1073
+ validator(data["asset_tag"], self.fields["asset_tag"])
1074
+ return super().validate(data)
1067
1075
 
1068
1076
 
1069
1077
  class ModuleTypeSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
@@ -1072,16 +1080,16 @@ class ModuleTypeSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
1072
1080
  fields = "__all__"
1073
1081
 
1074
1082
 
1075
- class VirtualDeviceContextSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
1083
+ class VirtualDeviceContextSerializer(NautobotModelSerializer):
1076
1084
  class Meta:
1077
1085
  model = VirtualDeviceContext
1078
1086
  fields = "__all__"
1079
1087
 
1080
- def validate(self, attrs):
1088
+ def validate(self, data):
1081
1089
  """Validate device cannot be changed for VirtualDeviceContext."""
1082
- if attrs.get("device") and self.instance and self.instance.device != attrs.get("device"):
1090
+ if data.get("device") and self.instance and self.instance.device != data.get("device"):
1083
1091
  raise serializers.ValidationError("Changing the device of a VirtualDeviceContext is not allowed.")
1084
- return super().validate(attrs)
1092
+ return super().validate(data)
1085
1093
 
1086
1094
 
1087
1095
  class InterfaceVDCAssignmentSerializer(ValidatedModelSerializer):