nautobot 2.4.0b1__py3-none-any.whl → 2.4.1__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 (601) 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 +1 -0
  18. nautobot/circuits/api/views.py +4 -8
  19. nautobot/circuits/tables.py +2 -1
  20. nautobot/circuits/templates/circuits/circuit_create.html +1 -7
  21. nautobot/circuits/views.py +3 -3
  22. nautobot/cloud/api/views.py +6 -10
  23. nautobot/cloud/models.py +1 -1
  24. nautobot/cloud/views.py +0 -16
  25. nautobot/core/api/constants.py +11 -0
  26. nautobot/core/api/fields.py +5 -5
  27. nautobot/core/api/filter_backends.py +3 -9
  28. nautobot/core/api/schema.py +13 -2
  29. nautobot/core/api/serializers.py +40 -34
  30. nautobot/core/api/views.py +56 -4
  31. nautobot/core/celery/log.py +4 -4
  32. nautobot/core/celery/schedulers.py +2 -2
  33. nautobot/core/choices.py +2 -2
  34. nautobot/core/events/__init__.py +3 -3
  35. nautobot/core/filters.py +67 -35
  36. nautobot/core/forms/__init__.py +19 -19
  37. nautobot/core/forms/fields.py +14 -11
  38. nautobot/core/forms/forms.py +33 -2
  39. nautobot/core/graphql/types.py +1 -1
  40. nautobot/core/jobs/__init__.py +28 -7
  41. nautobot/core/jobs/bulk_actions.py +285 -0
  42. nautobot/core/jobs/cleanup.py +48 -12
  43. nautobot/core/jobs/groups.py +1 -1
  44. nautobot/core/management/commands/validate_models.py +1 -1
  45. nautobot/core/models/__init__.py +3 -1
  46. nautobot/core/models/query_functions.py +2 -2
  47. nautobot/core/models/tree_queries.py +6 -3
  48. nautobot/core/settings.py +29 -2
  49. nautobot/core/settings.yaml +21 -0
  50. nautobot/core/tables.py +79 -61
  51. nautobot/core/templates/about.html +67 -0
  52. nautobot/core/templates/inc/media.html +3 -0
  53. nautobot/core/templates/inc/nav_menu.html +1 -0
  54. nautobot/core/templates/inc/tenancy_form_panel.html +9 -0
  55. nautobot/core/templates/inc/tenant_table_row.html +11 -0
  56. nautobot/core/templates/nautobot_config.py.j2 +13 -0
  57. nautobot/core/templates/search.html +7 -0
  58. nautobot/core/templates/utilities/render_jinja2.html +1 -1
  59. nautobot/core/templates/utilities/templatetags/tag.html +1 -1
  60. nautobot/core/templates/utilities/theme_preview.html +7 -0
  61. nautobot/core/templatetags/helpers.py +11 -2
  62. nautobot/core/testing/__init__.py +8 -8
  63. nautobot/core/testing/api.py +170 -15
  64. nautobot/core/testing/filters.py +45 -10
  65. nautobot/core/testing/forms.py +2 -0
  66. nautobot/core/testing/integration.py +86 -4
  67. nautobot/core/testing/mixins.py +7 -2
  68. nautobot/core/testing/views.py +44 -29
  69. nautobot/core/tests/integration/test_app_home.py +0 -1
  70. nautobot/core/tests/integration/test_app_navbar.py +0 -1
  71. nautobot/core/tests/integration/test_filters.py +0 -2
  72. nautobot/core/tests/integration/test_home.py +0 -1
  73. nautobot/core/tests/integration/test_navbar.py +0 -1
  74. nautobot/core/tests/integration/test_view_authentication.py +1 -0
  75. nautobot/core/tests/runner.py +1 -1
  76. nautobot/core/tests/test_api.py +98 -1
  77. nautobot/core/tests/test_csv.py +25 -3
  78. nautobot/core/tests/test_filters.py +209 -246
  79. nautobot/core/tests/test_forms.py +1 -0
  80. nautobot/core/tests/test_jobs.py +460 -1
  81. nautobot/core/tests/test_models.py +9 -0
  82. nautobot/core/tests/test_settings_schema.py +7 -0
  83. nautobot/core/tests/test_tables.py +100 -0
  84. nautobot/core/tests/test_utils.py +63 -1
  85. nautobot/core/tests/test_views.py +30 -3
  86. nautobot/core/ui/nav.py +1 -0
  87. nautobot/core/ui/object_detail.py +15 -1
  88. nautobot/core/urls.py +11 -0
  89. nautobot/core/utils/lookup.py +11 -8
  90. nautobot/core/utils/querysets.py +64 -0
  91. nautobot/core/utils/requests.py +24 -9
  92. nautobot/core/views/__init__.py +42 -0
  93. nautobot/core/views/generic.py +131 -197
  94. nautobot/core/views/mixins.py +126 -38
  95. nautobot/core/views/renderers.py +6 -6
  96. nautobot/dcim/api/serializers.py +56 -64
  97. nautobot/dcim/api/views.py +47 -113
  98. nautobot/dcim/constants.py +6 -13
  99. nautobot/dcim/factory.py +6 -1
  100. nautobot/dcim/filters/__init__.py +31 -2
  101. nautobot/dcim/forms.py +36 -17
  102. nautobot/dcim/graphql/types.py +2 -2
  103. nautobot/dcim/migrations/0067_controllermanageddevicegroup_tenant.py +25 -0
  104. nautobot/dcim/models/__init__.py +1 -1
  105. nautobot/dcim/models/device_component_templates.py +2 -2
  106. nautobot/dcim/models/device_components.py +22 -20
  107. nautobot/dcim/models/devices.py +10 -1
  108. nautobot/dcim/models/locations.py +3 -3
  109. nautobot/dcim/models/power.py +6 -5
  110. nautobot/dcim/models/racks.py +4 -4
  111. nautobot/dcim/tables/__init__.py +3 -3
  112. nautobot/dcim/tables/devices.py +7 -5
  113. nautobot/dcim/tables/devicetypes.py +2 -2
  114. nautobot/dcim/tables/racks.py +1 -1
  115. nautobot/dcim/templates/dcim/controller_create.html +1 -7
  116. nautobot/dcim/templates/dcim/controller_retrieve.html +1 -9
  117. nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +2 -0
  118. nautobot/dcim/templates/dcim/controllermanageddevicegroup_retrieve.html +5 -0
  119. nautobot/dcim/templates/dcim/device.html +1 -9
  120. nautobot/dcim/templates/dcim/device_edit.html +36 -37
  121. nautobot/dcim/templates/dcim/location.html +1 -9
  122. nautobot/dcim/templates/dcim/location_edit.html +1 -7
  123. nautobot/dcim/templates/dcim/rack.html +1 -9
  124. nautobot/dcim/templates/dcim/rack_edit.html +1 -7
  125. nautobot/dcim/templates/dcim/rackreservation.html +1 -9
  126. nautobot/dcim/templates/dcim/virtualdevicecontext_retrieve.html +1 -9
  127. nautobot/dcim/templates/dcim/virtualdevicecontext_update.html +1 -7
  128. nautobot/dcim/tests/integration/test_controller.py +62 -0
  129. nautobot/dcim/tests/integration/test_controller_managed_device_group.py +71 -0
  130. nautobot/dcim/tests/integration/test_device_bulk_delete.py +189 -0
  131. nautobot/dcim/tests/integration/test_device_bulk_edit.py +181 -0
  132. nautobot/dcim/tests/test_api.py +16 -5
  133. nautobot/dcim/tests/test_filters.py +33 -0
  134. nautobot/dcim/tests/test_forms.py +51 -2
  135. nautobot/dcim/tests/test_graphql.py +52 -0
  136. nautobot/dcim/tests/test_jobs.py +118 -0
  137. nautobot/dcim/tests/test_models.py +52 -9
  138. nautobot/dcim/tests/test_views.py +21 -83
  139. nautobot/dcim/views.py +1 -13
  140. nautobot/extras/api/customfields.py +2 -2
  141. nautobot/extras/api/serializers.py +90 -85
  142. nautobot/extras/api/views.py +22 -27
  143. nautobot/extras/constants.py +2 -0
  144. nautobot/extras/filters/__init__.py +8 -6
  145. nautobot/extras/forms/base.py +2 -2
  146. nautobot/extras/forms/forms.py +139 -31
  147. nautobot/extras/forms/mixins.py +14 -6
  148. nautobot/extras/group_sync.py +3 -3
  149. nautobot/extras/health_checks.py +1 -2
  150. nautobot/extras/jobs.py +85 -18
  151. nautobot/extras/managers.py +3 -1
  152. nautobot/extras/migrations/0018_joblog_data_migration.py +7 -9
  153. nautobot/extras/migrations/0120_job_is_singleton_job_is_singleton_override.py +22 -0
  154. nautobot/extras/migrations/0121_alter_team_contacts.py +17 -0
  155. nautobot/extras/models/__init__.py +1 -1
  156. nautobot/extras/models/contacts.py +1 -1
  157. nautobot/extras/models/customfields.py +12 -11
  158. nautobot/extras/models/groups.py +11 -9
  159. nautobot/extras/models/jobs.py +23 -4
  160. nautobot/extras/models/models.py +2 -2
  161. nautobot/extras/plugins/__init__.py +13 -2
  162. nautobot/extras/plugins/marketplace_manifest.yml +84 -79
  163. nautobot/extras/plugins/tables.py +16 -14
  164. nautobot/extras/plugins/views.py +65 -69
  165. nautobot/extras/registry.py +1 -1
  166. nautobot/extras/secrets/__init__.py +2 -2
  167. nautobot/extras/tables.py +7 -5
  168. nautobot/extras/templates/extras/dynamicgroup.html +1 -9
  169. nautobot/extras/templates/extras/job_detail.html +16 -0
  170. nautobot/extras/templates/extras/job_edit.html +1 -0
  171. nautobot/extras/templates/extras/jobqueue_retrieve.html +1 -9
  172. nautobot/extras/templates/extras/marketplace.html +29 -11
  173. nautobot/extras/templates/extras/plugin_detail.html +32 -15
  174. nautobot/extras/templates/extras/plugins_tiles.html +21 -10
  175. nautobot/extras/templatetags/job_buttons.py +4 -4
  176. nautobot/extras/test_jobs/api_test_job.py +1 -1
  177. nautobot/extras/test_jobs/atomic_transaction.py +2 -2
  178. nautobot/extras/test_jobs/dry_run.py +1 -1
  179. nautobot/extras/test_jobs/fail.py +5 -5
  180. nautobot/extras/test_jobs/file_output.py +1 -1
  181. nautobot/extras/test_jobs/file_upload_fail.py +1 -1
  182. nautobot/extras/test_jobs/file_upload_pass.py +1 -1
  183. nautobot/extras/test_jobs/ipaddress_vars.py +3 -1
  184. nautobot/extras/test_jobs/jobs_module/jobs_submodule/jobs.py +1 -1
  185. nautobot/extras/test_jobs/location_with_custom_field.py +1 -1
  186. nautobot/extras/test_jobs/log_redaction.py +1 -1
  187. nautobot/extras/test_jobs/log_skip_db_logging.py +1 -1
  188. nautobot/extras/test_jobs/modify_db.py +1 -1
  189. nautobot/extras/test_jobs/object_var_optional.py +1 -1
  190. nautobot/extras/test_jobs/object_var_required.py +1 -1
  191. nautobot/extras/test_jobs/object_vars.py +1 -1
  192. nautobot/extras/test_jobs/pass.py +3 -3
  193. nautobot/extras/test_jobs/profiling.py +1 -1
  194. nautobot/extras/test_jobs/relative_import.py +3 -3
  195. nautobot/extras/test_jobs/singleton.py +16 -0
  196. nautobot/extras/test_jobs/soft_time_limit_greater_than_time_limit.py +1 -1
  197. nautobot/extras/test_jobs/task_queues.py +1 -1
  198. nautobot/extras/tests/integration/test_plugin_banner.py +0 -2
  199. nautobot/extras/tests/test_api.py +13 -13
  200. nautobot/extras/tests/test_customfields.py +1 -1
  201. nautobot/extras/tests/test_datasources.py +2 -1
  202. nautobot/extras/tests/test_dynamicgroups.py +1 -1
  203. nautobot/extras/tests/test_filters.py +6 -6
  204. nautobot/extras/tests/test_forms.py +33 -1
  205. nautobot/extras/tests/test_jobs.py +178 -32
  206. nautobot/extras/tests/test_models.py +16 -10
  207. nautobot/extras/tests/test_plugins.py +62 -9
  208. nautobot/extras/tests/test_relationships.py +120 -9
  209. nautobot/extras/tests/test_views.py +56 -194
  210. nautobot/extras/utils.py +3 -2
  211. nautobot/extras/views.py +30 -98
  212. nautobot/ipam/api/fields.py +3 -3
  213. nautobot/ipam/api/serializers.py +41 -33
  214. nautobot/ipam/api/views.py +68 -117
  215. nautobot/ipam/factory.py +1 -1
  216. nautobot/ipam/filters.py +3 -2
  217. nautobot/ipam/lookups.py +101 -62
  218. nautobot/ipam/models.py +66 -16
  219. nautobot/ipam/querysets.py +2 -2
  220. nautobot/ipam/tables.py +23 -7
  221. nautobot/ipam/templates/ipam/ipaddress.html +1 -9
  222. nautobot/ipam/templates/ipam/ipaddress_bulk_add.html +1 -7
  223. nautobot/ipam/templates/ipam/ipaddress_edit.html +1 -7
  224. nautobot/ipam/templates/ipam/prefix.html +1 -9
  225. nautobot/ipam/templates/ipam/prefix_edit.html +1 -7
  226. nautobot/ipam/templates/ipam/vlan.html +1 -9
  227. nautobot/ipam/templates/ipam/vlan_edit.html +1 -7
  228. nautobot/ipam/templates/ipam/vrf_edit.html +1 -7
  229. nautobot/ipam/tests/test_api.py +436 -3
  230. nautobot/ipam/tests/test_forms.py +49 -47
  231. nautobot/ipam/tests/test_migrations.py +30 -30
  232. nautobot/ipam/tests/test_models.py +95 -34
  233. nautobot/ipam/tests/test_querysets.py +63 -1
  234. nautobot/ipam/tests/test_views.py +3 -0
  235. nautobot/ipam/utils/__init__.py +36 -6
  236. nautobot/ipam/views.py +61 -87
  237. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css.map +1 -1
  238. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css.map +1 -1
  239. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css +40 -2
  240. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css.map +1 -1
  241. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css +1 -1
  242. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css.map +1 -1
  243. nautobot/project-static/docs/404.html +46 -4
  244. nautobot/project-static/docs/apps/index.html +46 -4
  245. nautobot/project-static/docs/apps/nautobot-apps.html +47 -6
  246. nautobot/project-static/docs/assets/_mkdocstrings.css +25 -1
  247. nautobot/project-static/docs/assets/javascripts/{bundle.83f73b43.min.js → bundle.88dd0f4e.min.js} +2 -2
  248. nautobot/project-static/docs/assets/javascripts/{bundle.83f73b43.min.js.map → bundle.88dd0f4e.min.js.map} +2 -2
  249. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +62 -10
  250. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +59 -7
  251. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +374 -122
  252. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +90 -18
  253. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +95 -21
  254. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +53 -6
  255. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +52 -5
  256. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +79 -17
  257. nautobot/project-static/docs/code-reference/nautobot/apps/events.html +102 -28
  258. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +108 -21
  259. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +131 -38
  260. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +239 -65
  261. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +581 -165
  262. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +109 -36
  263. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +453 -167
  264. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +493 -211
  265. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +60 -8
  266. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +71 -15
  267. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +407 -55
  268. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +620 -205
  269. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +858 -412
  270. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +59 -7
  271. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +448 -186
  272. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +365 -147
  273. nautobot/project-static/docs/development/apps/api/configuration-view.html +46 -4
  274. nautobot/project-static/docs/development/apps/api/database-backend-config.html +46 -4
  275. nautobot/project-static/docs/development/apps/api/models/django-admin.html +46 -4
  276. nautobot/project-static/docs/development/apps/api/models/global-search.html +46 -4
  277. nautobot/project-static/docs/development/apps/api/models/graphql.html +46 -4
  278. nautobot/project-static/docs/development/apps/api/models/index.html +46 -4
  279. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +46 -4
  280. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +46 -4
  281. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +46 -4
  282. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +46 -4
  283. nautobot/project-static/docs/development/apps/api/platform-features/index.html +46 -4
  284. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +46 -4
  285. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +46 -4
  286. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +46 -4
  287. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +46 -4
  288. nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +68 -7
  289. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +46 -4
  290. nautobot/project-static/docs/development/apps/api/prometheus.html +46 -4
  291. nautobot/project-static/docs/development/apps/api/setup.html +46 -4
  292. nautobot/project-static/docs/development/apps/api/testing.html +46 -4
  293. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +46 -4
  294. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +46 -4
  295. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +46 -4
  296. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +46 -4
  297. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +46 -4
  298. nautobot/project-static/docs/development/apps/api/views/base-template.html +46 -4
  299. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +46 -4
  300. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +46 -4
  301. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +46 -4
  302. nautobot/project-static/docs/development/apps/api/views/index.html +46 -4
  303. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +46 -4
  304. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +46 -4
  305. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +46 -4
  306. nautobot/project-static/docs/development/apps/api/views/notes.html +46 -4
  307. nautobot/project-static/docs/development/apps/api/views/rest-api.html +52 -6
  308. nautobot/project-static/docs/development/apps/api/views/urls.html +46 -4
  309. nautobot/project-static/docs/development/apps/index.html +46 -4
  310. nautobot/project-static/docs/development/apps/migration/code-updates.html +46 -4
  311. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +46 -4
  312. nautobot/project-static/docs/development/apps/migration/from-v1.html +46 -4
  313. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +46 -4
  314. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +46 -4
  315. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +46 -4
  316. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +46 -4
  317. nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +50 -8
  318. nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +46 -4
  319. nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +211 -14
  320. nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +46 -4
  321. nautobot/project-static/docs/development/apps/porting-from-netbox.html +46 -4
  322. nautobot/project-static/docs/development/core/application-registry.html +46 -4
  323. nautobot/project-static/docs/development/core/best-practices.html +46 -4
  324. nautobot/project-static/docs/development/core/bootstrap-ui.html +46 -4
  325. nautobot/project-static/docs/development/core/caching.html +46 -4
  326. nautobot/project-static/docs/development/core/controllers.html +46 -4
  327. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +73 -74
  328. nautobot/project-static/docs/development/core/generic-views.html +46 -4
  329. nautobot/project-static/docs/development/core/getting-started.html +249 -224
  330. nautobot/project-static/docs/development/core/homepage.html +49 -7
  331. nautobot/project-static/docs/development/core/index.html +46 -4
  332. nautobot/project-static/docs/development/core/{local-k8s.html → minikube-dev-environment-for-k8s-jobs.html} +469 -168
  333. nautobot/project-static/docs/development/core/model-checklist.html +56 -12
  334. nautobot/project-static/docs/development/core/model-features.html +46 -4
  335. nautobot/project-static/docs/development/core/natural-keys.html +46 -4
  336. nautobot/project-static/docs/development/core/navigation-menu.html +46 -4
  337. nautobot/project-static/docs/development/core/release-checklist.html +49 -7
  338. nautobot/project-static/docs/development/core/role-internals.html +46 -4
  339. nautobot/project-static/docs/development/core/settings.html +46 -4
  340. nautobot/project-static/docs/development/core/style-guide.html +49 -7
  341. nautobot/project-static/docs/development/core/templates.html +46 -4
  342. nautobot/project-static/docs/development/core/testing.html +46 -4
  343. nautobot/project-static/docs/development/core/ui-component-framework.html +369 -273
  344. nautobot/project-static/docs/development/core/user-preferences.html +46 -4
  345. nautobot/project-static/docs/development/index.html +46 -4
  346. nautobot/project-static/docs/development/jobs/index.html +216 -122
  347. nautobot/project-static/docs/development/jobs/migration/from-v1.html +46 -4
  348. nautobot/project-static/docs/index.html +54 -23
  349. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_edit.png +0 -0
  350. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_edit_button.png +0 -0
  351. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_list_nav.png +0 -0
  352. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_list_view.png +0 -0
  353. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue.png +0 -0
  354. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue_add.png +0 -0
  355. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue_config.png +0 -0
  356. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_completed.png +0 -0
  357. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_nav.png +0 -0
  358. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_pending.png +0 -0
  359. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_run_form.png +0 -0
  360. nautobot/project-static/docs/media/development/core/kubernetes/k8s_nautobot_login.png +0 -0
  361. nautobot/project-static/docs/media/development/core/kubernetes/k8s_run_job.png +0 -0
  362. nautobot/project-static/docs/media/development/core/kubernetes/k8s_run_scheduled_job_form.png +0 -0
  363. nautobot/project-static/docs/media/development/core/kubernetes/k8s_scheduled_job_result.png +0 -0
  364. nautobot/project-static/docs/media/development/core/ui-component-framework/buttons-example.png +0 -0
  365. nautobot/project-static/docs/media/development/core/ui-component-framework/cluster-type-before-after-example.png +0 -0
  366. nautobot/project-static/docs/media/development/core/ui-component-framework/object-fields-panel-example_2.png +0 -0
  367. nautobot/project-static/docs/media/development/core/ui-component-framework/stats-panel-example-code.png +0 -0
  368. nautobot/project-static/docs/objects.inv +0 -0
  369. nautobot/project-static/docs/overview/application_stack.html +47 -7
  370. nautobot/project-static/docs/overview/design_philosophy.html +46 -4
  371. nautobot/project-static/docs/release-notes/index.html +52 -12
  372. nautobot/project-static/docs/release-notes/version-1.0.html +234 -193
  373. nautobot/project-static/docs/release-notes/version-1.1.html +231 -190
  374. nautobot/project-static/docs/release-notes/version-1.2.html +306 -265
  375. nautobot/project-static/docs/release-notes/version-1.3.html +332 -291
  376. nautobot/project-static/docs/release-notes/version-1.4.html +417 -377
  377. nautobot/project-static/docs/release-notes/version-1.5.html +605 -566
  378. nautobot/project-static/docs/release-notes/version-1.6.html +904 -447
  379. nautobot/project-static/docs/release-notes/version-2.0.html +528 -489
  380. nautobot/project-static/docs/release-notes/version-2.1.html +363 -324
  381. nautobot/project-static/docs/release-notes/version-2.2.html +356 -317
  382. nautobot/project-static/docs/release-notes/version-2.3.html +997 -352
  383. nautobot/project-static/docs/release-notes/version-2.4.html +525 -101
  384. nautobot/project-static/docs/requirements.txt +2 -2
  385. nautobot/project-static/docs/search/search_index.json +1 -1
  386. nautobot/project-static/docs/sitemap.xml +295 -287
  387. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  388. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +46 -4
  389. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +46 -4
  390. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +48 -6
  391. nautobot/project-static/docs/user-guide/administration/configuration/index.html +46 -4
  392. nautobot/project-static/docs/user-guide/administration/configuration/redis.html +46 -4
  393. nautobot/project-static/docs/user-guide/administration/configuration/settings.html +110 -8
  394. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +46 -4
  395. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +46 -4
  396. nautobot/project-static/docs/user-guide/administration/guides/docker.html +46 -4
  397. nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +46 -4
  398. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +46 -4
  399. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +46 -4
  400. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +46 -4
  401. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +46 -4
  402. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +48 -6
  403. nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +46 -4
  404. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +46 -4
  405. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +46 -4
  406. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +66 -8
  407. nautobot/project-static/docs/user-guide/administration/installation/index.html +46 -4
  408. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +47 -5
  409. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +46 -4
  410. nautobot/project-static/docs/user-guide/administration/installation/services.html +46 -4
  411. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +46 -4
  412. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +46 -4
  413. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +46 -4
  414. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +46 -4
  415. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +46 -4
  416. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +46 -4
  417. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +46 -4
  418. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +46 -4
  419. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +46 -4
  420. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +49 -8
  421. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +46 -4
  422. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +46 -4
  423. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +46 -4
  424. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +46 -4
  425. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +46 -4
  426. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +46 -4
  427. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +46 -4
  428. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +46 -4
  429. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +46 -4
  430. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +46 -4
  431. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +46 -4
  432. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +46 -4
  433. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +46 -4
  434. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +46 -4
  435. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +46 -4
  436. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +46 -4
  437. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +46 -4
  438. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +46 -4
  439. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +46 -4
  440. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +46 -4
  441. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +46 -4
  442. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +46 -4
  443. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +46 -4
  444. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +46 -4
  445. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +46 -4
  446. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +46 -4
  447. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +46 -4
  448. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +46 -4
  449. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +46 -4
  450. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +46 -4
  451. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +46 -4
  452. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +46 -4
  453. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +46 -4
  454. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +46 -4
  455. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +46 -4
  456. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +46 -4
  457. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +46 -4
  458. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +46 -4
  459. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +46 -4
  460. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +46 -4
  461. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +46 -4
  462. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +46 -4
  463. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +46 -4
  464. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +46 -4
  465. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +46 -4
  466. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +46 -4
  467. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +46 -4
  468. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +46 -4
  469. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +46 -4
  470. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +46 -4
  471. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +46 -4
  472. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +46 -4
  473. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +46 -4
  474. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +46 -4
  475. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +46 -4
  476. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +46 -4
  477. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +46 -4
  478. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +50 -12
  479. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +46 -4
  480. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +46 -4
  481. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +46 -4
  482. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +46 -4
  483. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +46 -4
  484. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +46 -4
  485. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +46 -4
  486. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +46 -4
  487. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +46 -4
  488. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +46 -4
  489. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +46 -4
  490. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +46 -4
  491. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +49 -7
  492. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +46 -4
  493. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +46 -4
  494. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +46 -4
  495. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +46 -4
  496. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +46 -4
  497. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +46 -4
  498. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +46 -4
  499. nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +46 -4
  500. nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +46 -4
  501. nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +46 -4
  502. nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +46 -4
  503. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +46 -4
  504. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +46 -4
  505. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +46 -4
  506. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +46 -4
  507. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +46 -4
  508. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +46 -4
  509. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +46 -4
  510. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +46 -4
  511. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +46 -4
  512. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +46 -4
  513. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +46 -4
  514. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +51 -7
  515. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +46 -4
  516. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/central-mode.png +0 -0
  517. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-add.png +0 -0
  518. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-create-1.png +0 -0
  519. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-create-2.png +0 -0
  520. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/radio-profile-add.png +0 -0
  521. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/radio-profile-create.png +0 -0
  522. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/supported-data-rate-add.png +0 -0
  523. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/supported-data-rate-create.png +0 -0
  524. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-add.png +0 -0
  525. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-create-1.png +0 -0
  526. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-create-2.png +0 -0
  527. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-network-add.png +0 -0
  528. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-network-create.png +0 -0
  529. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +46 -4
  530. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +46 -4
  531. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +49 -7
  532. nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +9444 -0
  533. nautobot/project-static/docs/user-guide/index.html +46 -4
  534. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +46 -4
  535. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +50 -8
  536. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +46 -4
  537. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +46 -4
  538. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +46 -4
  539. nautobot/project-static/docs/user-guide/platform-functionality/events.html +46 -4
  540. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +46 -4
  541. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +46 -4
  542. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +46 -4
  543. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +46 -4
  544. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +46 -4
  545. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +46 -4
  546. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +50 -7
  547. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +46 -4
  548. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +49 -7
  549. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +46 -4
  550. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +46 -4
  551. nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +9722 -0
  552. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +46 -4
  553. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +46 -4
  554. nautobot/project-static/docs/user-guide/platform-functionality/note.html +46 -4
  555. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +46 -4
  556. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +47 -5
  557. nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +46 -4
  558. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +46 -4
  559. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +94 -25
  560. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +74 -5
  561. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +46 -4
  562. nautobot/project-static/docs/user-guide/platform-functionality/role.html +46 -4
  563. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +46 -4
  564. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +46 -4
  565. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +46 -4
  566. nautobot/project-static/docs/user-guide/platform-functionality/status.html +46 -4
  567. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +46 -4
  568. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +46 -4
  569. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +46 -4
  570. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +46 -4
  571. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +46 -4
  572. nautobot/project-static/js/forms.js +1 -1
  573. nautobot/tenancy/api/views.py +9 -13
  574. nautobot/tenancy/views.py +4 -2
  575. nautobot/users/admin.py +1 -1
  576. nautobot/users/api/serializers.py +5 -4
  577. nautobot/users/api/views.py +3 -3
  578. nautobot/virtualization/api/serializers.py +4 -4
  579. nautobot/virtualization/api/views.py +5 -24
  580. nautobot/virtualization/filters.py +20 -3
  581. nautobot/virtualization/models.py +1 -1
  582. nautobot/virtualization/tables.py +2 -2
  583. nautobot/virtualization/templates/virtualization/cluster_edit.html +1 -7
  584. nautobot/virtualization/templates/virtualization/virtualmachine.html +1 -9
  585. nautobot/virtualization/templates/virtualization/virtualmachine_edit.html +2 -8
  586. nautobot/virtualization/tests/test_filters.py +17 -0
  587. nautobot/wireless/filters.py +2 -2
  588. nautobot/wireless/forms.py +1 -1
  589. nautobot/wireless/templates/wireless/wirelessnetwork_retrieve.html +1 -9
  590. nautobot/wireless/tests/integration/__init__.py +0 -0
  591. nautobot/wireless/tests/integration/test_radio_profile.py +42 -0
  592. nautobot/wireless/tests/test_filters.py +29 -1
  593. nautobot/wireless/tests/test_views.py +22 -1
  594. nautobot/wireless/views.py +0 -10
  595. {nautobot-2.4.0b1.dist-info → nautobot-2.4.1.dist-info}/METADATA +6 -6
  596. {nautobot-2.4.0b1.dist-info → nautobot-2.4.1.dist-info}/RECORD +600 -550
  597. {nautobot-2.4.0b1.dist-info → nautobot-2.4.1.dist-info}/WHEEL +1 -1
  598. nautobot/core/fixtures/user-data.json +0 -59
  599. {nautobot-2.4.0b1.dist-info → nautobot-2.4.1.dist-info}/LICENSE.txt +0 -0
  600. {nautobot-2.4.0b1.dist-info → nautobot-2.4.1.dist-info}/NOTICE +0 -0
  601. {nautobot-2.4.0b1.dist-info → nautobot-2.4.1.dist-info}/entry_points.txt +0 -0
