nautobot 2.4.16__py3-none-any.whl → 2.4.18__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 (434) hide show
  1. nautobot/apps/utils.py +2 -0
  2. nautobot/apps/views.py +2 -0
  3. nautobot/circuits/templates/circuits/circuittermination_retrieve.html +1 -8
  4. nautobot/circuits/templates/circuits/inc/circuit_termination_speed_fragment.html +9 -0
  5. nautobot/circuits/tests/integration/test_circuit.py +2 -2
  6. nautobot/circuits/views.py +32 -15
  7. nautobot/cloud/templates/cloud/cloudresourcetype_retrieve.html +3 -3
  8. nautobot/cloud/views.py +7 -0
  9. nautobot/core/apps/__init__.py +1 -0
  10. nautobot/core/celery/__init__.py +2 -1
  11. nautobot/core/filters.py +2 -2
  12. nautobot/core/settings.py +1 -0
  13. nautobot/core/settings.yaml +9 -0
  14. nautobot/core/tables.py +21 -23
  15. nautobot/core/templates/components/breadcrumbs.html +19 -0
  16. nautobot/core/templates/components/panel/panel.html +1 -1
  17. nautobot/core/templates/generic/object_changelog.html +0 -2
  18. nautobot/core/templates/generic/object_list.html +15 -12
  19. nautobot/core/templates/generic/object_notes.html +0 -2
  20. nautobot/core/templates/generic/object_retrieve.html +16 -9
  21. nautobot/core/templates/inc/paginator.html +3 -3
  22. nautobot/core/templates/inc/table.html +2 -2
  23. nautobot/core/templatetags/helpers.py +104 -6
  24. nautobot/core/templatetags/ui_framework.py +40 -5
  25. nautobot/core/testing/filters.py +37 -21
  26. nautobot/core/testing/mixins.py +1 -1
  27. nautobot/core/testing/views.py +27 -4
  28. nautobot/core/tests/test_tables.py +43 -6
  29. nautobot/core/tests/test_templatetags_ui_framework.py +146 -0
  30. nautobot/core/tests/test_titles.py +2 -2
  31. nautobot/core/tests/test_ui.py +14 -1
  32. nautobot/core/tests/test_views.py +45 -0
  33. nautobot/core/ui/breadcrumbs.py +13 -8
  34. nautobot/core/ui/bulk_buttons.py +53 -53
  35. nautobot/core/ui/object_detail.py +52 -9
  36. nautobot/core/ui/titles.py +9 -5
  37. nautobot/core/utils/data.py +13 -0
  38. nautobot/core/utils/deprecation.py +2 -0
  39. nautobot/core/views/__init__.py +24 -3
  40. nautobot/core/views/generic.py +42 -17
  41. nautobot/core/views/mixins.py +146 -12
  42. nautobot/core/views/utils.py +117 -0
  43. nautobot/dcim/migrations/0073_alter_powerport_power_factor_and_more.py +41 -0
  44. nautobot/dcim/models/device_component_templates.py +4 -2
  45. nautobot/dcim/models/device_components.py +3 -2
  46. nautobot/dcim/models/devices.py +4 -0
  47. nautobot/dcim/tables/__init__.py +2 -0
  48. nautobot/dcim/tables/devices.py +24 -0
  49. nautobot/dcim/tables/power.py +2 -2
  50. nautobot/dcim/templates/dcim/device/base.html +1 -11
  51. nautobot/dcim/templates/dcim/device_component.html +0 -19
  52. nautobot/dcim/templates/dcim/modulebay_retrieve.html +0 -16
  53. nautobot/dcim/templates/dcim/rack_elevation_list.html +4 -4
  54. nautobot/dcim/templates/dcim/virtualchassis_retrieve.html +1 -50
  55. nautobot/dcim/tests/test_views.py +41 -0
  56. nautobot/dcim/views.py +169 -39
  57. nautobot/extras/filters/mixins.py +1 -1
  58. nautobot/extras/forms/forms.py +15 -0
  59. nautobot/extras/models/customfields.py +45 -9
  60. nautobot/extras/models/groups.py +10 -1
  61. nautobot/extras/models/jobs.py +2 -2
  62. nautobot/extras/plugins/views.py +18 -5
  63. nautobot/extras/tables.py +4 -2
  64. nautobot/extras/templates/extras/configcontext_retrieve.html +1 -1
  65. nautobot/extras/templates/extras/configcontext_update.html +49 -49
  66. nautobot/extras/templates/extras/configcontextschema_retrieve.html +47 -47
  67. nautobot/extras/templates/extras/configcontextschema_update.html +18 -18
  68. nautobot/extras/templates/extras/customfield_retrieve.html +1 -128
  69. nautobot/extras/templates/extras/dynamicgroup.html +2 -99
  70. nautobot/extras/templates/extras/dynamicgroup_edit.html +2 -199
  71. nautobot/extras/templates/extras/dynamicgroup_retrieve.html +99 -0
  72. nautobot/extras/templates/extras/dynamicgroup_update.html +199 -0
  73. nautobot/extras/templates/extras/gitrepository.html +2 -82
  74. nautobot/extras/templates/extras/gitrepository_object_edit.html +2 -13
  75. nautobot/extras/templates/extras/gitrepository_retrieve.html +82 -0
  76. nautobot/extras/templates/extras/gitrepository_update.html +13 -0
  77. nautobot/extras/templates/extras/inc/job_table.html +1 -1
  78. nautobot/extras/templates/extras/inc/object_contact_header.html +2 -2
  79. nautobot/extras/templates/extras/note_retrieve.html +1 -53
  80. nautobot/extras/templates/extras/plugin_detail.html +3 -7
  81. nautobot/extras/templates/extras/plugins_list.html +0 -2
  82. nautobot/extras/templates/extras/tag_retrieve.html +1 -1
  83. nautobot/extras/templates/extras/tag_update.html +14 -14
  84. nautobot/extras/templates/extras/team_retrieve.html +1 -1
  85. nautobot/extras/tests/test_dynamicgroups.py +73 -18
  86. nautobot/extras/tests/test_models.py +216 -0
  87. nautobot/extras/tests/test_views.py +7 -2
  88. nautobot/extras/urls.py +2 -94
  89. nautobot/extras/views.py +425 -430
  90. nautobot/ipam/apps.py +1 -0
  91. nautobot/ipam/jobs/__init__.py +10 -0
  92. nautobot/ipam/jobs/cleanup.py +296 -0
  93. nautobot/ipam/models.py +301 -178
  94. nautobot/ipam/querysets.py +3 -3
  95. nautobot/ipam/signals.py +6 -1
  96. nautobot/ipam/templates/ipam/inc/ipadress_edit_header.html +3 -3
  97. nautobot/ipam/templates/ipam/inc/toggle_available.html +2 -2
  98. nautobot/ipam/templates/ipam/ipaddress_assign.html +1 -1
  99. nautobot/ipam/templates/ipam/prefix.html +0 -8
  100. nautobot/ipam/templates/ipam/prefix_list.html +1 -1
  101. nautobot/ipam/templates/ipam/vlan_retrieve.html +1 -77
  102. nautobot/ipam/tests/test_api.py +5 -0
  103. nautobot/ipam/tests/test_jobs.py +454 -0
  104. nautobot/ipam/tests/test_models.py +677 -122
  105. nautobot/ipam/tests/test_querysets.py +46 -0
  106. nautobot/ipam/tests/test_views.py +40 -164
  107. nautobot/ipam/urls.py +0 -11
  108. nautobot/ipam/utils/migrations.py +1 -1
  109. nautobot/ipam/utils/testing.py +9 -4
  110. nautobot/ipam/views.py +175 -235
  111. nautobot/project-static/docs/404.html +9 -6
  112. nautobot/project-static/docs/apps/index.html +9 -6
  113. nautobot/project-static/docs/apps/nautobot-apps.html +9 -6
  114. nautobot/project-static/docs/assets/javascripts/bundle.92b07e13.min.js +16 -0
  115. nautobot/project-static/docs/assets/javascripts/{bundle.50899def.min.js.map → bundle.92b07e13.min.js.map} +2 -2
  116. nautobot/project-static/docs/assets/javascripts/workers/{search.d50fe291.min.js → search.973d3a69.min.js} +4 -4
  117. nautobot/project-static/docs/assets/javascripts/workers/{search.d50fe291.min.js.map → search.973d3a69.min.js.map} +1 -1
  118. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +9 -6
  119. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +9 -6
  120. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +9 -6
  121. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +9 -6
  122. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +10 -7
  123. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +9 -6
  124. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +9 -6
  125. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +9 -6
  126. nautobot/project-static/docs/code-reference/nautobot/apps/events.html +9 -6
  127. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +9 -6
  128. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +9 -6
  129. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +9 -6
  130. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +9 -6
  131. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +9 -6
  132. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +9 -6
  133. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +11 -8
  134. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +9 -6
  135. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +9 -6
  136. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +11 -8
  137. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +81 -6
  138. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +73 -18
  139. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +9 -6
  140. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +69 -7
  141. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +402 -21
  142. nautobot/project-static/docs/development/apps/api/configuration-view.html +13 -10
  143. nautobot/project-static/docs/development/apps/api/database-backend-config.html +11 -8
  144. nautobot/project-static/docs/development/apps/api/models/django-admin.html +13 -10
  145. nautobot/project-static/docs/development/apps/api/models/global-search.html +10 -7
  146. nautobot/project-static/docs/development/apps/api/models/graphql.html +18 -15
  147. nautobot/project-static/docs/development/apps/api/models/index.html +14 -11
  148. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +12 -9
  149. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +15 -12
  150. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +9 -6
  151. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +15 -12
  152. nautobot/project-static/docs/development/apps/api/platform-features/index.html +9 -6
  153. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +11 -8
  154. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +16 -13
  155. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +12 -10305
  156. nautobot/project-static/docs/development/apps/api/platform-features/prepopulating-data.html +10722 -0
  157. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +15 -12
  158. nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +14 -11
  159. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +9 -6
  160. nautobot/project-static/docs/development/apps/api/prometheus.html +15 -12
  161. nautobot/project-static/docs/development/apps/api/setup.html +9 -6
  162. nautobot/project-static/docs/development/apps/api/testing.html +9 -6
  163. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +12 -9
  164. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +9 -6
  165. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +9 -6
  166. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +9 -6
  167. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +20 -17
  168. nautobot/project-static/docs/development/apps/api/views/base-template.html +9 -6
  169. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +15 -12
  170. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +14 -11
  171. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +9 -6
  172. nautobot/project-static/docs/development/apps/api/views/index.html +9 -6
  173. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +10 -7
  174. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +24 -21
  175. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +12 -9
  176. nautobot/project-static/docs/development/apps/api/views/notes.html +10 -7
  177. nautobot/project-static/docs/development/apps/api/views/rest-api.html +19 -16
  178. nautobot/project-static/docs/development/apps/api/views/urls.html +11 -8
  179. nautobot/project-static/docs/development/apps/index.html +9 -6
  180. nautobot/project-static/docs/development/apps/migration/code-updates.html +19 -16
  181. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +9 -6
  182. nautobot/project-static/docs/development/apps/migration/from-v1.html +9 -6
  183. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +22 -19
  184. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +9 -6
  185. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +9 -6
  186. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +9 -6
  187. nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +9 -6
  188. nautobot/project-static/docs/development/apps/migration/ui-component-framework/breadcrumbs-titles.html +14 -11
  189. nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +27 -24
  190. nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +20 -17
  191. nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +20 -17
  192. nautobot/project-static/docs/development/apps/porting-from-netbox.html +9 -6
  193. nautobot/project-static/docs/development/core/application-registry.html +23 -20
  194. nautobot/project-static/docs/development/core/best-practices.html +23 -20
  195. nautobot/project-static/docs/development/core/bootstrap-ui.html +9 -6
  196. nautobot/project-static/docs/development/core/caching.html +9 -6
  197. nautobot/project-static/docs/development/core/controllers.html +9 -6
  198. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +10 -7
  199. nautobot/project-static/docs/development/core/generic-views.html +9 -6
  200. nautobot/project-static/docs/development/core/getting-started.html +9 -21
  201. nautobot/project-static/docs/development/core/homepage.html +12 -9
  202. nautobot/project-static/docs/development/core/index.html +9 -6
  203. nautobot/project-static/docs/development/core/minikube-dev-environment-for-k8s-jobs.html +9 -6
  204. nautobot/project-static/docs/development/core/model-checklist.html +9 -6
  205. nautobot/project-static/docs/development/core/model-features.html +11 -8
  206. nautobot/project-static/docs/development/core/natural-keys.html +21 -18
  207. nautobot/project-static/docs/development/core/navigation-menu.html +10 -7
  208. nautobot/project-static/docs/development/core/release-checklist.html +9 -6
  209. nautobot/project-static/docs/development/core/role-internals.html +9 -6
  210. nautobot/project-static/docs/development/core/settings.html +9 -6
  211. nautobot/project-static/docs/development/core/style-guide.html +32 -29
  212. nautobot/project-static/docs/development/core/templates.html +9 -6
  213. nautobot/project-static/docs/development/core/testing.html +10 -7
  214. nautobot/project-static/docs/development/core/ui-component-framework.html +42 -44
  215. nautobot/project-static/docs/development/core/user-preferences.html +9 -6
  216. nautobot/project-static/docs/development/index.html +9 -6
  217. nautobot/project-static/docs/development/jobs/getting-started.html +13 -10
  218. nautobot/project-static/docs/development/jobs/index.html +9 -6
  219. nautobot/project-static/docs/development/jobs/installation.html +23 -20
  220. nautobot/project-static/docs/development/jobs/job-extensions.html +25 -22
  221. nautobot/project-static/docs/development/jobs/job-logging.html +12 -9
  222. nautobot/project-static/docs/development/jobs/job-patterns.html +45 -42
  223. nautobot/project-static/docs/development/jobs/job-structure.html +53 -50
  224. nautobot/project-static/docs/development/jobs/migration/from-v1.html +23 -20
  225. nautobot/project-static/docs/development/jobs/testing.html +14 -11
  226. nautobot/project-static/docs/index.html +9 -6
  227. nautobot/project-static/docs/objects.inv +0 -0
  228. nautobot/project-static/docs/overview/application_stack.html +9 -6
  229. nautobot/project-static/docs/overview/design_philosophy.html +9 -6
  230. nautobot/project-static/docs/release-notes/index.html +9 -6
  231. nautobot/project-static/docs/release-notes/version-1.0.html +9 -6
  232. nautobot/project-static/docs/release-notes/version-1.1.html +9 -6
  233. nautobot/project-static/docs/release-notes/version-1.2.html +10 -7
  234. nautobot/project-static/docs/release-notes/version-1.3.html +9 -6
  235. nautobot/project-static/docs/release-notes/version-1.4.html +9 -6
  236. nautobot/project-static/docs/release-notes/version-1.5.html +13 -10
  237. nautobot/project-static/docs/release-notes/version-1.6.html +9 -6
  238. nautobot/project-static/docs/release-notes/version-2.0.html +9 -6
  239. nautobot/project-static/docs/release-notes/version-2.1.html +9 -6
  240. nautobot/project-static/docs/release-notes/version-2.2.html +9 -6
  241. nautobot/project-static/docs/release-notes/version-2.3.html +9 -6
  242. nautobot/project-static/docs/release-notes/version-2.4.html +489 -6
  243. nautobot/project-static/docs/search/search_index.json +1 -1
  244. nautobot/project-static/docs/sitemap.xml +301 -301
  245. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  246. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +15 -12
  247. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +9 -6
  248. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +16 -13
  249. nautobot/project-static/docs/user-guide/administration/configuration/index.html +9 -6
  250. nautobot/project-static/docs/user-guide/administration/configuration/redis.html +9 -6
  251. nautobot/project-static/docs/user-guide/administration/configuration/settings.html +38 -8
  252. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +9 -6
  253. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +9 -6
  254. nautobot/project-static/docs/user-guide/administration/guides/docker.html +9 -6
  255. nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +9 -6
  256. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +9 -6
  257. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +9 -6
  258. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +9 -6
  259. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +9 -6
  260. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +16 -13
  261. nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +9 -6
  262. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +9 -6
  263. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +9 -6
  264. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +9 -6
  265. nautobot/project-static/docs/user-guide/administration/installation/index.html +9 -6
  266. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +9 -6
  267. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +9 -6
  268. nautobot/project-static/docs/user-guide/administration/installation/services.html +12 -9
  269. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +13 -10
  270. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +10 -7
  271. nautobot/project-static/docs/user-guide/administration/security/index.html +9 -6
  272. nautobot/project-static/docs/user-guide/administration/security/notices.html +9 -6
  273. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +9 -6
  274. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +10 -7
  275. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +9 -6
  276. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +9 -6
  277. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +9 -6
  278. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +9 -6
  279. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +9 -6
  280. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +9 -6
  281. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +9 -6
  282. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +15 -12
  283. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +9 -6
  284. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +9 -6
  285. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +9 -6
  286. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +9 -6
  287. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +9 -6
  288. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +9 -6
  289. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +9 -6
  290. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +9 -6
  291. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +9 -6
  292. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +9 -6
  293. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +9 -6
  294. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +9 -6
  295. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +9 -6
  296. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +9 -6
  297. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +9 -6
  298. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +9 -6
  299. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +9 -6
  300. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +9 -6
  301. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +9 -6
  302. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +9 -6
  303. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +9 -6
  304. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +9 -6
  305. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +9 -6
  306. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +9 -6
  307. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +13 -10
  308. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +9 -6
  309. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +9 -6
  310. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +9 -6
  311. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +9 -6
  312. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +9 -6
  313. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +9 -6
  314. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +9 -6
  315. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +9 -6
  316. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +9 -6
  317. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +9 -6
  318. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +9 -6
  319. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +9 -6
  320. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +9 -6
  321. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulefamily.html +9 -6
  322. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +9 -6
  323. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +9 -6
  324. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +9 -6
  325. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +9 -6
  326. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +9 -6
  327. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +9 -6
  328. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +9 -6
  329. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +9 -6
  330. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +9 -6
  331. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +9 -6
  332. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +9 -6
  333. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +9 -6
  334. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +9 -6
  335. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +9 -6
  336. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +9 -6
  337. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +9 -6
  338. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +9 -6
  339. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +9 -6
  340. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +9 -6
  341. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +11 -8
  342. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +11 -8
  343. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +41 -41
  344. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +9 -6
  345. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +197 -54
  346. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +9 -6
  347. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +9 -6
  348. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +9 -6
  349. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +9 -6
  350. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +9 -6
  351. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +9 -6
  352. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +9 -6
  353. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +9 -6
  354. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +9 -6
  355. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +9 -6
  356. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +9 -6
  357. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +9 -6
  358. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +9 -6
  359. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +9 -6
  360. nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +9 -6
  361. nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +9 -6
  362. nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +9 -6
  363. nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +9 -6
  364. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +9 -6
  365. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +9 -6
  366. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +9 -6
  367. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +9 -6
  368. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +9 -6
  369. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +9 -6
  370. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +9 -6
  371. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +9 -6
  372. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +9 -6
  373. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +9 -6
  374. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +9 -6
  375. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +9 -6
  376. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +13 -10
  377. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +9 -6
  378. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +9 -6
  379. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +9 -6
  380. nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +9 -6
  381. nautobot/project-static/docs/user-guide/index.html +9 -6
  382. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +9 -6
  383. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +9 -6
  384. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +10 -7
  385. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +9 -6
  386. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +9 -6
  387. nautobot/project-static/docs/user-guide/platform-functionality/events.html +11 -8
  388. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +9 -6
  389. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +9 -6
  390. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +9 -6
  391. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +9 -6
  392. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +9 -6
  393. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +9 -6
  394. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +9 -6
  395. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +9 -6
  396. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +9 -6
  397. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +9 -6
  398. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +9 -6
  399. nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +9 -6
  400. nautobot/project-static/docs/user-guide/platform-functionality/jobs/managing-jobs.html +9 -6
  401. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +9 -6
  402. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +9 -6
  403. nautobot/project-static/docs/user-guide/platform-functionality/note.html +9 -6
  404. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +12 -9
  405. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +9 -6
  406. nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +9 -6
  407. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +9 -6
  408. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +9 -6
  409. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +9 -6
  410. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +9 -6
  411. nautobot/project-static/docs/user-guide/platform-functionality/role.html +9 -6
  412. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +9 -6
  413. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +11 -8
  414. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +9 -6
  415. nautobot/project-static/docs/user-guide/platform-functionality/status.html +9 -6
  416. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +9 -6
  417. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +9 -6
  418. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +9 -6
  419. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +9 -6
  420. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +9 -6
  421. nautobot/project-static/fonts/UFL.txt +96 -96
  422. nautobot/project-static/img/nautobot_icon.svg +32 -34
  423. nautobot/project-static/js/forms.js +35 -2
  424. nautobot/project-static/js/table_sorting_indicator.js +0 -2
  425. nautobot/virtualization/filters.py +7 -0
  426. {nautobot-2.4.16.dist-info → nautobot-2.4.18.dist-info}/METADATA +8 -8
  427. {nautobot-2.4.16.dist-info → nautobot-2.4.18.dist-info}/RECORD +431 -421
  428. nautobot/core/templates/inc/breadcrumbs.html +0 -14
  429. nautobot/project-static/docs/assets/javascripts/bundle.50899def.min.js +0 -16
  430. nautobot/project-static/docs/requirements.txt +0 -14
  431. {nautobot-2.4.16.dist-info → nautobot-2.4.18.dist-info}/LICENSE.txt +0 -0
  432. {nautobot-2.4.16.dist-info → nautobot-2.4.18.dist-info}/NOTICE +0 -0
  433. {nautobot-2.4.16.dist-info → nautobot-2.4.18.dist-info}/WHEEL +0 -0
  434. {nautobot-2.4.16.dist-info → nautobot-2.4.18.dist-info}/entry_points.txt +0 -0
