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
nautobot/cloud/views.py CHANGED
@@ -100,6 +100,16 @@ class CloudNetworkUIViewSet(NautobotUIViewSet):
100
100
 
101
101
  return context
102
102
 
103
+ def extra_post_save_action(self, obj, form):
104
+ if form.cleaned_data.get("add_prefixes", None):
105
+ obj.prefixes.add(*form.cleaned_data["add_prefixes"])
106
+ if form.cleaned_data.get("remove_prefixes", None):
107
+ obj.prefixes.remove(*form.cleaned_data["remove_prefixes"])
108
+ if form.cleaned_data.get("add_cloud_services", None):
109
+ obj.cloud_services.add(*form.cleaned_data["add_cloud_services"])
110
+ if form.cleaned_data.get("remove_cloud_services", None):
111
+ obj.cloud_services.remove(*form.cleaned_data["remove_cloud_services"])
112
+
103
113
 
104
114
  class CloudResourceTypeUIViewSet(NautobotUIViewSet):
105
115
  queryset = CloudResourceType.objects.all()
@@ -163,3 +173,9 @@ class CloudServiceUIViewSet(NautobotUIViewSet):
163
173
  )
164
174
 
165
175
  return context
176
+
177
+ def extra_post_save_action(self, obj, form):
178
+ if form.cleaned_data.get("add_cloud_networks", None):
179
+ obj.cloud_networks.add(*form.cleaned_data["add_cloud_networks"])
180
+ if form.cleaned_data.get("remove_cloud_networks", None):
181
+ obj.cloud_networks.remove(*form.cleaned_data["remove_cloud_networks"])
@@ -53,10 +53,10 @@ class ChoiceField(serializers.Field):
53
53
  data = ""
54
54
  return super().validate_empty_values(data)
55
55
 
56
- def to_representation(self, value):
57
- if value == "":
56
+ def to_representation(self, obj):
57
+ if obj == "":
58
58
  return None
59
- return OrderedDict([("value", value), ("label", self._choices[value])])
59
+ return OrderedDict([("value", obj), ("label", self._choices[obj])])
60
60
 
61
61
  def to_internal_value(self, data):
62
62
  if data == "":
@@ -123,8 +123,8 @@ class ContentTypeField(RelatedField):
123
123
  self.fail("invalid")
124
124
  return None
125
125
 
126
- def to_representation(self, value):
127
- return f"{value.app_label}.{value.model}"
126
+ def to_representation(self, obj):
127
+ return f"{obj.app_label}.{obj.model}"
128
128
 
129
129
 
130
130
  class LaxURLField(URLField):
@@ -2,8 +2,6 @@ from django_filters.rest_framework.backends import DjangoFilterBackend
2
2
  from rest_framework.filters import OrderingFilter
3
3
  from tree_queries.models import TreeNode
4
4
 
5
- from nautobot.core.api.constants import NON_FILTER_QUERY_PARAMS
6
-
7
5
 
8
6
  class NautobotFilterBackend(DjangoFilterBackend):
9
7
  """Custom filtering backend for use with django-rest-framework and django-filters."""
@@ -19,7 +17,15 @@ class NautobotFilterBackend(DjangoFilterBackend):
19
17
  # The default 'data' is a reference to request.GET, which is immutable; copies of this data are mutable
20
18
  data = kwargs["data"].copy()
21
19
 
22
- for non_filter_param in NON_FILTER_QUERY_PARAMS:
20
+ for non_filter_param in (
21
+ "api_version", # used to select the Nautobot API version
22
+ "depth", # nested levels of the serializers default to depth=0
23
+ "format", # "json" or "api", used in the interactive HTML REST API views
24
+ "include", # used to include computed fields, relationships, config-contexts, etc. (excluded by default)
25
+ "limit", # pagination
26
+ "offset", # pagination
27
+ "sort", # sorting of results
28
+ ):
23
29
  data.pop(non_filter_param, None)
