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
@@ -13,6 +13,7 @@ from django.core.validators import RegexValidator, ValidationError
13
13
  from django.db import models, transaction
14
14
  from django.forms.widgets import TextInput
15
15
  from django.utils.html import format_html
16
+ from jinja2 import TemplateError, TemplateSyntaxError
16
17
 
17
18
  from nautobot.core.constants import CHARFIELD_MAX_LENGTH
18
19
  from nautobot.core.forms import (
@@ -35,7 +36,7 @@ from nautobot.core.models.querysets import RestrictedQuerySet
35
36
  from nautobot.core.models.validators import validate_regex
36
37
  from nautobot.core.settings_funcs import is_truthy
37
38
  from nautobot.core.templatetags.helpers import render_markdown
38
- from nautobot.core.utils.data import render_jinja2
39
+ from nautobot.core.utils.data import render_jinja2, validate_jinja2
39
40
  from nautobot.extras.choices import CustomFieldFilterLogicChoices, CustomFieldTypeChoices
40
41
  from nautobot.extras.models import ChangeLoggedModel
41
42
  from nautobot.extras.models.mixins import ContactMixin, DynamicGroupsModelMixin, NotesMixin, SavedViewMixin
@@ -84,6 +85,31 @@ class ComputedFieldManager(BaseManager.from_queryset(RestrictedQuerySet)):
84
85
  label = f"{ct.app_label}.{ct.model}"
85
86
  cache.set(f"{self.get_for_model.cache_key_prefix}.{label}.list", listings[label])
86
87
 
88
+ def bulk_create(self, objs, *args, **kwargs):
89
+ """Validate templates before saving."""
90
+ self._validate_templates_bulk(objs)
91
+ return super().bulk_create(objs, *args, **kwargs)
92
+
93
+ def bulk_update(self, objs, fields, *args, **kwargs):
94
+ """Validate templates before updating if template field is being modified."""
95
+ if "template" in fields:
96
+ self._validate_templates_bulk(objs)
97
+
98
+ return super().bulk_update(objs, fields, *args, **kwargs)
99
+
100
+ def _validate_templates_bulk(self, objs):
101
+ """Helper method to validate templates for multiple objects."""
102
+ errors = []
103
+ for obj in objs:
104
+ try:
105
+ obj.validate_template()
106
+ except ValidationError as exc:
107
+ message_list = [f"'{obj.label}': {x}" for x in exc.messages]
108
+ errors.extend(message_list)
109
+
110
+ if errors:
111
+ raise ValidationError(f"Template validation failed - {'; '.join(errors)}")
112
+
87
113
 
88
114
  @extras_features("graphql")
89
115
  class ComputedField(
@@ -144,14 +170,7 @@ class ComputedField(
144
170
 
145
171
  def render(self, context):
146
172
  try:
147
- rendered = render_jinja2(self.template, context)
148
- # If there is an undefined variable within a template, it returns nothing
149
- # Doesn't raise an exception either most likely due to using Undefined rather
150
- # than StrictUndefined, but return fallback_value if None is returned
151
- if rendered is None:
152
- logger.warning("Failed to render computed field %s", self.key)
153
- return self.fallback_value
154
- return rendered
173
+ return render_jinja2(self.template, context)
155
174
  except Exception as exc:
156
175
  logger.warning("Failed to render computed field %s: %s", self.key, exc)
157
176
  return self.fallback_value
@@ -162,9 +181,26 @@ class ComputedField(
162
181
 
163
182
  def clean(self):
164
183
  super().clean()
184
+
185
+ self.validate_template()
186
+
165
187
  if self.key != "":
166
188
  check_if_key_is_graphql_safe(self.__class__.__name__, self.key)
167
189
 
190
+ def validate_template(self):
191
+ """
192
+ Validate that the template contains valid Jinja2 syntax.
193
+ """
194
+ try:
195
+ validate_jinja2(self.template)
196
+ except TemplateSyntaxError as exc:
197
+ raise ValidationError({"template": f"Template syntax error on line {exc.lineno}: {exc.message}"})
198
+ except TemplateError as exc:
199
+ raise ValidationError({"template": f"Template error: {exc}"})
200
+ except Exception as exc:
201
+ # System-level exceptions (very rare) - memory, recursion, encoding issues
202
+ raise ValidationError(f"Template validation failed: {exc}")
203
+
168
204
 
169
205
  class CustomFieldModel(models.Model):
170
206
  """
@@ -806,7 +806,16 @@ class DynamicGroup(PrimaryModel):
806
806
  def _get_group_queryset(self):
807
807
  """Construct the queryset representing dynamic membership of this group."""
808
808
  query = self.generate_query()
809
- return self.model.objects.filter(query)
809
+ # https://github.com/nautobot/nautobot/issues/7631
810
+ # Some queries may result in duplicate records, hence the need for `.distinct()`.
811
+ # Use of `.distinct()` in general is a code smell and a performance hit, but given the wide variety of
812
+ # filters that can be applied, support for both MySQL and PostgreSQL, and limitations of the Django ORM,
813
+ # I don't see a clear alternative at this time.
814
+ #
815
+ # Additionally, due to the use of `.distinct()`, in combination with our use of `.only("id")`
816
+ # on this queryset, e.g. in `_set_members()`, we also need to override any default model ordering on the
817
+ # queryset in order to avoid SQL errors like "each EXCEPT query must have the same number of columns"
818
+ return self.model.objects.filter(query).order_by("id").distinct()
810
819
 
811
820
  # TODO: unused in core
812
821
  def add_child(self, child, operator, weight):
@@ -48,7 +48,7 @@ from nautobot.extras.constants import (
48
48
  )
49
49
  from nautobot.extras.managers import JobResultManager, ScheduledJobsManager
50
50
  from nautobot.extras.models import ChangeLoggedModel, GitRepository
51
- from nautobot.extras.models.mixins import ContactMixin, DynamicGroupsModelMixin, NotesMixin
51
+ from nautobot.extras.models.mixins import ContactMixin, DynamicGroupsModelMixin, NotesMixin, SavedViewMixin
52
52
  from nautobot.extras.querysets import JobQuerySet, ScheduledJobExtendedQuerySet
53
53
  from nautobot.extras.utils import (
54
54
  ChangeLoggedModelsQuery,
@@ -631,7 +631,7 @@ class JobQueueAssignment(BaseModel):
631
631
  "custom_links",
632
632
  "graphql",
633
633
  )
634
- class JobResult(BaseModel, CustomFieldModel):
634
+ class JobResult(SavedViewMixin, BaseModel, CustomFieldModel):
635
635
  """
636
636
  This model stores the results from running a Job.
637
637
  """
@@ -86,10 +86,8 @@ class InstalledAppsView(GenericView):
86
86
  """
87
87
 
88
88
  table = InstalledAppsTable
89
- breadcrumbs = Breadcrumbs(
90
- items={"generic": [ViewNameBreadcrumbItem(view_name="apps:apps_list", label="Installed Apps")]}
91
- )
92
- view_titles = Titles(titles={"generic": "Installed Apps"})
89
+ breadcrumbs = Breadcrumbs(items={"*": [ViewNameBreadcrumbItem(view_name="apps:apps_list", label="Installed Apps")]})
90
+ view_titles = Titles(titles={"*": "Installed Apps"})
93
91
 
94
92
  def get(self, request):
95
93
  marketplace_data = load_marketplace_data()
@@ -129,7 +127,6 @@ class InstalledAppsView(GenericView):
129
127
  "filter_form": None,
130
128
  "app_icons": app_icons,
131
129
  "display": display,
132
- "view_action": "generic",
133
130
  "breadcrumbs": self.breadcrumbs,
134
131
  "view_titles": self.view_titles,
135
132
  },
@@ -141,6 +138,20 @@ class InstalledAppDetailView(GenericView):
141
138
  View for showing details of an installed App.
142
139
  """
143
140
 
141
+ breadcrumbs = Breadcrumbs(
142
+ items={
143
+ "*": [
144
+ ViewNameBreadcrumbItem(view_name="apps:apps_list", label="Installed Apps"),
145
+ ViewNameBreadcrumbItem(
146
+ view_name="apps:app_detail",
147
+ reverse_kwargs=lambda context: {"app": context["app_data"]["package"]},
148
+ label=lambda context: context["app_data"]["name"],
149
+ ),
150
+ ]
151
+ }
152
+ )
153
+ view_titles = Titles(titles={"*": "{{ app_data.name | bettertitle }}"})
154
+
144
155
  def get(self, request, app=None, plugin=None):
145
156
  if plugin and not app:
146
157
  app = plugin
@@ -154,6 +165,8 @@ class InstalledAppDetailView(GenericView):
154
165
  {
155
166
  "app_data": extract_app_data(app_config, load_marketplace_data()),
156
167
  "object": app_config,
168
+ "breadcrumbs": self.breadcrumbs,
169
+ "view_titles": self.view_titles,
157
170
  },
158
171
  )
159
172
 
nautobot/extras/tables.py CHANGED
@@ -736,11 +736,12 @@ class JobTable(BaseTable):
736
736
  accessor="latest_result",
737
737
  template_code="""
738
738
  {% if value %}
739
- {{ value.date_created|date:settings.SHORT_DATETIME_FORMAT }} by {{ value.user }}
739
+ {{ value.date_created|date:SHORT_DATETIME_FORMAT }} by {{ value.user }}
740
740
  {% else %}
741
741
  <span class="text-muted">Never</span>
742
742
  {% endif %}
743
743
  """,
744
+ extra_context={"SHORT_DATETIME_FORMAT": settings.SHORT_DATETIME_FORMAT},
744
745
  linkify=lambda value: value.get_absolute_url() if value else None,
745
746
  )
746
747
  last_status = tables.TemplateColumn(
@@ -906,6 +907,7 @@ class JobResultTable(BaseTable):
906
907
  linkify=True,
907
908
  verbose_name="Scheduled Job",
908
909
  )
910
+ duration = tables.Column(orderable=False)
909
911
  actions = ButtonsColumn(JobResult, buttons=("delete",), prepend_template=JOB_RESULT_BUTTONS)
910
912
 
911
913
  def __init__(self, *args, **kwargs):
@@ -1069,7 +1071,7 @@ class ObjectMetadataTable(BaseTable):
1069
1071
  )
1070
1072
  # This is needed so that render_value method below does not skip itself
1071
1073
  # when metadata_type.data_type is TYPE_CONTACT_TEAM and we need it to display either contact or team
1072
- value = tables.Column(empty_values=[])
1074
+ value = tables.Column(empty_values=[], order_by=("_value",))
1073
1075
 
1074
1076
  class Meta(BaseTable.Meta):
1075
1077
  model = ObjectMetadata
@@ -1,2 +1,2 @@
1
- {% extends 'generic/object_retrieve.html' %}
1
+ {% extends 'generic/object_retrieve.html' %}
2
2
  {% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
@@ -1,50 +1,50 @@
1
- {% extends 'generic/object_create.html' %}
2
- {% load form_helpers %}
3
-
4
- {% block form %}
5
- <div class="panel panel-default">
6
- <div class="panel-heading"><strong>Config Context</strong></div>
7
- <div class="panel-body">
8
- {% render_field form.name %}
9
- {% render_field form.weight %}
10
- {% render_field form.description %}
11
- {% render_field form.config_context_schema %}
12
- {% render_field form.is_active %}
13
- </div>
14
- </div>
15
- <div class="panel panel-default">
16
- <div class="panel-heading"><strong>Assignment</strong></div>
17
- <div class="panel-body">
18
- {% render_field form.locations %}
19
- {% render_field form.roles %}
20
- {% render_field form.device_types %}
21
- {% render_field form.platforms %}
22
- {% render_field form.cluster_groups %}
23
- {% render_field form.clusters %}
24
- {% render_field form.tenant_groups %}
25
- {% render_field form.tenants %}
26
- {% render_field form.device_redundancy_groups %}
27
- {% render_field form.tags %}
28
- {% if settings.CONFIG_CONTEXT_DYNAMIC_GROUPS_ENABLED %}
29
- {% render_field form.dynamic_groups %}
30
- {% endif %}
31
- </div>
32
- </div>
33
- <div class="panel panel-default">
34
- <div class="panel-heading"><strong>Data</strong></div>
35
- <div class="panel-body">
36
- {% render_field form.data %}
37
- </div>
38
- </div>
39
- {% comment %}
40
- We don't use 'inc/extras_features_edit_form_fields.html' because it would add a second,
41
- and incorrect, "Tags" field to the form. Currently config-contexts don't support custom-fields or relationships,
42
- but they do support notes.
43
- {% endcomment %}
44
- <div class="panel panel-default">
45
- <div class="panel-heading"><strong>Notes</strong></div>
46
- <div class="panel-body">
47
- {% render_field form.object_note %}
48
- </div>
49
- </div>
1
+ {% extends 'generic/object_create.html' %}
2
+ {% load form_helpers %}
3
+
4
+ {% block form %}
5
+ <div class="panel panel-default">
6
+ <div class="panel-heading"><strong>Config Context</strong></div>
7
+ <div class="panel-body">
8
+ {% render_field form.name %}
9
+ {% render_field form.weight %}
10
+ {% render_field form.description %}
11
+ {% render_field form.config_context_schema %}
12
+ {% render_field form.is_active %}
13
+ </div>
14
+ </div>
15
+ <div class="panel panel-default">
16
+ <div class="panel-heading"><strong>Assignment</strong></div>
17
+ <div class="panel-body">
18
+ {% render_field form.locations %}
19
+ {% render_field form.roles %}
20
+ {% render_field form.device_types %}
21
+ {% render_field form.platforms %}
22
+ {% render_field form.cluster_groups %}
23
+ {% render_field form.clusters %}
24
+ {% render_field form.tenant_groups %}
25
+ {% render_field form.tenants %}
26
+ {% render_field form.device_redundancy_groups %}
27
+ {% render_field form.tags %}
28
+ {% if settings.CONFIG_CONTEXT_DYNAMIC_GROUPS_ENABLED %}
29
+ {% render_field form.dynamic_groups %}
30
+ {% endif %}
31
+ </div>
32
+ </div>
33
+ <div class="panel panel-default">
34
+ <div class="panel-heading"><strong>Data</strong></div>
35
+ <div class="panel-body">
36
+ {% render_field form.data %}
37
+ </div>
38
+ </div>
39
+ {% comment %}
40
+ We don't use 'inc/extras_features_edit_form_fields.html' because it would add a second,
41
+ and incorrect, "Tags" field to the form. Currently config-contexts don't support custom-fields or relationships,
42
+ but they do support notes.
43
+ {% endcomment %}
44
+ <div class="panel panel-default">
45
+ <div class="panel-heading"><strong>Notes</strong></div>
46
+ <div class="panel-body">
47
+ {% render_field form.object_note %}
48
+ </div>
49
+ </div>
50
50
  {% endblock %}
@@ -1,48 +1,48 @@
1
- {% extends 'generic/object_retrieve.html' %}
2
- {% load buttons %}
3
- {% load plugins %}
4
- {% load helpers %}
5
-
6
- {% block extra_nav_tabs %}
7
- <li role="presentation"{% if active_tab == 'validation' %} class="active"{% endif %}>
8
- <a href="{% url 'extras:configcontextschema_object_validation' pk=object.pk %}">Validation</a>
9
- </li>
10
- {% endblock extra_nav_tabs %}
11
-
12
- {% block content_left_page %}
13
- <div class="panel panel-default">
14
- <div class="panel-heading">
15
- <strong>Config Context Schema</strong>
16
- </div>
17
- <table class="table table-hover panel-body attr-table">
18
- <tr>
19
- <td>Name</td>
20
- <td>
21
- {{ object.name }}
22
- </td>
23
- </tr>
24
- {% if object.owner %}
25
- <tr>
26
- <td>Owner</td>
27
- <td>{{ object.owner|hyperlinked_object }}</td>
28
- </tr>
29
- {% endif %}
30
- <tr>
31
- <td>Description</td>
32
- <td>{{ object.description|placeholder }}</td>
33
- </tr>
34
- </table>
35
- </div>
36
- {% endblock content_left_page %}
37
-
38
- {% block content_right_page %}
39
- <div class="panel panel-default">
40
- <div class="panel-heading">
41
- <strong>Data Schema</strong>
42
- {% include 'extras/inc/configcontext_format.html' %}
43
- </div>
44
- <div class="panel-body">
45
- {% include 'extras/inc/json_data.html' with data=object.data_schema format=data_format %}
46
- </div>
47
- </div>
1
+ {% extends 'generic/object_retrieve.html' %}
2
+ {% load buttons %}
3
+ {% load plugins %}
4
+ {% load helpers %}
5
+
6
+ {% block extra_nav_tabs %}
7
+ <li role="presentation"{% if active_tab == 'validation' %} class="active"{% endif %}>
8
+ <a href="{% url 'extras:configcontextschema_object_validation' pk=object.pk %}">Validation</a>
9
+ </li>
10
+ {% endblock extra_nav_tabs %}
11
+
12
+ {% block content_left_page %}
13
+ <div class="panel panel-default">
14
+ <div class="panel-heading">
15
+ <strong>Config Context Schema</strong>
16
+ </div>
17
+ <table class="table table-hover panel-body attr-table">
18
+ <tr>
19
+ <td>Name</td>
20
+ <td>
21
+ {{ object.name }}
22
+ </td>
23
+ </tr>
24
+ {% if object.owner %}
25
+ <tr>
26
+ <td>Owner</td>
27
+ <td>{{ object.owner|hyperlinked_object }}</td>
28
+ </tr>
29
+ {% endif %}
30
+ <tr>
31
+ <td>Description</td>
32
+ <td>{{ object.description|placeholder }}</td>
33
+ </tr>
34
+ </table>
35
+ </div>
36
+ {% endblock content_left_page %}
37
+
38
+ {% block content_right_page %}
39
+ <div class="panel panel-default">
40
+ <div class="panel-heading">
41
+ <strong>Data Schema</strong>
42
+ {% include 'extras/inc/configcontext_format.html' %}
43
+ </div>
44
+ <div class="panel-body">
45
+ {% include 'extras/inc/json_data.html' with data=object.data_schema format=data_format %}
46
+ </div>
47
+ </div>
48
48
  {% endblock content_right_page %}
@@ -1,19 +1,19 @@
1
- {% extends 'generic/object_create.html' %}
2
- {% load form_helpers %}
3
-
4
- {% block form %}
5
- <div class="panel panel-default">
6
- <div class="panel-heading"><strong>Config Context Schema</strong></div>
7
- <div class="panel-body">
8
- {% render_field form.name %}
9
- {% render_field form.description %}
10
- </div>
11
- </div>
12
- <div class="panel panel-default">
13
- <div class="panel-heading"><strong>Data Schema</strong></div>
14
- <div class="panel-body">
15
- {% render_field form.data_schema %}
16
- </div>
17
- </div>
18
- {% include 'inc/extras_features_edit_form_fields.html' %}
1
+ {% extends 'generic/object_create.html' %}
2
+ {% load form_helpers %}
3
+
4
+ {% block form %}
5
+ <div class="panel panel-default">
6
+ <div class="panel-heading"><strong>Config Context Schema</strong></div>
7
+ <div class="panel-body">
8
+ {% render_field form.name %}
9
+ {% render_field form.description %}
10
+ </div>
11
+ </div>
12
+ <div class="panel panel-default">
13
+ <div class="panel-heading"><strong>Data Schema</strong></div>
14
+ <div class="panel-body">
15
+ {% render_field form.data_schema %}
16
+ </div>
17
+ </div>
18
+ {% include 'inc/extras_features_edit_form_fields.html' %}
19
19
  {% endblock %}
@@ -1,129 +1,2 @@
1
1
  {% extends 'generic/object_retrieve.html' %}
2
- {% load buttons %}
3
- {% load helpers %}
4
-
5
- {% block content_left_page %}
6
- <div class="panel panel-default">
7
- <div class="panel-heading">
8
- <strong>Custom Field</strong>
9
- </div>
10
- <table class="table table-hover panel-body attr-table">
11
- <tr>
12
- <td>Label</td>
13
- <td>{{ object.label }}</td>
14
- </tr>
15
- <tr>
16
- <td>Key</td>
17
- <td>{{ object.key }}</td>
18
- </tr>
19
- <tr>
20
- <td>Type</td>
21
- <td>{{ object.type | capfirst }}</td>
22
- </tr>
23
- <tr>
24
- <td>Weight</td>
25
- <td>{{ object.weight }}</td>
26
- </tr>
27
- <tr>
28
- <td>Grouping</td>
29
- <td>{{ object.grouping | placeholder }}</td>
30
- </tr>
31
- <tr>
32
- <td>Description</td>
33
- <td>{{ object.description | render_markdown | placeholder }}</td>
34
- </tr>
35
- <tr>
36
- <td>Required</td>
37
- <td>{{ object.required | render_boolean }}</td>
38
- </tr>
39
- <tr>
40
- <td>Default</td>
41
- <td>
42
- {% if object.type == "markdown" %}
43
- {{ object.default | render_markdown | placeholder }}
44
- {% elif object.type == "json" and object.default is not None %}
45
- <pre>{{ object.default | render_json }}</pre>
46
- {% else %}
47
- {{ object.default | placeholder }}
48
- {% endif %}
49
- </td>
50
- </tr>
51
- <tr>
52
- <td>Filter Logic</td>
53
- <td>{{ object.filter_logic | capfirst }}</td>
54
- </tr>
55
- <tr>
56
- <td>Move to Advanced Tab</td>
57
- <td>{{ object.advanced_ui | render_boolean }}</td>
58
- </tr>
59
- </table>
60
- </div>
61
- {% if object.custom_field_choices.exists %}
62
- <div class="panel panel-default">
63
- <div class="panel-heading">
64
- <strong>Custom Field Choices</strong>
65
- </div>
66
- <table class="table table-hover panel-body attr-table">
67
- <thead>
68
- <tr>
69
- <th>Value</th>
70
- <th>Weight</th>
71
- </tr>
72
- </thead>
73
- <tbody>
74
- {% for choice in object.custom_field_choices.all %}
75
- <tr>
76
- <td>{{ choice.value }}</td>
77
- <td>{{ choice.weight }}</td>
78
- </tr>
79
- {% endfor %}
80
- </tbody>
81
- </table>
82
- </div>
83
- {% endif %}
84
- {% endblock content_left_page %}
85
-
86
- {% block content_right_page %}
87
- <div class="panel panel-default">
88
- <div class="panel-heading">
89
- <strong>Assignment</strong>
90
- </div>
91
- <table class="table table-hover panel-body attr-table">
92
- <tr>
93
- <td>Content Types</td>
94
- <td>
95
- <ul>
96
- {% for ct in object.content_types.all %}
97
- <li>{{ ct }}</li>
98
- {% endfor %}
99
- </ul>
100
- </td>
101
- </tr>
102
- </table>
103
- </div>
104
- <div class="panel panel-default">
105
- <div class="panel-heading">
106
- <strong>Validation Rules</strong>
107
- </div>
108
- <table class="table table-hover panel-body attr-table">
109
- <tr>
110
- <td>Minimum Value/Length</td>
111
- <td>{{ object.validation_minimum | placeholder }}</td>
112
- </tr>
113
- <tr>
114
- <td>Maximum Value/Length</td>
115
- <td>{{ object.validation_maximum | placeholder }}</td>
116
- </tr>
117
- <tr>
118
- <td>Validation Regex</td>
119
- <td>
120
- {% if object.validation_regex %}
121
- <code>{{ object.validation_regex | placeholder }}</code>
122
- {% else %}
123
- {{ object.validation_regex | placeholder }}
124
- {% endif %}
125
- </td>
126
- </tr>
127
- </table>
128
- </div>
129
- {% endblock content_right_page %}
2
+ {% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}