nautobot/apps/utils.py CHANGED
@@ -13,6 +13,7 @@ from nautobot.core.utils.data import (
13
13
  render_jinja2,
14
14
  shallow_compare_dict,
15
15
  to_meters,
16
+ validate_jinja2,
16
17
  )
17
18
  from nautobot.core.utils.deprecation import class_deprecated, class_deprecated_in_favor_of
18
19
  from nautobot.core.utils.filtering import (
@@ -139,5 +140,6 @@ __all__ = (
139
140
  "swap_status_initials",
140
141
  "task_queues_as_choices",
141
142
  "to_meters",
143
+ "validate_jinja2",
142
144
  "wrap_model_clean_methods",
143
145
  )
nautobot/apps/views.py CHANGED
@@ -30,6 +30,7 @@ from nautobot.core.views.mixins import (
30
30
  ObjectListViewMixin,
31
31
  ObjectNotesViewMixin,
32
32
  ObjectPermissionRequiredMixin,
33
+ UIComponentsMixin,
33
34
  )
34
35
  from nautobot.core.views.paginator import EnhancedPage, EnhancedPaginator, get_paginate_count
35
36
  from nautobot.core.views.renderers import NautobotHTMLRenderer
@@ -78,6 +79,7 @@ __all__ = (
78
79
  "ObjectNotesViewMixin",
79
80
  "ObjectPermissionRequiredMixin",
80
81
  "ObjectView",
82
+ "UIComponentsMixin",
81
83
  "check_and_call_git_repository_function",
82
84
  "check_filter_for_display",
83
85
  "csv_format",
@@ -1,9 +1,2 @@
1
1
  {% extends 'generic/object_retrieve.html' %}
2
- {% load helpers %}
3
-
4
- {% block breadcrumbs %}
5
- <li><a href="{% url 'circuits:circuit_list' %}">Circuits</a></li>
6
- <li><a href="{% url 'circuits:circuit_list' %}?provider={{ object.circuit.provider.pk }}">{{ object.circuit.provider }}</a></li>
7
- <li>{{ object.circuit|hyperlinked_object }}</li>
8
- <li>{{ object|hyperlinked_object }}</li>
9
- {% endblock breadcrumbs %}
2
+ {% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
@@ -0,0 +1,9 @@
1
+ {% spaceless %}
2
+ {% load helpers %}
3
+ {% if termination.port_speed and termination.upstream_speed %}
4
+ <i class="mdi mdi-arrow-down-bold" title="Downstream"></i>{{ termination.port_speed|humanize_speed }}&nbsp;
5
+ <i class="mdi mdi-arrow-up-bold" title="Upstream"></i>{{ termination.upstream_speed|humanize_speed }}
6
+ {% else %}
7
+ {{ termination.port_speed|humanize_speed|placeholder }}
8
+ {% endif %}
9
+ {% endspaceless %}
@@ -128,8 +128,8 @@ class CircuitTestCase(SeleniumTestCase, ObjectsListMixin, ObjectDetailsMixin):
128
128
  # Assert that value are properly set
129
129
  panel_label = f"Termination - {side} Side"
130
130
  self.assertPanelValue(panel_label, "Location", self.location.name)
131
- self.assertPanelValue(panel_label, "Port Speed (Kbps)", port_speed)
132
- self.assertPanelValue(panel_label, "Upstream Speed (Kbps)", upstream_speed)
131
+ self.assertPanelValue(panel_label, "Speed", port_speed)
132
+ self.assertPanelValue(panel_label, "Speed", upstream_speed)
133
133
  self.assertPanelValue(panel_label, "Cross-connect ID", xconnect_id)
134
134
  self.assertPanelValue(panel_label, "Patch Panel/port(s)", pp_info)
135
135
  self.assertPanelValue(panel_label, "Description", description)
@@ -5,6 +5,7 @@ from django.utils.html import format_html, format_html_join
5
5
 
6
6
  from nautobot.core.forms import ConfirmationForm
7
7
  from nautobot.core.templatetags import helpers
8
+ from nautobot.core.ui.breadcrumbs import Breadcrumbs, InstanceBreadcrumbItem, ModelBreadcrumbItem
8
9
  from nautobot.core.ui.choices import SectionChoices
9
10
  from nautobot.core.ui.object_detail import (
10
11
  ObjectDetailContent,
@@ -58,6 +59,10 @@ class CircuitTerminationObjectFieldsPanel(ObjectFieldsPanel):
58
59
  def render_key(self, key, value, context):
59
60
  if key == "connected_endpoint":
60
61
  return "IP Addressing"
62
+
63
+ if key == "port_speed":
64
+ return "Speed"
65
+
61
66
  return super().render_key(key, value, context)
62
67
 
63
68
  def render_value(self, key, value, context):
@@ -80,6 +85,10 @@ class CircuitTerminationObjectFieldsPanel(ObjectFieldsPanel):
80
85
  "{} ({})",
81
86
  ((helpers.hyperlinked_object(ip), getattr(ip, "vrf", None) or "Global") for ip in ip_addresses.all()),
82
87
  )
88
+
89
+ if key == "port_speed":
90
+ return render_component_template("circuits/inc/circuit_termination_speed_fragment.html", context)
91
+
83
92
  return super().render_value(key, value, context)
84
93
 
85
94
 
@@ -93,6 +102,20 @@ class CircuitTerminationUIViewSet(NautobotUIViewSet):
93
102
  serializer_class = serializers.CircuitTerminationSerializer
94
103
  table_class = tables.CircuitTerminationTable
95
104
 
105
+ breadcrumbs = Breadcrumbs(
106
+ items={
107
+ "detail": [
108
+ ModelBreadcrumbItem(model=Circuit),
109
+ ModelBreadcrumbItem(
110
+ model=Circuit,
111
+ label=lambda c: c["object"].circuit.provider,
112
+ reverse_query_params=lambda c: {"provider": c["object"].circuit.provider.pk},
113
+ ),
114
+ InstanceBreadcrumbItem(instance=lambda c: c["object"].circuit),
115
+ ]
116
+ }
117
+ )
118
+
96
119
  object_detail_content = ObjectDetailContent(
97
120
  panels=(
98
121
  CircuitTerminationObjectFieldsPanel(
@@ -104,7 +127,6 @@ class CircuitTerminationUIViewSet(NautobotUIViewSet):
104
127
  "cloud_network",
105
128
  "cable",
106
129
  "port_speed",
107
- "upstream_speed",
108
130
  "connected_endpoint",
109
131
  "xconnect_id",
110
132
  "pp_info",
@@ -115,15 +137,7 @@ class CircuitTerminationUIViewSet(NautobotUIViewSet):
115
137
  "provider_network",
116
138
  "cloud_network",
117
139
  "port_speed",
118
- "upstream_speed",
119
- ],
120
- exclude_fields=[
121
- "circuit",
122
140
  ],
123
- value_transforms={
124
- "port_speed": [helpers.humanize_speed],
125
- "upstream_speed": [helpers.humanize_speed],
126
- },
127
141
  ),
128
142
  )
129
143
  )
@@ -188,17 +202,12 @@ class CircuitUIViewSet(NautobotUIViewSet):
188
202
  "provider_network",
189
203
  "cloud_network",
190
204
  "port_speed",
191
- "upstream_speed",
192
205
  "ip_addresses",
193
206
  "xconnect_id",
194
207
  "pp_info",
195
208
  "description",
196
209
  ),
197
- value_transforms={
198
- "port_speed": [helpers.humanize_speed, helpers.placeholder],
199
- "upstream_speed": [helpers.humanize_speed],
200
- },
201
- hide_if_unset=("location", "provider_network", "cloud_network", "upstream_speed"),
210
+ hide_if_unset=("location", "provider_network", "cloud_network"),
202
211
  ignore_nonexistent_fields=True, # ip_addresses may be undefined
203
212
  header_extra_content_template_path="circuits/inc/circuit_termination_header_extra_content.html",
204
213
  **kwargs,
@@ -245,6 +254,10 @@ class CircuitUIViewSet(NautobotUIViewSet):
245
254
  )