nautobot/core/tables.py CHANGED
@@ -1,10 +1,10 @@
1
1
  import contextlib
2
2
  import logging
3
3
 
4
+ from django.conf import settings
4
5
  from django.contrib.auth.models import AnonymousUser
5
6
  from django.contrib.contenttypes.fields import GenericForeignKey
6
7
  from django.core.exceptions import FieldDoesNotExist, FieldError
7
- from django.db import NotSupportedError
8
8
  from django.db.models import Prefetch
9
9
  from django.db.models.fields.related import ForeignKey, RelatedField
10
10
  from django.db.models.fields.reverse_related import ManyToOneRel
@@ -14,13 +14,15 @@ from django.utils.http import urlencode
14
14
  from django.utils.safestring import mark_safe
15
15
  from django.utils.text import Truncator
16
16
  import django_tables2
17
- from django_tables2.data import TableQuerysetData
17
+ from django_tables2.data import TableData, TableQuerysetData
18
+ from django_tables2.rows import BoundRows
18
19
  from django_tables2.utils import Accessor, OrderBy, OrderByTuple
19
20
  from tree_queries.models import TreeNode
20
21
 
21
22
  from nautobot.core.models.querysets import count_related
22
23
  from nautobot.core.templatetags import helpers
23
24
  from nautobot.core.utils.lookup import get_model_for_view_name, get_related_field_for_models, get_route_for_model