24
30
 
25
31
  kwargs["data"] = data
@@ -112,13 +112,13 @@ class NautobotAutoSchema(AutoSchema):
112
112
  "required": True,
113
113
  }
114
114
 
115
+ # Inject a custom description for the "id" parameter since ours has custom lookup behavior.
115
116
  if operation is not None and "parameters" in operation:
116
117
  for param in operation["parameters"]:
117
- # Inject a custom description for the "id" parameter since ours has custom lookup behavior.
118
118
  if param["name"] == "id" and "description" not in param:
119
119
  param["description"] = "Unique object identifier, either a UUID primary key or a composite key."
120
120
  if self.method == "GET":
121
- if not any(param["name"] == "depth" for param in operation["parameters"]):
121
+ if "depth" not in operation["parameters"]:
122
122
  operation["parameters"].append(
123
123
  {
124
124
  "in": "query",
@@ -128,17 +128,6 @@ class NautobotAutoSchema(AutoSchema):
128
128
  "schema": {"type": "integer", "minimum": 0, "maximum": 10, "default": 1},
129
129
  }
130
130
  )
131
- if not any(param["name"] == "exclude_m2m" for param in operation["parameters"]):
132
- operation["parameters"].append(
133
- {
134
- "in": "query",
135
- "name": "exclude_m2m",
136
- "required": False,
137
- "description": "Exclude many-to-many fields from the response",
138
- "schema": {"type": "boolean", "default": False},
139
- }
140
- )
141
- # TODO: add "include" parameter to the schema where relevant - nautobot/nautobot#685
142
131
  return operation
143
132
 
144
133
  def get_operation_id(self):