246
255
  if key == "ip_addresses":
247
256
  return "IP Addressing"
257
+
258
+ if key == "port_speed":
259
+ return "Speed"
260
+
248
261
  return super().render_key(key, value, context)
249
262
 
250
263
  def render_value(self, key, value, context):
@@ -257,6 +270,10 @@ class CircuitUIViewSet(NautobotUIViewSet):
257
270
  if not context["termination"].location:
258
271
  return ""
259
272
  return render_component_template("circuits/inc/circuit_termination_cable_fragment.html", context)
273
+
274
+ if key == "port_speed":
275
+ return render_component_template("circuits/inc/circuit_termination_speed_fragment.html", context)
276
+
260
277
  return super().render_value(key, value, context)
261
278
 
262
279
  def queryset_list_url_filter(self, key, value, context):
@@ -1,4 +1,4 @@
1
- {% extends 'generic/object_retrieve.html' %}
2
- {% block extra_breadcrumbs %}
3
- <li><a href="{% url 'cloud:cloudresourcetype_list' %}?provider={{ object.provider.pk }}">{{ object.provider }}</a></li>
1
+ {% extends 'generic/object_retrieve.html' %}
2
+ {% block extra_breadcrumbs %}
3
+ <li><a href="{% url 'cloud:cloudresourcetype_list' %}?provider={{ object.provider.pk }}">{{ object.provider }}</a></li>
4
4
  {% endblock extra_breadcrumbs %}