25
+ from nautobot.core.utils.querysets import maybe_prefetch_related, maybe_select_related
24
26
  from nautobot.extras import choices, models
25
27
 
26
28
  logger = logging.getLogger(__name__)
@@ -46,8 +48,27 @@ class BaseTable(django_tables2.Table):
46
48
  user=None,
47
49
  hide_hierarchy_ui=False,
48
50
  order_by=None,
51
+ data_transform_callback=None,
49
52
  **kwargs,
50
53
  ):
54
+ """
55
+ Instantiate a BaseTable.
56
+
57
+ Args:
58
+ *args (list, optional): Passed through to django_tables2.Table
59
+ table_changes_pending (bool): TODO
60
+ saved_view (SavedView, optional): TODO
61
+ user (User, optional): TODO
62
+ hide_hierarchy_ui (bool): Whether to display or hide hierarchy indentation of nested objects.
63
+ order_by (list, optional): Field(s) to sort by
64
+ data_transform_callback (function, optional): A function that takes the given `data` as an input and
65
+ returns new data. Runs after all of the queryset auto-optimization performed by this class.
66
+ Used for example in IPAM views to inject "fake" records for "available" Prefixes, IPAddresses, or VLANs.
67
+ **kwargs (dict, optional): Passed through to django_tables2.Table
68
+ Warning:
69
+ Do not modify/set the `base_columns` attribute after BaseTable class is instantiated.
70
+ Do not modify/set the `base_columns` attribute after calling super().__init__() of BaseTable class.
71
+ """
51
72
  # Add custom field columns