@@ -33,7 +33,6 @@ from nautobot.core.api.utils import (
33
33
  from nautobot.core.models.fields import LaxURLField as LaxURLModelField
34
34
  from nautobot.core.models.managers import TagsManager
35
35
  from nautobot.core.models.utils import construct_composite_key, construct_natural_slug
36
- from nautobot.core.settings_funcs import is_truthy
37
36
  from nautobot.core.utils.lookup import get_route_for_model
38
37
  from nautobot.core.utils.requests import normalize_querydict
39
38
  from nautobot.extras.api.customfields import CustomFieldDefaultValues, CustomFieldsDataField
@@ -47,9 +46,8 @@ logger = logging.getLogger(__name__)
47
46
 
48
47
  class OptInFieldsMixin:
49
48
  """
50
- Serializer mixin that adjusts its fields based on the `include` and `exclude_m2m` query parameters in a request.
51
-
52
- The serializer's `Meta.opt_in_fields` controls which fields are influenced by `include`.
49
+ A serializer mixin that takes an additional `opt_in_fields` argument that controls
50
+ which fields should be displayed.
53
51
  """
54
52
 
55
53
  def __init__(self, *args, **kwargs):
@@ -59,11 +57,8 @@ class OptInFieldsMixin:
59
57
  @property
60
58
  def fields(self):
61
59
  """
62
- Dynamically adjust the dictionary of fields attributed to this serializer instance.
63
-
64
- - Removes all serializer fields specified in `Meta.opt_in_fields` list that aren't specified in the
65
- `include` query parameter. (applies to GET requests only)
66
- - If the `exclude_m2m` query parameter is truthy, remove all many-to-many serializer fields for performance.
60
+ Removes all serializer fields specified in a serializers `opt_in_fields` list that aren't specified in the
61
+ `include` query parameter.
67
62
 
68
63
  As an example, if the serializer specifies that `opt_in_fields = ["computed_fields"]`
69
64
  but `computed_fields` is not specified in the `?include` query parameter, `computed_fields` will be popped
@@ -71,7 +66,12 @@ class OptInFieldsMixin:
71
66
  """
72
67
  if self.__pruned_fields is None:
73
68
  fields = dict(super().fields)
74
- serializer_opt_in_fields = getattr(self.Meta, "opt_in_fields", [])
69
+ serializer_opt_in_fields = getattr(self.Meta, "opt_in_fields", None)
70
+
71
+ if not serializer_opt_in_fields:
72
+ # This serializer has no defined opt_in_fields, so we never need to go further than this
73
+ self.__pruned_fields = fields
74
+ return self.__pruned_fields
75
75
 
76
76
  if not hasattr(self, "_context"):
77
77
  # We are being called before a request cycle
@@ -83,29 +83,24 @@ class OptInFieldsMixin:
83
83
  # No available request?
84
84
  return fields
85
85
 
86
+ # opt-in fields only applies on GET requests, for other methods we support these fields regardless
87
+ if request is not None and request.method != "GET":
88
+ return fields
89
+
86
90
  # NOTE: drf test framework builds a request object where the query
87
91
  # parameters are found under the GET attribute.
88
92
  params = normalize_querydict(getattr(request, "query_params", getattr(request, "GET", None)))
89
93
 
90
- # opt-in fields only applies on GET requests, for other methods we support these fields regardless
91
- if request is None or request.method == "GET":
92
- try:
93
- user_opt_in_fields = params.get("include", [])
94
- except AttributeError:
95
- # include parameter was not specified
96
- user_opt_in_fields = []
97
-
98
- # Drop any fields that are not specified in the users opt in fields
99
- for field in serializer_opt_in_fields:
100
- if field not in user_opt_in_fields:
101
- fields.pop(field, None)
102
-
103
- # If exclude_m2m is present and truthy, mark any many-to-many fields as write-only so they
104
- # don't get included in the response.
105
- if is_truthy(params.get("exclude_m2m", "false")):
106
- for field_instance in fields.values():
107
- if isinstance(field_instance, (serializers.ManyRelatedField, serializers.ListSerializer)):
108
- field_instance.write_only = True
94
+ try:
95
+ user_opt_in_fields = params.get("include", [])
96
+ except AttributeError:
97
+ # include parameter was not specified
98
+ user_opt_in_fields = []
99
+
100
+ # Drop any fields that are not specified in the users opt in fields
101
+ for field in serializer_opt_in_fields:
102
+ if field not in user_opt_in_fields:
103
+ fields.pop(field, None)
109
104
 
110
105
  self.__pruned_fields = fields
111
106
 
@@ -136,7 +131,6 @@ class BaseModelSerializer(OptInFieldsMixin, serializers.HyperlinkedModelSerializ
136
131
 
137
132
  serializer_related_field = NautobotHyperlinkedRelatedField
138
133
 
139
- id = serializers.UUIDField(read_only=False, default=serializers.CreateOnlyDefault(uuid.uuid4))
140
134
  display = serializers.SerializerMethodField(read_only=True, help_text="Human friendly display value")
141
135
  object_type = ObjectTypeField()
142
136
  # composite_key = serializers.SerializerMethodField() # TODO: Revisit if we reintroduce composite keys
@@ -531,27 +525,27 @@ class ValidatedModelSerializer(BaseModelSerializer):
531
525
  validation. (DRF does not do this by default; see https://github.com/encode/django-rest-framework/issues/3144)
532
526
  """
533
527
 
534
- def validate(self, attrs):
528
+ def validate(self, data):
535
529
  # Remove custom fields data and tags (if any) prior to model validation
536
- local_attrs = attrs.copy()
537
- local_attrs.pop("custom_fields", None)
538
- local_attrs.pop("relationships", None)
539
- local_attrs.pop("tags", None)
530
+ attrs = data.copy()
531
+ attrs.pop("custom_fields", None)
532
+ attrs.pop("relationships", None)
533
+ attrs.pop("tags", None)
540
534
 
541
535
  # Skip ManyToManyFields
542
536
  for field in self.Meta.model._meta.get_fields():
543
537
  if isinstance(field, models.ManyToManyField):
544
- local_attrs.pop(field.name, None)
538
+ attrs.pop(field.name, None)
545
539
 
546
540
  # Run clean() on an instance of the model
547
541
  if self.instance is None:
548
- instance = self.Meta.model(**local_attrs)
542
+ instance = self.Meta.model(**attrs)
549
543
  else:
550
544
  instance = self.instance
551
- for k, v in local_attrs.items():
545
+ for k, v in attrs.items():
552
546
  setattr(instance, k, v)
553
547
  instance.full_clean()
554
- return attrs
548
+ return data
555
549
 
556
550
 
557
551
  class WritableNestedSerializer(BaseModelSerializer):
@@ -597,7 +591,7 @@ class WritableNestedSerializer(BaseModelSerializer):
597
591
  pk = None
598
592
 
599
593
  if isinstance(self.Meta.model._meta.pk, models.AutoField):
600
- # PK is an int for this model. This is usually the Group or Content-Type model
594
+ # PK is an int for this model. This is usually the User model
601
595
  try:
602
596
  pk = int(data)
603
597
  except (TypeError, ValueError):
@@ -7,11 +7,9 @@ from django import __version__ as DJANGO_VERSION, forms
7
7
  from django.apps import apps
8
8
  from django.conf import settings
9
9
  from django.contrib.contenttypes.models import ContentType
10
- from django.core.exceptions import FieldDoesNotExist, ObjectDoesNotExist, ValidationError
10
+ from django.core.exceptions import ObjectDoesNotExist, ValidationError
11
11
  from django.db import transaction
12
12
  from django.db.models import ProtectedError
13
- from django.db.models.fields.related import ForeignKey, ManyToManyField, RelatedField
14
- from django.db.models.fields.reverse_related import ManyToManyRel, ManyToOneRel
15
13
  from django.http.response import HttpResponseBadRequest
16
14
  from django.shortcuts import get_object_or_404, redirect
17
15
  from drf_spectacular.plumbing import get_relative_url, set_query_parameters
@@ -25,7 +23,7 @@ from graphql.execution import ExecutionResult
25
23
  from graphql.execution.middleware import MiddlewareManager
26
24
  from graphql.type.schema import GraphQLSchema
27
25
  import redis.exceptions
28
- from rest_framework import routers, serializers as drf_serializers, status
26
+ from rest_framework import routers, status
29
27
  from rest_framework.exceptions import APIException, ParseError, PermissionDenied
30
28
  from rest_framework.generics import GenericAPIView
31
29
  from rest_framework.permissions import IsAuthenticated
@@ -40,11 +38,9 @@ from nautobot.core.api.exceptions import SerializerNotFound
40
38
  from nautobot.core.api.utils import get_serializer_for_model
41
39
  from nautobot.core.celery import app as celery_app
42
40
  from nautobot.core.exceptions import FilterSetFieldNotFound
43
- from nautobot.core.models.fields import TagsField
44
41
  from nautobot.core.utils.data import is_uuid, render_jinja2
45
42
  from nautobot.core.utils.filtering import get_all_lookup_expr_for_field, get_filterset_parameter_form_field
46
43
  from nautobot.core.utils.lookup import get_form_for_model
47
- from nautobot.core.utils.querysets import maybe_prefetch_related, maybe_select_related
48
44
  from nautobot.core.utils.requests import ensure_content_type_and_field_name_in_query_params
49
45
  from nautobot.core.views.utils import get_csv_form_fields_from_serializer_class
50
46
 
@@ -236,53 +232,6 @@ class ModelViewSetMixin:
236
232
 
237
233
  return context
238
234
 
239
- def get_queryset(self):
240
- """
241
- Attempt to optimize the queryset based on the fields present in the associated serializer.
242
-
243
- See similar logic in nautobot.core.tables.BaseTable.
244
- """
245
- queryset = super().get_queryset()
246
- model = queryset.model
247
- serializer = self.get_serializer()
248
-
249
- select_fields = []
250
- prefetch_fields = []
251
-
252
- for field_instance in serializer.fields.values():
253
- if field_instance.write_only:
254
- continue
255
- if field_instance.source == "*":
256
- continue
257
- if "." in field_instance.source:
258
- # DRF uses `field.nested_field` instead of `field__nested_field`
259
- # TODO: We don't currently attempt to optimize nested lookups.
260
- continue
261
- if isinstance(field_instance, (drf_serializers.ManyRelatedField, drf_serializers.ListSerializer)):
262
- # ListSerializer with depth > 0, ManyRelatedField with depth 0
263
- try:
264
- model_field = model._meta.get_field(field_instance.source)
265
- except FieldDoesNotExist:
266
- continue
267
- if isinstance(model_field, (ManyToManyField, ManyToManyRel, RelatedField, ManyToOneRel, TagsField)):
268
- prefetch_fields.append(field_instance.source)
269
- elif isinstance(field_instance, (drf_serializers.RelatedField, drf_serializers.Serializer)):
270
- # Serializer with depth > 0, RelatedField with depth 0
271
- try:
272
- model_field = model._meta.get_field(field_instance.source)
273
- except FieldDoesNotExist:
274
- continue
275
- if isinstance(model_field, ForeignKey):
276
- select_fields.append(field_instance.source)
277
-
278
- if select_fields:
279
- queryset = maybe_select_related(queryset, select_fields)
280
-
281
- if prefetch_fields:
282
- queryset = maybe_prefetch_related(queryset, prefetch_fields)
283
-
284
- return queryset
285
-
286
235
  def restrict_queryset(self, request, *args, **kwargs):
287
236
  """
288
237
  Restrict the view's queryset to allow only the permitted objects for the given request.
@@ -421,7 +370,7 @@ class APIRootView(AuthenticatedAPIRootView):
421
370
  name = "API Root"
422
371
 
423
372
  @extend_schema(exclude=True)
424
- def get(self, request, *args, format=None, **kwargs): # pylint: disable=redefined-builtin
373
+ def get(self, request, format=None): # pylint: disable=redefined-builtin
425
374
  return Response(
426
375
  OrderedDict(
427
376
  (
@@ -628,13 +577,12 @@ class GraphQLDRFAPIView(NautobotAPIVersionMixin, APIView):
628
577
  middleware = None
629
578
  root_value = None
630
579
 
631
- def __init__(self, schema=None, executor=None, middleware=None, root_value=None, backend=None, **kwargs):
580
+ def __init__(self, schema=None, executor=None, middleware=None, root_value=None, backend=None):
632
581
  self.schema = schema
633
582
  self.executor = executor
634
583
  self.middleware = middleware
635
584
  self.root_value = root_value
636
585
  self.backend = backend
637
- super().__init__(**kwargs)
638
586
 
639
587
  def get_root_value(self, request):
640
588
  return self.root_value
@@ -11,10 +11,6 @@ class NautobotDatabaseHandler(logging.Handler):
11
11
  if current_task is None:
12
12
  return
13
13
 
14
- # Skip recording the log entry if it has been marked as such
15
- if getattr(record, "skip_db_logging", False):
16
- return
17
-
18
14
  from nautobot.extras.models.jobs import JobResult
19
15
 
20
16
  try:
@@ -28,6 +24,10 @@ class NautobotDatabaseHandler(logging.Handler):
28
24
  # JobResult.DoesNotExist - because we might not have a JobResult with that ID
29
25
  return
30
26
 
27
+ # Skip recording the log entry if it has been marked as such
28
+ if getattr(record, "skip_db_logging", False):
29
+ return
30
+
31
31
  job_result.log(
32
32
  message=record.message,
33
33
  level_choice=record.levelname.lower(),
@@ -25,7 +25,7 @@ class NautobotScheduleEntry(ModelEntry):
25
25
  nautobot.extras.models.ScheduledJob model
26
26
  """
27
27
 
28
- def __init__(self, model, app=None): # pylint:disable=super-init-not-called # we must copy-and-paste from super
28
+ def __init__(self, model, app=None):
29
29
  """Initialize the model entry."""
30
30
  # copy-paste from django_celery_beat.schedulers
31
31
  self.app = app or current_app._get_current_object()
nautobot/core/choices.py CHANGED
@@ -182,14 +182,14 @@ class ButtonActionColorChoices(ChoiceSet):
182
182
  Map standard button actions to Bootstrap color classes.
183
183
  """
184
184
 
185
- ADD = "primary"
185
+ ADD = "info"
186
186
  CANCEL = "default"
187
187
  CLONE = "success"
188
188
  CONFIGURE = "default"
189
189
  CONNECT = "success"
190
190
  DEFAULT = "default"
191
191
  DELETE = "danger"
192
- DISCONNECT = "danger"
192
+ DISCONNECT = "info"
193
193
  EDIT = "warning"
194
194
  EXPORT = "success"
195
195
  IMPORT = "primary"
@@ -107,10 +107,10 @@ def publish_event(*, topic, payload):
107
107
 
108
108
 
109
109
  __all__ = (
110
- "EventBroker",
111
- "RedisEventBroker",
112
- "SyslogEventBroker",
113
110
  "deregister_event_broker",
111
+ "EventBroker",
114
112
  "publish_event",
113
+ "RedisEventBroker",
115
114
  "register_event_broker",
115
+ "SyslogEventBroker",
116
116
  )
nautobot/core/filters.py CHANGED
@@ -618,7 +618,6 @@ class BaseFilterSet(django_filters.FilterSet):
618
618
  @staticmethod
619
619
  def _get_filter_lookup_dict(existing_filter):
620
620
  # Choose the lookup expression map based on the filter type
621
-
622
621
  if isinstance(
623
622
  existing_filter,
624
623
  (
@@ -638,7 +637,6 @@ class BaseFilterSet(django_filters.FilterSet):
638
637
  (
639
638
  django_filters.ModelChoiceFilter,
640
639
  django_filters.ModelMultipleChoiceFilter,
641
- MultiValueUUIDFilter,
642
640
  TagFilter,
643
641
  TreeNodeMultipleChoiceFilter,
644
642
  ),
@@ -668,7 +666,7 @@ class BaseFilterSet(django_filters.FilterSet):
668
666
  the form `<field_name>__<lookup_expr>`
669
667
  """
670
668
  magic_filters = {}
671
- if filter_field.method is not None or filter_field.lookup_expr not in ["exact", "in", "iexact"]:
669
+ if filter_field.method is not None or filter_field.lookup_expr not in ["exact", "in"]:
672
670
  return magic_filters
673
671
 
674
672
  # Choose the lookup expression map based on the filter type
@@ -679,7 +677,7 @@ class BaseFilterSet(django_filters.FilterSet):
679
677
 
680
678
  # Get properties of the existing filter for later use
681
679
  field_name = filter_field.field_name
682
- field = get_model_field(cls._meta.model, field_name) # pylint: disable=no-member
680
+ field = get_model_field(cls._meta.model, field_name)
683
681
 
684
682
  # If there isn't a model field, return.
685
683
  if field is None:
@@ -696,7 +694,7 @@ class BaseFilterSet(django_filters.FilterSet):
696
694
  new_filter_name = f"{filter_name}__{lookup_name}"
697
695
 
698
696
  try:
699
- if filter_name in cls.declared_filters and lookup_expr not in {"isnull"}: # pylint: disable=no-member
697
+ if filter_name in cls.declared_filters and lookup_expr not in {"isnull"}:
700
698
  # The filter field has been explicitly defined on the filterset class so we must manually
701
699
  # create the new filter with the same type because there is no guarantee the defined type
702
700
  # is the same as the default type for the field. This does not apply if the filter
@@ -727,10 +725,7 @@ class BaseFilterSet(django_filters.FilterSet):
727
725
  # If the base filter_field has a custom label, django_filters won't adjust it for the new_filter lookup,
728
726
  # so we have to do it.
729
727
  if filter_field.label and filter_field.label != label_for_filter(
730
- cls._meta.model, # pylint: disable=no-member
731
- filter_field.field_name,
732
- filter_field.lookup_expr,
733
- filter_field.exclude,
728
+ cls.Meta.model, filter_field.field_name, filter_field.lookup_expr, filter_field.exclude
734
729
  ):
735
730
  # Lightly adjusted from label_for_filter() implementation:
736
731
  verbose_expression = ["exclude", filter_field.label] if new_filter.exclude else [filter_field.label]
@@ -753,22 +748,22 @@ class BaseFilterSet(django_filters.FilterSet):
753
748
  if not isinstance(new_filter_field, django_filters.Filter):
754
749
  raise TypeError(f"Tried to add filter ({new_filter_name}) which is not an instance of Django Filter")
755
750
 
756
- if new_filter_name in cls.base_filters: # pylint: disable=no-member
751
+ if new_filter_name in cls.base_filters:
757
752
  raise AttributeError(
758
753
  f"There was a conflict with filter `{new_filter_name}`, the custom filter was ignored."
759
754
  )
760
755
 
761
- cls.base_filters[new_filter_name] = new_filter_field # pylint: disable=no-member
756
+ cls.base_filters[new_filter_name] = new_filter_field
762
757
  # django-filters has no concept of "abstract" filtersets, so we have to fake it
763
- if cls._meta.model is not None: # pylint: disable=no-member
764
- cls.base_filters.update( # pylint: disable=no-member
758
+ if cls._meta.model is not None:
759
+ cls.base_filters.update(
765
760
  cls._generate_lookup_expression_filters(filter_name=new_filter_name, filter_field=new_filter_field)
766
761
  )
767
762
 
768
763
  @classmethod
769
764
  def get_fields(cls):
770
765
  fields = super().get_fields()
771
- if "id" not in fields and (cls._meta.exclude is None or "id" not in cls._meta.exclude): # pylint: disable=no-member
766
+ if "id" not in fields and (cls._meta.exclude is None or "id" not in cls._meta.exclude):
772
767
  # Add "id" as the first key in the `fields` dict
773
768
  fields = {"id": [django_filters.conf.settings.DEFAULT_LOOKUP_EXPR], **fields}
774
769
  return fields
@@ -785,7 +780,7 @@ class BaseFilterSet(django_filters.FilterSet):
785
780
  if filter_name.startswith("_"):
786
781
  del filters[filter_name]
787
782
 
788
- if getattr(cls._meta.model, "is_contact_associable_model", False): # pylint: disable=no-member
783
+ if getattr(cls._meta.model, "is_contact_associable_model", False):
789
784
  # Add "contacts" and "teams" filters
790
785
  from nautobot.extras.models import Contact, Team
791
786
 
@@ -805,13 +800,13 @@ class BaseFilterSet(django_filters.FilterSet):
805
800
  label="Teams (name or ID)",
806
801
  )
807
802
 
808
- if "dynamic_groups" not in filters and getattr(cls._meta.model, "is_dynamic_group_associable_model", False): # pylint: disable=no-member
809
- if not hasattr(cls._meta.model, "static_group_association_set"): # pylint: disable=no-member
803
+ if "dynamic_groups" not in filters and getattr(cls._meta.model, "is_dynamic_group_associable_model", False):
804
+ if not hasattr(cls._meta.model, "static_group_association_set"):
810
805
  logger.warning(
811
806
  "Model %s has 'is_dynamic_group_associable_model = True' but lacks "
812
807
  "a 'static_group_association_set' attribute. Perhaps this is due to it inheriting from "
813
808
  "the deprecated DynamicGroupMixin class instead of the preferred DynamicGroupsModelMixin?",
814
- cls._meta.model, # pylint: disable=no-member
809
+ cls._meta.model,
815
810
  )
816
811
  else:
817
812
  # Add "dynamic_groups" field as the last key
@@ -821,14 +816,14 @@ class BaseFilterSet(django_filters.FilterSet):
821
816
  queryset=DynamicGroup.objects.all(),
822
817
  field_name="static_group_association_set__dynamic_group",
823
818
  to_field_name="name",
824
- query_params={"content_type": cls._meta.model._meta.label_lower}, # pylint: disable=no-member
819
+ query_params={"content_type": cls._meta.model._meta.label_lower},
825
820
  label="Dynamic groups (name or ID)",
826
821
  )
827
822
 
828
823
  # django-filters has no concept of "abstract" filtersets, so we have to fake it
829
- if cls._meta.model is not None: # pylint: disable=no-member
824
+ if cls._meta.model is not None:
830
825
  if "tags" in filters and isinstance(filters["tags"], TagFilter):
831
- filters["tags"].extra["query_params"] = {"content_types": [cls._meta.model._meta.label_lower]} # pylint: disable=no-member
826
+ filters["tags"].extra["query_params"] = {"content_types": [cls._meta.model._meta.label_lower]}
832
827
 
833
828
  new_filters = {}
834
829
  for existing_filter_name, existing_filter in filters.items():
@@ -0,0 +1,59 @@
1
+ [
2
+ {
3
+ "model": "users.user",
4
+ "pk": "90798182-9d19-479a-899f-a415fc2c62fe",
5
+ "fields": {
6
+ "password": "pbkdf2_sha256$216000$TtNpNWboQq6C$6vh6qqRXUGSuLZlwvvGRbz35BS6avrdEFudnjJv2HXY=",
7
+ "last_login": null,
8
+ "is_superuser": false,
9
+ "username": "alice",
10
+ "first_name": "",
11
+ "last_name": "",
12
+ "email": "alice@localhost",
13
+ "is_staff": false,
14
+ "is_active": true,
15
+ "date_joined": "2021-05-25T23:49:55.008Z",
16
+ "config_data": {},
17
+ "groups": [],
18
+ "user_permissions": []
19
+ }
20
+ },
21
+ {
22
+ "model": "users.user",
23
+ "pk": "90798182-9d19-479a-899f-a415fc2c62fd",
24
+ "fields": {
25
+ "password": "pbkdf2_sha256$216000$TtNpNWboQq6C$6vh6qqRXUGSuLZlwvvGRbz35BS6avrdEFudnjJv2HXY=",
26
+ "last_login": null,
27
+ "is_superuser": true,
28
+ "username": "bob",
29
+ "first_name": "",
30
+ "last_name": "",
31
+ "email": "bob@localhost",
32
+ "is_staff": true,
33
+ "is_active": true,
34
+ "date_joined": "2021-05-25T23:49:55.008Z",
35
+ "config_data": {},
36
+ "groups": [],
37
+ "user_permissions": []
38
+ }
39
+ },
40
+ {
41
+ "model": "users.user",
42
+ "pk": "90798182-9d19-479a-899f-a415fc2c62ff",
43
+ "fields": {
44
+ "password": "pbkdf2_sha256$216000$TtNpNWboQq6C$6vh6qqRXUGSuLZlwvvGRbz35BS6avrdEFudnjJv2HXY=",
45
+ "last_login": null,
46
+ "is_superuser": false,
47
+ "username": "charlie",
48
+ "first_name": "",
49
+ "last_name": "",
50
+ "email": "charlie@localhost",
51
+ "is_staff": false,
52
+ "is_active": true,
53
+ "date_joined": "2021-05-25T23:49:55.008Z",
54
+ "config_data": {},
55
+ "groups": [],
56
+ "user_permissions": []
57
+ }
58
+ }
59
+ ]