nautobot/cloud/views.py CHANGED
@@ -94,6 +94,7 @@ class CloudNetworkUIViewSet(NautobotUIViewSet):
94
94
  table_class=CloudNetworkTable,
95
95
  table_filter="parent",
96
96
  tab_id="children",
97
+ include_paginator=True,
97
98
  ),
98
99
  ),
99
100
  ),
@@ -111,6 +112,7 @@ class CloudNetworkUIViewSet(NautobotUIViewSet):
111
112
  table_filter="cloud_networks",
112
113
  exclude_columns=("location_count", "vlan"),
113
114
  tab_id="prefixes",
115
+ include_paginator=True,
114
116
  ),
115
117
  ),
116
118
  ),
@@ -129,6 +131,7 @@ class CloudNetworkUIViewSet(NautobotUIViewSet):
129
131
  related_field_name="cloud_network",
130
132
  exclude_columns=("circuit_termination_a", "circuit_termination_z"),
131
133
  tab_id="circuits",
134
+ include_paginator=True,
132
135
  ),
133
136
  ),
134
137
  ),
@@ -146,6 +149,7 @@ class CloudNetworkUIViewSet(NautobotUIViewSet):
146
149
  table_filter="cloud_networks",
147
150
  exclude_columns=("cloud_network_count"),