52
73
  model = self._meta.model
53
74
 
@@ -89,6 +110,14 @@ class BaseTable(django_tables2.Table):
89
110
  # Init table
90
111
  super().__init__(*args, order_by=order_by, **kwargs)
91
112
 
113
+ if not isinstance(self.data, TableQuerysetData):
114
+ # LinkedCountColumns don't work properly if the data is a list of dicts instead of a queryset,
115
+ # as they rely on a `queryset.annotate()` call to gather the data.
116
+ self.exclude = [
117
+ *self.exclude,
118
+ *[column.name for column in self.columns if isinstance(column.column, LinkedCountColumn)],
119
+ ]
120
+
92
121
  # Don't show hierarchy if we're sorted
93
122
  if order_by is not None and hide_hierarchy_ui is None:
94
123
  hide_hierarchy_ui = True
@@ -122,7 +151,7 @@ class BaseTable(django_tables2.Table):
122
151
  columns = user.get_config(f"tables.{self.__class__.__name__}.columns")
123
152
  if columns:
124
153
  for name, column in self.base_columns.items():
125
- if name in columns:
154
+ if name in columns and name not in self.exclude:
126
155
  self.columns.show(name)
127
156
  else:
128
157
  self.columns.hide(name)
@@ -161,7 +190,8 @@ class BaseTable(django_tables2.Table):
161
190
  logger.error("Couldn't find model for %s", column.column.viewname)
162
191
  continue
163
192
  reverse_lookup = column.column.reverse_lookup or next(iter(column.column.url_params.keys()))
164
- count_fields.append((column.name, column_model, reverse_lookup))
193
+ distinct = column.column.distinct
194
+ count_fields.append((column.name, column_model, reverse_lookup, distinct))
165
195
  try:
166
196
  lookup = column.column.lookup or get_related_field_for_models(model, column_model).name
167
197
  # For some reason get_related_field_for_models(Tag, DynamicGroup) gives a M2M with the name
@@ -173,7 +203,8 @@ class BaseTable(django_tables2.Table):
173
203
  if lookup is not None:
174
204
  # Also attempt to prefetch the first matching record for display - see LinkedCountColumn
175
205
  prefetch_fields.append(
176
- Prefetch(lookup, column_model.objects.all()[:1], to_attr=f"{lookup}_list")
206
+ # Use order_by() because we don't care about ordering here and it's potentially expensive
207
+ Prefetch(lookup, column_model.objects.order_by()[:1], to_attr=f"{lookup}_list")
177
208
  )
178
209
  continue
179
210
 
@@ -209,75 +240,46 @@ class BaseTable(django_tables2.Table):
209
240
  prefetch_fields.append("__".join(prefetch_path))
210
241
 
211
242
  if select_fields:
212
- # Django doesn't allow .select_related() on a QuerySet that had .values()/.values_list() applied, or
213
- # one that has had union()/intersection()/difference() applied.
214
- # We can detect and avoid these cases the same way that Django itself does.
215
- if queryset._fields is not None:
216
- logger.debug(
217
- "NOT applying select_related(%s) to %s QuerySet as it includes .values()/.values_list()",
218
- select_fields,
219
- model.__name__,
220
- )
221
- elif queryset.query.combinator:
222
- logger.debug(
223
- "NOT applying select_related(%s) to %s QuerySet as it is a combinator query",
224
- select_fields,
225
- model.__name__,
226
- )
227
- else:
228
- logger.debug("Applying .select_related(%s) to %s QuerySet", select_fields, model.__name__)
229
- # Belt and suspenders - we should have avoided any error cases above, but be safe anyway:
230
- try:
231
- queryset = queryset.select_related(*select_fields)
232
- except (TypeError, ValueError, NotSupportedError) as exc:
233
- logger.warning(
234
- "Unexpected error when trying to .select_related() on %s QuerySet: %s",
235
- model.__name__,
236
- exc,
237
- )
243
+ queryset = maybe_select_related(queryset, select_fields)
238
244
 
239
245
  if prefetch_fields:
240
- if queryset.query.combinator:
241
- logger.debug(
242
- "NOT applying prefetch_related(%s) to %s QuerySet as it is a combinator query",
243
- prefetch_fields,
244
- model.__name__,
245
- )
246
- else:
247
- logger.debug("Applying .prefetch_related(%s) to %s QuerySet", prefetch_fields, model.__name__)
248
- # Belt and suspenders - we should have avoided any error cases above, but be safe anyway:
249
- try:
250
- queryset = queryset.prefetch_related(*prefetch_fields)
251
- except (AttributeError, TypeError, ValueError, NotSupportedError) as exc:
252
- logger.warning(
253
- "Unexpected error when trying to .prefetch_related() on %s QuerySet: %s",
254
- model.__name__,
255
- exc,
256
- )
246
+ queryset = maybe_prefetch_related(queryset, prefetch_fields)
257
247
 
258
248
  if count_fields:
259
- for column_name, column_model, lookup_name in count_fields:
249
+ for column_name, column_model, lookup_name, distinct in count_fields:
260
250
  if hasattr(queryset.first(), column_name):
261
251
  continue
262
252
  try:
263
253
  logger.debug(
264
- "Applying .annotate(%s=count_related(%s, %r) to %s QuerySet",
254
+ "Applying .annotate(%s=count_related(%s, %r, distinct=%s) to %s QuerySet",
265
255
  column_name,
266
256
  column_model.__name__,
267
257
  lookup_name,
258
+ distinct,
268
259
  model.__name__,
269
260
  )
270
- queryset = queryset.annotate(**{column_name: count_related(column_model, lookup_name)})
261
+ queryset = queryset.annotate(
262
+ **{column_name: count_related(column_model, lookup_name, distinct=distinct)}
263
+ )
271
264
  except FieldError:
272
265
  # No error message logged here as the above is *very much* best-effort
273
266
  pass
274
267
 
275
268
  self.data.data = queryset
276
269
 
270
+ # TODO: it would be better if we could apply this transformation and the above queryset optimizations
271
+ # **before** calling super().__init__(), but the current implementation works for now, though inelegant.
272
+ if data_transform_callback is not None:
273
+ self.data = TableData.from_data(data_transform_callback(self.data.data))
274
+ self.data.set_table(self)
275
+ self.rows = BoundRows(data=self.data, table=self, pinned_data=self.pinned_data)
276
+
277
277
  @property
278
278
  def configurable_columns(self):
279
279
  selected_columns = [
280
- (name, self.columns[name].verbose_name) for name in self.sequence if name not in ["pk", "actions"]
280
+ (name, column.verbose_name)
281
+ for name, column in self.columns.items()
282
+ if name in self.sequence and name not in ["pk", "actions"]
281
283
  ]