148
151
  tab_id="cloud_services",
152
+ include_paginator=True,
149
153
  ),
150
154
  ),
151
155
  ),
@@ -222,6 +226,7 @@ class CloudResourceTypeUIViewSet(NautobotUIViewSet):
222
226
  table_class=CloudNetworkTable,
223
227
  table_filter="cloud_resource_type",
224
228
  tab_id="networks",
229
+ include_paginator=True,
225
230
  ),
226
231
  ),
227
232
  ),
@@ -238,6 +243,7 @@ class CloudResourceTypeUIViewSet(NautobotUIViewSet):
238
243
  table_class=CloudServiceTable,
239
244
  table_filter="cloud_resource_type",
240
245
  tab_id="services",
246
+ include_paginator=True,
241
247
  ),
242
248
  ),
243
249
  ),
@@ -302,6 +308,7 @@ class CloudServiceUIViewSet(NautobotUIViewSet):
302
308
  table_filter="cloud_services",
303
309
  tab_id="cloud_networks",
304
310
  add_button_route=None,
311
+ include_paginator=True,
305
312
  ),
306
313
  ),
307
314
  ),
@@ -337,6 +337,7 @@ class CoreConfig(NautobotConfig):
337
337
  from graphene_django.converter import convert_django_field
338
338
 