282
284
  available_columns = [
283
285
  (name, column.verbose_name)
@@ -288,7 +290,7 @@ class BaseTable(django_tables2.Table):
288
290
 
289
291
  @property
290
292
  def visible_columns(self):
291
- return [name for name in self.sequence if self.columns[name].visible]
293
+ return [name for name, column in self.columns.items() if column.visible and name not in self.exclude]
292
294
 
293
295
  @property
294
296
  def order_by(self):
@@ -443,7 +445,7 @@ class ChoiceFieldColumn(django_tables2.Column):
443
445
  choices. The CSS class is derived by calling .get_FOO_class() on the row record.
444
446
  """
445
447
 
446
- def render(self, record, bound_column, value): # pylint: disable=arguments-differ
448
+ def render(self, *, record, bound_column, value): # pylint: disable=arguments-differ # tables2 varies its kwargs
447
449
  if value:
448
450
  name = bound_column.name
449
451
  css_class = getattr(record, f"get_{name}_class")()
@@ -490,6 +492,7 @@ class LinkedCountColumn(django_tables2.Column):
490
492
  TODO: this currently does *not* support nested lookups via `__`. That may be solvable in the future.
491
493
  reverse_lookup (str, optional): The reverse lookup parameter to use to derive the count.
492
494
  If not specified, the first key in `url_params` will be implicitly used as the `reverse_lookup` value.
495
+ distinct (bool, optional): Parameter passed through to `count_related()`.
493
496
  **kwargs (dict, optional): As the parent Column class.
494
497
 
495
498
  Examples:
@@ -514,25 +517,37 @@ class LinkedCountColumn(django_tables2.Column):
514
517
  # We'd like to do the below but this module isn't currently smart enough to build the right Prefetch()
515
518
  # for a nested lookup:
516
519
  # lookup="circuit_terminations__circuit",
517
- # For the count, .annotate(circuit_count=count_related(Circuit, "circuit_terminations__cloud_network"))
520
+ # For the count,
521
+ # .annotate(circuit_count=count_related(Circuit, "circuit_terminations__cloud_network", distinct=True))
518
522
  reverse_lookup="circuit_terminations__cloud_network",
523
+ distinct=True,
519
524
  verbose_name="Circuits",
520
525
  )
521
526
  ```
522
527
  """
523
528
 
524
529
  def __init__(
525
- self, viewname, *args, view_kwargs=None, url_params=None, lookup=None, reverse_lookup=None, default=0, **kwargs
530
+ self,
531
+ viewname,
532
+ *args,
533
+ view_kwargs=None,
534
+ url_params=None,
535
+ lookup=None,
536
+ reverse_lookup=None,
537
+ distinct=False,
538
+ default=None,
539
+ **kwargs,
526
540
  ):
527
541
  self.viewname = viewname
528
542
  self.lookup = lookup
529
543
  self.view_kwargs = view_kwargs or {}
530
544
  self.url_params = url_params
531
545
  self.reverse_lookup = reverse_lookup or next(iter(url_params.keys()))
546
+ self.distinct = distinct
532
547
  self.model = get_model_for_view_name(self.viewname)
533
548
  super().__init__(*args, default=default, **kwargs)
534
549
 
535
- def render(self, bound_column, record, value): # pylint: disable=arguments-differ
550
+ def render(self, *, bound_column, record, value): # pylint: disable=arguments-differ # tables2 varies its kwargs
536
551
  related_record = None
537
552
  try:
538
553
  lookup = self.lookup or get_related_field_for_models(bound_column._table._meta.model, self.model).name
@@ -543,7 +558,10 @@ class LinkedCountColumn(django_tables2.Column):
543
558
  related_record = related_records[0]
544
559
  url = reverse(self.viewname, kwargs=self.view_kwargs)
545
560
  if self.url_params:
546
- url += "?" + urlencode({k: getattr(record, v) for k, v in self.url_params.items()})
561
+ url += "?" + urlencode(
562
+ # Replace None values with `FILTERS_NULL_CHOICE_VALUE` to handle URL parameters correctly
563
+ {k: (getattr(record, v) or settings.FILTERS_NULL_CHOICE_VALUE) for k, v in self.url_params.items()}
564
+ )
547
565
  if value > 1:
548
566
  return format_html('<a href="{}" class="badge">{}</a>', url, value)
549
567
  if related_record is not None:
@@ -616,7 +634,7 @@ class ComputedFieldColumn(django_tables2.Column):
616
634
 
617
635
  super().__init__(*args, **kwargs)
618
636
 
619
- def render(self, record):
637
+ def render(self, *, record): # pylint: disable=arguments-differ # tables2 varies its kwargs
620
638
  return self.computedfield.render({"obj": record})
621
639
 
622
640
 
@@ -635,7 +653,7 @@ class CustomFieldColumn(django_tables2.Column):
635
653
 
636
654
  super().__init__(*args, **kwargs)
637
655
 
638
- def render(self, record, bound_column, value): # pylint: disable=arguments-differ
656
+ def render(self, *, record, bound_column, value): # pylint: disable=arguments-differ # tables2 varies its kwargs
639
657
  if self.customfield.type == choices.CustomFieldTypeChoices.TYPE_BOOLEAN:
640
658
  template = helpers.render_boolean(value)
641
659
  elif self.customfield.type == choices.CustomFieldTypeChoices.TYPE_MULTISELECT:
@@ -666,7 +684,7 @@ class RelationshipColumn(django_tables2.Column):
666
684
  kwargs.setdefault("accessor", Accessor("associations"))
667
685
  super().__init__(orderable=False, *args, **kwargs)
668
686
 
669
- def render(self, record, value): # pylint: disable=arguments-differ
687
+ def render(self, *, record, value): # pylint: disable=arguments-differ # tables2 varies its kwargs
670
688
  # Filter the relationship associations by the relationship instance.
671
689
  # Since associations accessor returns all the relationship associations regardless of the relationship.
672
690
  value = [v for v in value if v.relationship == self.relationship]
@@ -0,0 +1,67 @@
1
+ {% extends 'base.html' %}
2
+ {% load helpers %}
3
+ {% load registry %}
4
+
5
+ {% block header %}
6
+ {{ block.super }}
7
+ {% if new_release %}
8
+ {# new_release is set only if the current user is a superuser or staff member #}
9
+ <div class="alert alert-info text-center" role="alert">
10
+ <i class="mdi mdi-information-outline"></i>
11
+ A new release is available: <a href="{{ new_release.url }}">Nautobot v{{ new_release.version }}</a> |
12
+ <a href="https://docs.nautobot.com/projects/core/en/v{{ new_release.version }}/installation/upgrading/">Upgrade instructions</a>
13
+ </div>
14
+ {% endif %}
15
+ {% endblock %}
16
+
17
+
18
+ {% block content %}
19
+ <h1>About Nautobot</h1>
20
+ <div class="row">
21
+ <div class="col-md-6">
22
+ <div class="panel panel-default">
23
+ <div class="panel-heading">
24
+ <strong>About</strong>
25
+ </div>
26
+ <div class="panel-body">
27
+ <a href="https://networktocode.com/nautobot/">Nautobot</a> is a product of <a href="https://networktocode.com/">Network to Code</a>. Nautobot is a Network Source of Truth and Network Automation Platform. Nautobot has an extensive ecosystem of solutions that can be installed to provide and power Network Automation feature sets. Please check the <a href="{% url 'apps:apps_marketplace' %}">App Marketplace</a> to learn more.
28
+ </div>
29
+ </div>
30
+ </div>
31
+ <div class="col-md-6">
32
+ <div class="panel panel-default">
33
+ <div class="panel-heading">
34
+ <strong>Support</strong>
35
+ </div>
36
+ <table class="table table-hover panel-body attr-table">
37
+ <tr>
38
+ <td>Support Contract Status</td>
39
+ <td>{{ support_contract_active | render_boolean }}</td>
40
+ </tr>
41
+ <tr>
42
+ <td>Contract Expiry Date</td>
43
+ <td>
44
+ {% if support_contract_active %}
45
+ {{ support_expiration_date | date }}
46
+ {% elif support_expiration_date %}
47
+ <span style="color: red;">{{ support_expiration_date | date }}</span>
48
+ {% else %}
49
+ &mdash;
50
+ {% endif %}
51
+ </td>
52
+ </tr>
53
+ <tr>
54
+ <td>&nbsp;</td>
55
+ <td>
56
+ {% if not support_expiration_date %}
57
+ To inquire about Nautobot support with Network to Code, please email <a href="mailto:info@networktocode.com">info@networktocode.com</a>.
58
+ {% else %}
59
+ If there is any question on the status of your Nautobot support contract with Network to Code, please email <a href="mailto:info@networktocode.com">info@networktocode.com</a>.
60
+ {% endif %}
61
+ </td>
62
+ </tr>
63
+ </table>
64
+ </div>
65
+ </div>
66
+ </div>
67
+ {% endblock %}
@@ -47,3 +47,6 @@
47
47
  <meta name="theme-color" content="#ffffff">
48
48
  <meta charset="UTF-8">
49
49
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
50
+ {% if settings.PUBLISH_ROBOTS_TXT %}
51
+ <meta name="robots" content="noindex, nofollow">
52
+ {% endif %}
@@ -93,6 +93,7 @@
93
93
  <span class="mdi mdi-chevron-down"></span>
94
94
  </a>
95
95
  <ul class="collapse nav-dropdown-menu" id="adminDropdown">
96
+ <li><a href="{% url 'about' %}"><i class="mdi mdi-information"></i> About</a></li>
96
97
  <li><a href="{% url 'user:profile' %}"><i class="mdi mdi-account-box"></i> Profile</a></li>
97
98
  {% if request.user.is_staff %}
98
99
  <li><a href="{% url 'worker_status' %}"><i class="mdi mdi-server-network"></i> Worker Status</a></li>
@@ -0,0 +1,9 @@
1
+ {% load form_helpers %}
2
+
3
+ <div class="panel panel-default">
4
+ <div class="panel-heading"><strong>Tenancy</strong></div>
5
+ <div class="panel-body">
6
+ {% render_field form.tenant_group %}
7
+ {% render_field form.tenant %}
8
+ </div>
9
+ </div>
@@ -0,0 +1,11 @@
1
+ {% load helpers %}
2
+
3
+ <tr>
4
+ <td>Tenant</td>
5
+ <td>
6
+ {% if object.tenant and object.tenant.tenant_group %}
7
+ {{ object.tenant.tenant_group|hyperlinked_object }} /
8
+ {% endif %}
9
+ {{ object.tenant|hyperlinked_object }}
10
+ </td>
11
+ </tr>
@@ -463,6 +463,16 @@ INSTALLATION_METRICS_ENABLED = is_truthy(os.getenv("NAUTOBOT_INSTALLATION_METRIC
463
463
  #
464
464
  # NAPALM_ARGS = {}
465
465
 
466
+ # Expiration date (YYYY-MM-DD) for an active Nautobot support contract with Network to Code.
467
+ # Displayed in the About page.
468
+ # if (
469
+ # "NAUTOBOT_NTC_SUPPORT_CONTRACT_EXPIRATION_DATE" in os.environ
470
+ # and os.environ["NAUTOBOT_NTC_SUPPORT_CONTRACT_EXPIRATION_DATE"] != ""
471
+ # ):
472
+ # NTC_SUPPORT_CONTRACT_EXPIRATION_DATE = datetime.date.fromisoformat(
473
+ # os.environ["NAUTOBOT_NTC_SUPPORT_CONTRACT_EXPIRATION_DATE"]
474
+ # )
475
+
466
476
  # Default number of objects to display per page of the UI and REST API. Default is 50
467
477
  #
468
478
  # if "NAUTOBOT_PAGINATE_COUNT" in os.environ and os.environ["NAUTOBOT_PAGINATE_COUNT"] != "":
@@ -493,6 +503,9 @@ INSTALLATION_METRICS_ENABLED = is_truthy(os.getenv("NAUTOBOT_INSTALLATION_METRIC
493
503
  # if "NAUTOBOT_PREFER_IPV4" in os.environ and os.environ["NAUTOBOT_PREFER_IPV4"] != "":
494
504
  # PREFER_IPV4 = is_truthy(os.environ["NAUTOBOT_PREFER_IPV4"])
495
505
 
506
+ # Publish a simple "no-index" robots.txt for Nautobot?
507
+ # PUBLISH_ROBOTS_TXT = is_truthy(os.getenv("NAUTOBOT_PUBLISH_ROBOTS_TXT", "True"))
508
+
496
509
  # Default height and width in pixels of a single rack unit in rendered rack elevations. Defaults are 22 and 230
497
510
  #
498
511
  # if (
@@ -65,3 +65,10 @@
65
65
  </div>
66
66
  {% endif %}
67
67
  {% endblock %}
68
+
69
+ {% block javascript %}
70
+ {{ block.super }}
71
+ <script>
72
+ var clipboard = new ClipboardJS('.btn');
73
+ </script>
74
+ {% endblock %}
@@ -10,7 +10,7 @@
10
10
  }
11
11
  #render_jinja_template_form textarea {
12
12
  resize: vertical;
13
- white-space: nowrap;
13
+ white-space: pre;
14
14
  }
15
15
 
16
16
  </style>
@@ -1,3 +1,3 @@
1
1
  {% load helpers %}
2
2
 
3
- {% if url_name %}<a href="{% url url_name %}?tags={{ tag.name }}">{% endif %}<span class="label label-default" style="color: {{ tag.color|fgcolor }}; background-color: #{{ tag.color }}">{{ tag }}</span>{% if url_name %}</a>{% endif %}
3
+ {% if url_name %}<a href="{% url url_name %}?tags={{ tag.name }}">{% endif %}<span class="label" style="color: {{ tag.color|fgcolor }}; background-color: #{{ tag.color }}">{{ tag }}</span>{% if url_name %}</a>{% endif %}
@@ -330,6 +330,7 @@
330
330
  <small>title for most object views</small>
331
331
  <span class="label label-default">Default</span>
332
332
  <span class="label label-primary">Primary</span>
333
+ <span class="label label-transparent">Transparent</span>
333
334
  <span class="label label-success">Success</span>
334
335
  <span class="label label-info">Info</span>
335
336
  <span class="label label-warning">Warning</span>
@@ -340,6 +341,7 @@
340
341
  <small>used for special purposes such as Location detail "badges"</small>
341
342
  <span class="label label-default">Default</span>
342
343
  <span class="label label-primary">Primary</span>
344
+ <span class="label label-transparent">Transparent</span>
343
345
  <span class="label label-success">Success</span>
344
346
  <span class="label label-info">Info</span>
345
347
  <span class="label label-warning">Warning</span>
@@ -350,6 +352,7 @@
350
352
  <small>title for object create/edit forms</small>
351
353
  <span class="label label-default">Default</span>
352
354
  <span class="label label-primary">Primary</span>
355
+ <span class="label label-transparent">Transparent</span>
353
356
  <span class="label label-success">Success</span>
354
357
  <span class="label label-info">Info</span>
355
358
  <span class="label label-warning">Warning</span>
@@ -360,6 +363,7 @@
360
363
  <small>used in modal titles and a few others</small>
361
364
  <span class="label label-default">Default</span>
362
365
  <span class="label label-primary">Primary</span>
366
+ <span class="label label-transparent">Transparent</span>
363
367
  <span class="label label-success">Success</span>
364
368
  <span class="label label-info">Info</span>
365
369
  <span class="label label-warning">Warning</span>
@@ -370,6 +374,7 @@
370
374
  <small>used in user profiles and cable traces</small>
371
375
  <span class="label label-default">Default</span>
372
376
  <span class="label label-primary">Primary</span>
377
+ <span class="label label-transparent">Transparent</span>
373
378
  <span class="label label-success">Success</span>
374
379
  <span class="label label-info">Info</span>
375
380
  <span class="label label-warning">Warning</span>
@@ -380,6 +385,7 @@
380
385
  <small>Unused in core</small>
381
386
  <span class="label label-default">Default</span>
382
387
  <span class="label label-primary">Primary</span>
388
+ <span class="label label-transparent">Transparent</span>
383
389
  <span class="label label-success">Success</span>
384
390
  <span class="label label-info">Info</span>
385
391
  <span class="label label-warning">Warning</span>
@@ -390,6 +396,7 @@
390
396
  <small>Small text</small>
391
397
  <span class="label label-default">Default</span>
392
398
  <span class="label label-primary">Primary</span>
399
+ <span class="label label-transparent">Transparent</span>
393
400
  <span class="label label-success">Success</span>
394
401
  <span class="label label-info">Info</span>
395
402
  <span class="label label-warning">Warning</span>
@@ -890,7 +890,13 @@ def saved_view_modal(
890
890
  "clear_view",
891
891
  ]
892
892
 
893
- table_name = lookup.get_table_for_model(model).__name__
893
+ view_class = lookup.get_view_for_model(model, "List")
894
+ table_name = None
895
+ if hasattr(view_class, "table"):
896
+ table_name = view_class.table.__name__
897
+ if hasattr(view_class, "table_class"):
898
+ table_name = view_class.table_class.__name__
899
+
894
900
  for param in non_filter_params:
895
901
  if param == "saved_view":
896
902
  current_saved_view_pk = filters_applied.pop(param, None)
@@ -1044,12 +1050,13 @@ def versioned_static(file_path):
1044
1050
 
1045
1051
 
1046
1052
  @register.simple_tag
1047
- def tree_hierarchy_ui_representation(tree_depth, hide_hierarchy_ui):
1053
+ def tree_hierarchy_ui_representation(tree_depth, hide_hierarchy_ui, base_depth=0):
1048
1054
  """Generates a visual representation of a tree record hierarchy using dots.
1049
1055
 
1050
1056
  Args:
1051
1057
  tree_depth (range): A range representing the depth of the tree nodes.
1052
1058
  hide_hierarchy_ui (bool): Indicates whether to hide the hierarchy UI.
1059
+ base_depth (int, optional): Starting depth (number of dots to skip rendering).
1053
1060
 
1054
1061
  Returns:
1055
1062
  str: A string containing dots (representing hierarchy levels) if `hide_hierarchy_ui` is False,
@@ -1057,6 +1064,8 @@ def tree_hierarchy_ui_representation(tree_depth, hide_hierarchy_ui):
1057
1064
  """
1058
1065
  if hide_hierarchy_ui or tree_depth == 0:
1059
1066
  return ""
1067
+ if isinstance(base_depth, int): # may be an empty string
1068
+ tree_depth = tree_depth[base_depth:]
1060
1069
  ui_representation = " ".join(['<i class="mdi mdi-circle-small"></i>' for _ in tree_depth])
1061
1070
  return mark_safe(ui_representation) # noqa: S308 # suspicious-mark-safe-usage, OK here since its just the `i` tag
1062
1071
 
@@ -21,23 +21,23 @@ from nautobot.extras.models import Job, JobResult
21
21
  __all__ = (
22
22
  "APITestCase",
23
23
  "APIViewTestCases",
24
+ "FilterTestCases",
25
+ "JobClassInfo",
26
+ "ModelTestCase",
27
+ "ModelViewTestCase",
28
+ "NautobotTestCaseMixin",
29
+ "NautobotTestClient",
30
+ "TestCase",
31
+ "ViewTestCases",
24
32
  "create_job_result_and_run_job",
25
33
  "create_test_user",
26
34
  "disable_warnings",
27
35
  "extract_form_failures",
28
36
  "extract_page_body",
29
- "FilterTestCases",
30
37
  "get_deletable_objects",
31
38
  "get_job_class_and_model",
32
- "JobClassInfo",
33
- "ModelTestCase",
34
- "ModelViewTestCase",
35
- "NautobotTestCaseMixin",
36
- "NautobotTestClient",
37
39
  "post_data",
38
40
  "run_job_for_testing",
39
- "TestCase",
40
- "ViewTestCases",
41
41
  )
42
42
 
43
43
  # Use the proper swappable User model