339
339
  from nautobot.core.graphql import BigInteger
340
+ import nautobot.core.jobs # noqa: F401 # unused-import -- but this import registers the system jobs
340
341
 
341
342
  @convert_django_field.register(JSONField)
342
343
  def convert_json(field, registry=None): # pylint: disable=redefined-outer-name
@@ -54,7 +54,8 @@ def import_jobs(sender=None, **kwargs):
54
54
 
55
55
  Note that app-provided jobs are automatically imported at startup time via NautobotAppConfig.ready()
56
56
  """
57
- import nautobot.core.jobs # noqa: F401
57
+ import nautobot.core.jobs
58
+ import nautobot.ipam.jobs # noqa: F401
58
59
 
59
60
  _import_jobs_from_jobs_root()
60
61
  _import_dynamic_jobs_from_apps()
nautobot/core/filters.py CHANGED
@@ -175,7 +175,7 @@ class RelatedMembershipBooleanFilter(django_filters.BooleanFilter):
175
175
  )
176
176
 
177
177
  def filter(self, qs, value):
178
- if value in EMPTY_VALUES:
178
+ if value in EMPTY_VALUES or (hasattr(value, "exists") and not value.exists()):
179
179
  return qs
180
180
  if self.distinct:
181
181
  qs = qs.distinct()
@@ -542,7 +542,7 @@ class TreeNodeMultipleChoiceFilter(NaturalKeyOrPKMultipleChoiceFilter):
542
542
  return query
543
543
 
544
544
  def filter(self, qs, value):
545
- if value in EMPTY_VALUES:
545
+ if value in EMPTY_VALUES or (hasattr(value, "exists") and not value.exists()):
546
546
  return qs
547
547
 
548
548
  # Fetch the generated Q object and filter the incoming qs with it before passing it along.
nautobot/core/settings.py CHANGED
@@ -157,6 +157,7 @@ METRICS_AUTHENTICATED = is_truthy(os.getenv("NAUTOBOT_METRICS_AUTHENTICATED", "F
157
157
  METRICS_DISABLED_APPS = []
158
158
  if "NAUTOBOT_METRICS_DISABLED_APPS" in os.environ and os.environ["NAUTOBOT_METRICS_DISABLED_APPS"] != "":
159
159
  METRICS_DISABLED_APPS = os.getenv("NAUTOBOT_METRICS_DISABLED_APPS", "").split(_CONFIG_SETTING_SEPARATOR)
160
+ METRICS_EXPERIMENTAL_CACHING_DURATION = int(os.getenv("NAUTOBOT_METRICS_EXPERIMENTAL_CACHING_DURATION", "0"))
160
161
 
161
162
  # Napalm
162
163
  NAPALM_ARGS = {}
@@ -1377,6 +1377,15 @@ properties:
1377
1377
  see_also:
1378
1378
  "Guide to Nautobot Prometheus metrics": "../guides/prometheus-metrics.md"
1379
1379
  type: "boolean"
1380
+ METRICS_EXPERIMENTAL_CACHING_DURATION:
1381
+ default: 0
1382
+ description: >-
1383
+ The number of seconds to cache Nautobot App metrics before refreshing them.
1384
+ A value of `0` means no caching (i.e. always recompute metrics on each request). This feature is experimental
1385
+ and may change or be removed in a future release, including patch releases.
1386
+ environment_variable: "NAUTOBOT_METRICS_EXPERIMENTAL_CACHING_DURATION"
1387
+ type: "integer"
1388
+ version_added: "2.4.18"
1380
1389
  NAPALM_ARGS:
1381
1390
  additionalProperties: true
1382
1391
  default: {}
nautobot/core/tables.py CHANGED
@@ -17,7 +17,6 @@ import django_tables2
17
17
  from django_tables2.data import TableData, TableQuerysetData
18
18
  from django_tables2.rows import BoundRows
19
19
  from django_tables2.utils import Accessor, OrderBy, OrderByTuple
20
- from tree_queries.models import TreeNode
21
20
 
22
21
  from nautobot.core.models.querysets import count_related
23
22
  from nautobot.core.templatetags import helpers
@@ -107,6 +106,12 @@ class BaseTable(django_tables2.Table):
107
106
  if order_by is None and saved_view is not None:
108
107
  order_by = saved_view.config.get("sort_order", None)
109
108
 
109
+ # Don't show hierarchy if we're sorted
110
+ if order_by is not None and hide_hierarchy_ui is None:
111
+ hide_hierarchy_ui = True
112
+
113
+ self.hide_hierarchy_ui = hide_hierarchy_ui
114
+
110
115
  # Init table
111
116
  super().__init__(*args, order_by=order_by, **kwargs)
112
117
 
@@ -118,12 +123,6 @@ class BaseTable(django_tables2.Table):
118
123
  *[column.name for column in self.columns if isinstance(column.column, LinkedCountColumn)],
119
124
  ]
120
125
 
121
- # Don't show hierarchy if we're sorted
122
- if order_by is not None and hide_hierarchy_ui is None:
123
- hide_hierarchy_ui = True
124
-
125
- self.hide_hierarchy_ui = hide_hierarchy_ui
126
-
127
126
  # Set default empty_text if none was provided
128
127
  if self.empty_text is None:
129
128
  self.empty_text = f"No {self._meta.model._meta.verbose_name_plural} found"
@@ -304,6 +303,10 @@ class BaseTable(django_tables2.Table):
304
303
  Arguments:
305
304
  value: iterable or comma separated string of order by aliases.
306
305
  """
306
+ # The below block of code is copied from Table.order_by()
307
+ # due to limitations in directly calling parent class methods within a property setter.
308
+ # See Python bug report: https://bugs.python.org/issue14965
309
+
307
310
  # collapse empty values to ()
308
311
  order_by = () if not value else value
309
312
  # accept string
@@ -316,22 +319,17 @@ class BaseTable(django_tables2.Table):
316
319
  valid.append(alias)
317
320
  self._order_by = OrderByTuple(valid)
318
321
 
319
- # The above block of code is copied from super().order_by
320
- # due to limitations in directly calling parent class methods within a property setter.
321
- # See Python bug report: https://bugs.python.org/issue14965
322
- model = getattr(self.Meta, "model", None)
323
- if model and issubclass(model, TreeNode):
324
- # Use the TreeNode model's approach to sorting
325
- queryset = self.data.data
326
- # If the data passed into the Table is a list (as in cases like BulkImport post),
327
- # convert this list to a queryset.
328
- # This ensures consistent behavior regardless of the input type.
329
- if isinstance(self.data.data, list):
330
- queryset = model.objects.filter(pk__in=[instance.pk for instance in self.data.data])
331
- self.data.data = queryset.extra(order_by=self._order_by)
332
- else:
333
- # Otherwise, use the default sorting method
334
- self.data.order_by(self._order_by)
322
+ # Nautobot-specific logic begins here
323
+ if self._order_by:
324
+ self.hide_hierarchy_ui = True
325
+ if isinstance(self.data.data, QuerySet) and hasattr(self.data.data, "without_tree_fields"):
326
+ self.data.data = self.data.data.without_tree_fields()
327
+ elif not self.hide_hierarchy_ui:
328
+ if isinstance(self.data.data, QuerySet) and hasattr(self.data.data, "with_tree_fields"):
329
+ self.data.data = self.data.data.with_tree_fields()
330
+
331
+ # Resume base class implementation
332
+ self.data.order_by(self._order_by)
335
333
 
336
334
  def add_conditional_prefetch(self, table_field, db_column=None, prefetch=None):
337
335
  """Conditionally prefetch the specified database column if the related table field is visible.
@@ -0,0 +1,19 @@
1
+ {% load helpers %}
2
+
3
+ <ol class="breadcrumb">
4
+ {% block breadcrumbs %}
5
+ {% if legacy_breadcrumbs %}
6
+ {{ legacy_breadcrumbs | safe }}
7
+ {% else %}
8
+ {% for url, title in breadcrumbs_items %}
9
+ <li>
10
+ {% if url %}
11
+ <a href="{{ url }}">{{ title }}</a>
12
+ {% else %}
13
+ {{ title }}
14
+ {% endif %}
15
+ </li>
16
+ {% endfor %}
17
+ {% endif %}
18
+ {% endblock %}
19
+ </ol>
@@ -15,6 +15,6 @@
15
15
  {% endif %}
16
16
  </div>
17
17
 
18
- {% if body_content_table.paginator %}
18
+ {% if include_paginator and body_content_table.paginator%}
19
19
  {% include 'inc/paginator.html' with paginator=body_content_table.paginator page=body_content_table.page %}
20
20
  {% endif %}
@@ -1,7 +1,5 @@
1
1
  {% extends base_template %}
2
2
 
3
- {% block title %}{{ block.super }} - Change Log{% endblock %}
4
-
5
3
  {% block content %}
6
4
  {% include 'panel_table.html' %}
7
5
  {% include 'inc/paginator.html' with paginator=table.paginator page=table.page %}
@@ -11,19 +11,22 @@
11
11
  {% block header %}
12
12
  <div class="row noprint">
13
13
  <div class="{% if search_form %}col-sm-8 col-md-9 {% else %} col-md-12 {% endif %}">
14
- {% if breadcrumbs is not None %}
15
- {% render_breadcrumbs %}
16
- {% else %}
17
- {# TODO: remove this fragment after breadcrumbs implementation in generic views like ConsoleConnectionsListView #}
18
- <ol class="breadcrumb">
19
- {% block breadcrumbs %}
20
- {% if list_url %}
21
- <li><a href="{% url list_url %}">{{ title }}</a></li>
22
- {% endif %}
23
- {% block extra_breadcrumbs %}{% endblock extra_breadcrumbs %}
24
- {% endblock breadcrumbs %}
25
- </ol>
14
+ {% captureas default_breadcrumbs %}
15
+ {% if list_url %}
16
+ <li><a href="{% url list_url %}">{{ title }}</a></li>
26
17
  {% endif %}
18
+ {% endcaptureas %}
19
+
20
+ {% captureas block_breadcrumbs %}
21
+ {% block breadcrumbs %}
22
+ {% if list_url %}
23
+ <li><a href="{% url list_url %}">{{ title }}</a></li>
24
+ {% endif %}
25
+ {% block extra_breadcrumbs %}{% endblock extra_breadcrumbs %}
26
+ {% endblock breadcrumbs %}
27
+ {% endcaptureas %}
28
+
29
+ {% render_breadcrumbs default_breadcrumbs block_breadcrumbs %}
27
30
  </div>
28
31
  {% if search_form %}
29
32
  <div class="col-sm-4 col-md-3">
@@ -2,8 +2,6 @@
2
2
  {% load helpers %}
3
3
  {% load form_helpers %}
4
4
 
5
- {% block title %}{{ block.super }} - Notes{% endblock %}
6
-
7
5
  {% block content %}
8
6
  {% if perms.extras.add_note %}
9
7
  <form action="{% url 'extras:note_add' %}?return_url={{ request.path }}?tab=notes" method="post" enctype="multipart/form-data" class="form form-horizontal">
@@ -14,17 +14,24 @@
14
14
  <div class="row noprint">
15
15
  {% with list_url=object|validated_viewname:"list" %}
16
16
  <div class="col-sm-8 col-md-9">
17
- <ol class="breadcrumb">
17
+ {% captureas default_breadcrumbs %}
18
+ {% with list_url=object|validated_viewname:"list" %}
19
+ <li><a href="{% url list_url %}">{{ verbose_name_plural|bettertitle }}</a></li>
20
+ {% endwith %}
21
+ <li>{{ object|hyperlinked_object }}</li>
22
+ {% endcaptureas %}
23
+
24
+ {% captureas block_breadcrumbs %}
18
25
  {% block breadcrumbs %}
19
- {% if list_url %}
20
- <li><a href="{% url list_url %}">
21
- {{ verbose_name_plural|bettertitle }}
22
- </a></li>
23
- {% endif %}
26
+ {% with list_url=object|validated_viewname:"list" %}
27
+ <li><a href="{% url list_url %}">{{ verbose_name_plural|bettertitle }}</a></li>
28
+ {% endwith %}
24
29
  {% block extra_breadcrumbs %}{% endblock extra_breadcrumbs %}
25
30
  <li>{{ object|hyperlinked_object }}</li>
26
- {% endblock breadcrumbs %}
27
- </ol>
31
+ {% endblock %}
32
+ {% endcaptureas %}
33
+
34
+ {% render_breadcrumbs default_breadcrumbs block_breadcrumbs %}
28
35
  </div>
29
36
  {% if list_url %}
30
37
  <div class="col-sm-4 col-md-3">
@@ -55,7 +62,7 @@
55
62
  {% block masthead %}
56
63
  <h1>
57
64
  <span class="hover_copy">
58
- <span id="copy_title">{% block title %}{{object.display|default:object}}{% endblock %}</span>
65
+ <span id="copy_title">{% block title %}{% render_title %}{% endblock %}</span>
59
66
  <button type="button" class="btn btn-inline btn-default hover_copy_button" data-clipboard-text="{{ object.display | default:object }}">
60
67
  <span class="mdi mdi-content-copy"></span>
61
68
  </button>
@@ -5,17 +5,17 @@
5
5
  <nav>
6
6
  <ul class="pagination pull-right">
7
7
  {% if page.has_previous %}
8
- <li><a href="{% querystring request page=page.previous_page_number %}"><i class="mdi mdi-chevron-double-left"></i></a></li>
8
+ <li><a href="{% legacy_querystring request page=page.previous_page_number %}"><i class="mdi mdi-chevron-double-left"></i></a></li>
9
9
  {% endif %}
10
10
  {% for p in page.smart_pages %}
11
11
  {% if p %}
12
- <li{% if page.number == p %} class="active"{% endif %}><a href="{% querystring request page=p %}">{{ p }}</a></li>
12
+ <li{% if page.number == p %} class="active"{% endif %}><a href="{% legacy_querystring request page=p %}">{{ p }}</a></li>
13
13
  {% else %}
14
14
  <li class="disabled"><span>&hellip;</span></li>
15
15
  {% endif %}
16
16
  {% endfor %}
17
17
  {% if page.has_next %}
18
- <li><a href="{% querystring request page=page.next_page_number %}"><i class="mdi mdi-chevron-double-right"></i></a></li>
18
+ <li><a href="{% legacy_querystring request page=page.next_page_number %}"><i class="mdi mdi-chevron-double-right"></i></a></li>
19
19
  {% endif %}
20
20
  </ul>
21
21
  </nav>
@@ -1,6 +1,6 @@
1
- {% load django_tables2 %}
1
+ {% load querystring from django_tables2 %}
2
2
 
3
- <table{% if table.attrs %} {{ table.attrs.as_html }}{% endif %}>
3
+ <table {% if table.attrs %} {{ table.attrs.as_html }}{% endif %}>
4
4
  {% if table.show_header %}
5
5
  <thead>
6
6
  <tr>