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

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

Potentially problematic release.


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

Files changed (675) hide show
  1. nautobot/__init__.py +15 -0
  2. nautobot/apps/api.py +0 -2
  3. nautobot/apps/config.py +32 -3
  4. nautobot/apps/events.py +19 -0
  5. nautobot/apps/exceptions.py +0 -2
  6. nautobot/apps/ui.py +44 -9
  7. nautobot/apps/utils.py +0 -8
  8. nautobot/apps/views.py +2 -0
  9. nautobot/circuits/navigation.py +0 -57
  10. nautobot/circuits/tables.py +1 -2
  11. nautobot/circuits/templates/circuits/circuit_retrieve.html +0 -71
  12. nautobot/circuits/templates/circuits/inc/circuit_termination.html +6 -64
  13. nautobot/circuits/templates/circuits/inc/circuit_termination_cable_fragment.html +40 -0
  14. nautobot/circuits/templates/circuits/inc/circuit_termination_header_extra_content.html +26 -0
  15. nautobot/circuits/templates/circuits/provider_retrieve.html +0 -76
  16. nautobot/circuits/tests/integration/test_relationships.py +33 -24
  17. nautobot/circuits/tests/test_filters.py +4 -8
  18. nautobot/circuits/views.py +143 -26
  19. nautobot/cloud/factory.py +4 -1
  20. nautobot/cloud/models.py +1 -1
  21. nautobot/cloud/tests/test_filters.py +5 -4
  22. nautobot/core/api/fields.py +5 -5
  23. nautobot/core/api/metadata.py +28 -256
  24. nautobot/core/api/pagination.py +3 -2
  25. nautobot/core/api/renderers.py +3 -0
  26. nautobot/core/api/serializers.py +24 -244
  27. nautobot/core/api/urls.py +3 -4
  28. nautobot/core/api/utils.py +0 -62
  29. nautobot/core/api/views.py +48 -158
  30. nautobot/core/apps/__init__.py +22 -578
  31. nautobot/core/celery/__init__.py +13 -0
  32. nautobot/core/celery/log.py +4 -4
  33. nautobot/core/celery/schedulers.py +48 -3
  34. nautobot/core/cli/__init__.py +8 -0
  35. nautobot/core/constants.py +7 -0
  36. nautobot/core/events/__init__.py +116 -0
  37. nautobot/core/events/base.py +27 -0
  38. nautobot/core/events/exceptions.py +10 -0
  39. nautobot/core/events/redis_broker.py +48 -0
  40. nautobot/core/events/syslog_broker.py +19 -0
  41. nautobot/core/exceptions.py +0 -6
  42. nautobot/core/filters.py +16 -21
  43. nautobot/core/fixtures/user-data.json +59 -0
  44. nautobot/core/forms/fields.py +53 -8
  45. nautobot/core/forms/utils.py +2 -1
  46. nautobot/core/graphql/schema.py +3 -1
  47. nautobot/core/graphql/types.py +1 -1
  48. nautobot/core/jobs/__init__.py +4 -4
  49. nautobot/core/jobs/cleanup.py +13 -49
  50. nautobot/core/jobs/groups.py +1 -1
  51. nautobot/core/management/commands/generate_test_data.py +21 -0
  52. nautobot/core/management/commands/validate_models.py +1 -1
  53. nautobot/core/middleware.py +16 -0
  54. nautobot/core/models/__init__.py +1 -1
  55. nautobot/core/models/fields.py +11 -7
  56. nautobot/core/models/query_functions.py +2 -2
  57. nautobot/core/models/tree_queries.py +3 -6
  58. nautobot/core/settings.py +44 -7
  59. nautobot/core/settings.yaml +86 -8
  60. nautobot/core/tables.py +15 -65
  61. nautobot/core/tasks.py +1 -1
  62. nautobot/core/templates/components/button/default.html +7 -0
  63. nautobot/core/templates/components/button/dropdown.html +20 -0
  64. nautobot/core/templates/components/layout/one_over_two.html +19 -0
  65. nautobot/core/templates/components/layout/two_over_one.html +19 -0
  66. nautobot/core/templates/components/panel/body_content_data_table.html +27 -0
  67. nautobot/core/templates/components/panel/body_content_objects_table.html +4 -0
  68. nautobot/core/templates/components/panel/body_content_tags.html +6 -0
  69. nautobot/core/templates/components/panel/body_content_text.html +12 -0
  70. nautobot/core/templates/components/panel/body_wrapper_generic.html +3 -0
  71. nautobot/core/templates/components/panel/body_wrapper_key_value_table.html +3 -0
  72. nautobot/core/templates/components/panel/body_wrapper_table.html +3 -0
  73. nautobot/core/templates/components/panel/footer_contacts_table.html +20 -0
  74. nautobot/core/templates/components/panel/footer_content_table.html +14 -0
  75. nautobot/core/templates/components/panel/grouping_toggle.html +14 -0
  76. nautobot/core/templates/components/panel/header_extra_content_table.html +3 -0
  77. nautobot/core/templates/components/panel/panel.html +16 -0
  78. nautobot/core/templates/components/panel/stats_panel_body.html +8 -0
  79. nautobot/core/templates/components/tab/content_wrapper.html +3 -0
  80. nautobot/core/templates/components/tab/label_wrapper.html +5 -0
  81. nautobot/core/templates/components/tab/label_wrapper_distinct_view.html +3 -0
  82. nautobot/core/templates/generic/object_retrieve.html +28 -17
  83. nautobot/core/templates/inc/computed_fields/panel_data.html +4 -7
  84. nautobot/core/templates/inc/custom_fields/panel.html +2 -2
  85. nautobot/core/templates/inc/custom_fields/panel_data.html +4 -7
  86. nautobot/core/templates/inc/footer.html +1 -0
  87. nautobot/core/templates/inc/media.html +0 -3
  88. nautobot/core/templates/inc/nav_menu.html +1 -1
  89. nautobot/core/templates/inc/relationships_panel.html +1 -1
  90. nautobot/core/templates/nautobot_config.py.j2 +3 -3
  91. nautobot/core/templates/panel_table.html +12 -0
  92. nautobot/core/templates/search.html +0 -7
  93. nautobot/core/templates/utilities/render_jinja2.html +117 -0
  94. nautobot/core/templatetags/helpers.py +101 -12
  95. nautobot/core/templatetags/ui_framework.py +40 -0
  96. nautobot/core/testing/api.py +23 -128
  97. nautobot/core/testing/context.py +18 -0
  98. nautobot/core/testing/filters.py +41 -58
  99. nautobot/core/testing/mixins.py +2 -7
  100. nautobot/core/testing/views.py +25 -123
  101. nautobot/core/tests/integration/test_app_home.py +1 -0
  102. nautobot/core/tests/integration/test_app_navbar.py +1 -0
  103. nautobot/core/tests/integration/test_filters.py +2 -0
  104. nautobot/core/tests/integration/test_home.py +1 -0
  105. nautobot/core/tests/integration/test_navbar.py +1 -0
  106. nautobot/core/tests/integration/test_view_authentication.py +1 -2
  107. nautobot/core/tests/nautobot_config.py +198 -0
  108. nautobot/core/tests/runner.py +3 -3
  109. nautobot/core/tests/test_api.py +82 -201
  110. nautobot/core/tests/test_csv.py +3 -25
  111. nautobot/core/tests/test_events.py +214 -0
  112. nautobot/core/tests/test_jinja_filters.py +1 -0
  113. nautobot/core/tests/test_jobs.py +84 -13
  114. nautobot/core/tests/test_navigations.py +7 -241
  115. nautobot/core/tests/test_templatetags_helpers.py +16 -0
  116. nautobot/core/tests/test_ui.py +150 -0
  117. nautobot/core/tests/test_utils.py +0 -25
  118. nautobot/core/tests/test_views.py +123 -31
  119. nautobot/core/ui/__init__.py +0 -0
  120. nautobot/core/ui/base.py +11 -0
  121. nautobot/core/ui/choices.py +44 -0
  122. nautobot/core/ui/homepage.py +167 -0
  123. nautobot/core/ui/nav.py +279 -0
  124. nautobot/core/ui/object_detail.py +1841 -0
  125. nautobot/core/ui/utils.py +36 -0
  126. nautobot/core/urls.py +4 -9
  127. nautobot/core/utils/config.py +30 -3
  128. nautobot/core/utils/lookup.py +20 -13
  129. nautobot/core/views/__init__.py +6 -1
  130. nautobot/core/views/generic.py +47 -52
  131. nautobot/core/views/mixins.py +15 -25
  132. nautobot/core/views/paginator.py +8 -5
  133. nautobot/core/views/renderers.py +3 -3
  134. nautobot/core/views/utils.py +11 -0
  135. nautobot/core/wsgi.py +3 -3
  136. nautobot/dcim/api/serializers.py +80 -179
  137. nautobot/dcim/api/urls.py +5 -0
  138. nautobot/dcim/api/views.py +17 -4
  139. nautobot/dcim/apps.py +1 -0
  140. nautobot/dcim/choices.py +28 -0
  141. nautobot/dcim/factory.py +58 -0
  142. nautobot/dcim/filters/__init__.py +197 -24
  143. nautobot/dcim/forms.py +203 -12
  144. nautobot/dcim/graphql/types.py +2 -2
  145. nautobot/dcim/migrations/0063_interfacevdcassignment_virtualdevicecontext_and_more.py +165 -0
  146. nautobot/dcim/migrations/0064_virtualdevicecontext_status_data_migration.py +28 -0
  147. nautobot/dcim/migrations/0065_controller_capabilities_and_more.py +29 -0
  148. nautobot/dcim/migrations/0066_controllermanageddevicegroup_radio_profiles_and_more.py +33 -0
  149. nautobot/dcim/models/__init__.py +4 -0
  150. nautobot/dcim/models/device_component_templates.py +2 -2
  151. nautobot/dcim/models/device_components.py +20 -22
  152. nautobot/dcim/models/devices.py +173 -4
  153. nautobot/dcim/models/locations.py +3 -3
  154. nautobot/dcim/models/power.py +5 -6
  155. nautobot/dcim/models/racks.py +6 -6
  156. nautobot/dcim/navigation.py +25 -224
  157. nautobot/dcim/signals.py +44 -0
  158. nautobot/dcim/tables/__init__.py +5 -3
  159. nautobot/dcim/tables/devices.py +96 -2
  160. nautobot/dcim/tables/devicetypes.py +2 -2
  161. nautobot/dcim/templates/dcim/controller/base.html +10 -0
  162. nautobot/dcim/templates/dcim/controller_create.html +1 -0
  163. nautobot/dcim/templates/dcim/controller_retrieve.html +5 -1
  164. nautobot/dcim/templates/dcim/controller_wirelessnetworks.html +25 -0
  165. nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +66 -0
  166. nautobot/dcim/templates/dcim/controllermanageddevicegroup_retrieve.html +46 -0
  167. nautobot/dcim/templates/dcim/device/base.html +6 -42
  168. nautobot/dcim/templates/dcim/device/wireless.html +73 -0
  169. nautobot/dcim/templates/dcim/device.html +3 -1
  170. nautobot/dcim/templates/dcim/interface.html +1 -0
  171. nautobot/dcim/templates/dcim/interface_edit.html +1 -0
  172. nautobot/dcim/templates/dcim/locationtype.html +0 -107
  173. nautobot/dcim/templates/dcim/locationtype_retrieve.html +8 -0
  174. nautobot/dcim/templates/dcim/virtualdevicecontext_retrieve.html +76 -0
  175. nautobot/dcim/templates/dcim/virtualdevicecontext_update.html +34 -0
  176. nautobot/dcim/tests/test_api.py +172 -61
  177. nautobot/dcim/tests/test_filters.py +171 -109
  178. nautobot/dcim/tests/test_forms.py +2 -51
  179. nautobot/dcim/tests/test_graphql.py +0 -52
  180. nautobot/dcim/tests/test_models.py +126 -4
  181. nautobot/dcim/tests/test_signals.py +1 -0
  182. nautobot/dcim/tests/test_views.py +103 -11
  183. nautobot/dcim/urls.py +72 -27
  184. nautobot/dcim/utils.py +2 -2
  185. nautobot/dcim/views.py +369 -62
  186. nautobot/extras/api/customfields.py +2 -2
  187. nautobot/extras/api/serializers.py +91 -75
  188. nautobot/extras/api/urls.py +4 -0
  189. nautobot/extras/api/views.py +78 -15
  190. nautobot/extras/choices.py +13 -0
  191. nautobot/extras/constants.py +0 -1
  192. nautobot/extras/context_managers.py +23 -6
  193. nautobot/extras/datasources/git.py +4 -1
  194. nautobot/extras/factory.py +27 -0
  195. nautobot/extras/filters/__init__.py +59 -0
  196. nautobot/extras/forms/forms.py +125 -30
  197. nautobot/extras/forms/mixins.py +3 -11
  198. nautobot/extras/graphql/types.py +25 -1
  199. nautobot/extras/group_sync.py +3 -3
  200. nautobot/extras/health_checks.py +2 -1
  201. nautobot/extras/jobs.py +62 -26
  202. nautobot/extras/management/__init__.py +1 -0
  203. nautobot/extras/management/commands/runjob.py +7 -79
  204. nautobot/extras/management/commands/runjob_with_job_result.py +46 -0
  205. nautobot/extras/management/utils.py +87 -0
  206. nautobot/extras/managers.py +1 -3
  207. nautobot/extras/migrations/0018_joblog_data_migration.py +9 -7
  208. nautobot/extras/migrations/0117_create_job_queue_model.py +129 -0
  209. nautobot/extras/migrations/0118_task_queue_to_job_queue_migration.py +78 -0
  210. nautobot/extras/migrations/0119_remove_task_queues_from_job_and_queue_from_scheduled_job.py +28 -0
  211. nautobot/extras/models/__init__.py +4 -0
  212. nautobot/extras/models/change_logging.py +7 -3
  213. nautobot/extras/models/customfields.py +11 -12
  214. nautobot/extras/models/groups.py +9 -13
  215. nautobot/extras/models/jobs.py +218 -37
  216. nautobot/extras/models/models.py +2 -2
  217. nautobot/extras/models/relationships.py +69 -1
  218. nautobot/extras/models/secrets.py +5 -0
  219. nautobot/extras/navigation.py +20 -262
  220. nautobot/extras/plugins/__init__.py +56 -32
  221. nautobot/extras/plugins/marketplace_manifest.yml +450 -0
  222. nautobot/extras/plugins/urls.py +1 -0
  223. nautobot/extras/plugins/views.py +48 -1
  224. nautobot/extras/signals.py +39 -1
  225. nautobot/extras/tables.py +40 -6
  226. nautobot/extras/templates/extras/externalintegration_retrieve.html +0 -47
  227. nautobot/extras/templates/extras/inc/tags_panel.html +1 -5
  228. nautobot/extras/templates/extras/job_bulk_edit.html +2 -1
  229. nautobot/extras/templates/extras/job_detail.html +36 -6
  230. nautobot/extras/templates/extras/job_edit.html +5 -2
  231. nautobot/extras/templates/extras/job_list.html +2 -7
  232. nautobot/extras/templates/extras/jobqueue_retrieve.html +44 -0
  233. nautobot/extras/templates/extras/marketplace.html +278 -0
  234. nautobot/extras/templates/extras/plugins_list.html +35 -1
  235. nautobot/extras/templates/extras/plugins_tiles.html +79 -0
  236. nautobot/extras/templates/extras/role_retrieve.html +16 -0
  237. nautobot/extras/templates/extras/secret.html +0 -65
  238. nautobot/extras/templates/extras/secret_check.js +16 -0
  239. nautobot/extras/templates/extras/secret_create.html +114 -0
  240. nautobot/extras/templates/extras/secret_edit.html +1 -114
  241. nautobot/extras/templates/extras/secretsgroup_edit.html +1 -1
  242. nautobot/extras/templates/extras/templatetags/plugin_object_detail_tabs.html +2 -0
  243. nautobot/extras/templatetags/job_buttons.py +5 -4
  244. nautobot/extras/templatetags/plugins.py +69 -6
  245. nautobot/extras/test_jobs/api_test_job.py +1 -1
  246. nautobot/extras/test_jobs/atomic_transaction.py +2 -2
  247. nautobot/extras/test_jobs/dry_run.py +1 -1
  248. nautobot/extras/test_jobs/fail.py +5 -5
  249. nautobot/extras/test_jobs/file_output.py +1 -1
  250. nautobot/extras/test_jobs/file_upload_fail.py +1 -1
  251. nautobot/extras/test_jobs/file_upload_pass.py +1 -1
  252. nautobot/extras/test_jobs/ipaddress_vars.py +1 -3
  253. nautobot/extras/test_jobs/jobs_module/jobs_submodule/jobs.py +1 -1
  254. nautobot/extras/test_jobs/location_with_custom_field.py +1 -1
  255. nautobot/extras/test_jobs/log_redaction.py +1 -1
  256. nautobot/extras/test_jobs/log_skip_db_logging.py +1 -1
  257. nautobot/extras/test_jobs/modify_db.py +1 -1
  258. nautobot/extras/test_jobs/object_var_optional.py +1 -1
  259. nautobot/extras/test_jobs/object_var_required.py +1 -1
  260. nautobot/extras/test_jobs/object_vars.py +1 -1
  261. nautobot/extras/test_jobs/pass.py +3 -3
  262. nautobot/extras/test_jobs/profiling.py +1 -1
  263. nautobot/extras/test_jobs/relative_import.py +3 -3
  264. nautobot/extras/test_jobs/soft_time_limit_greater_than_time_limit.py +1 -1
  265. nautobot/extras/test_jobs/task_queues.py +1 -1
  266. nautobot/extras/tests/integration/test_plugin_banner.py +2 -0
  267. nautobot/extras/tests/test_api.py +157 -55
  268. nautobot/extras/tests/test_context_managers.py +4 -1
  269. nautobot/extras/tests/test_customfields.py +1 -1
  270. nautobot/extras/tests/test_datasources.py +1 -2
  271. nautobot/extras/tests/test_dynamicgroups.py +1 -1
  272. nautobot/extras/tests/test_filters.py +219 -535
  273. nautobot/extras/tests/test_forms.py +1 -20
  274. nautobot/extras/tests/test_job_variables.py +73 -152
  275. nautobot/extras/tests/test_jobs.py +43 -54
  276. nautobot/extras/tests/test_models.py +71 -16
  277. nautobot/extras/tests/test_relationships.py +5 -2
  278. nautobot/extras/tests/test_utils.py +23 -2
  279. nautobot/extras/tests/test_views.py +183 -43
  280. nautobot/extras/tests/test_webhooks.py +2 -1
  281. nautobot/extras/urls.py +2 -20
  282. nautobot/extras/utils.py +118 -4
  283. nautobot/extras/views.py +203 -92
  284. nautobot/extras/webhooks.py +5 -2
  285. nautobot/ipam/api/fields.py +3 -3
  286. nautobot/ipam/api/serializers.py +36 -137
  287. nautobot/ipam/api/views.py +93 -62
  288. nautobot/ipam/lookups.py +62 -101
  289. nautobot/ipam/models.py +11 -63
  290. nautobot/ipam/navigation.py +0 -90
  291. nautobot/ipam/querysets.py +2 -2
  292. nautobot/ipam/tables.py +6 -20
  293. nautobot/ipam/templates/ipam/routetarget.html +0 -28
  294. nautobot/ipam/templates/ipam/vrf.html +0 -47
  295. nautobot/ipam/tests/test_api.py +8 -419
  296. nautobot/ipam/tests/test_filters.py +39 -119
  297. nautobot/ipam/tests/test_forms.py +47 -51
  298. nautobot/ipam/tests/test_migrations.py +30 -30
  299. nautobot/ipam/tests/test_models.py +0 -41
  300. nautobot/ipam/tests/test_querysets.py +1 -63
  301. nautobot/ipam/urls.py +3 -69
  302. nautobot/ipam/utils/__init__.py +0 -24
  303. nautobot/ipam/views.py +153 -198
  304. nautobot/project-static/css/base.css +38 -3
  305. nautobot/project-static/docs/404.html +421 -19
  306. nautobot/project-static/docs/apps/index.html +421 -19
  307. nautobot/project-static/docs/apps/nautobot-apps.html +421 -19
  308. nautobot/project-static/docs/assets/extra.css +5 -1
  309. nautobot/project-static/docs/assets/javascripts/{bundle.88dd0f4e.min.js → bundle.83f73b43.min.js} +2 -2
  310. nautobot/project-static/docs/assets/javascripts/{bundle.88dd0f4e.min.js.map → bundle.83f73b43.min.js.map} +2 -2
  311. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +421 -19
  312. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +421 -19
  313. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +421 -172
  314. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +421 -19
  315. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +421 -19
  316. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +425 -21
  317. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +421 -19
  318. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +424 -22
  319. nautobot/project-static/docs/code-reference/nautobot/apps/events.html +9809 -0
  320. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +424 -63
  321. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +421 -19
  322. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +421 -19
  323. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +457 -20
  324. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +421 -19
  325. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +425 -25
  326. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +457 -19
  327. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +421 -19
  328. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +421 -19
  329. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +425 -215
  330. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +430 -342
  331. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +5799 -1054
  332. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +421 -19
  333. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +447 -176
  334. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +460 -21
  335. nautobot/project-static/docs/development/apps/api/configuration-view.html +421 -19
  336. nautobot/project-static/docs/development/apps/api/database-backend-config.html +421 -19
  337. nautobot/project-static/docs/development/apps/api/models/django-admin.html +421 -19
  338. nautobot/project-static/docs/development/apps/api/models/global-search.html +421 -19
  339. nautobot/project-static/docs/development/apps/api/models/graphql.html +421 -19
  340. nautobot/project-static/docs/development/apps/api/models/index.html +421 -19
  341. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +421 -19
  342. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +421 -19
  343. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +421 -19
  344. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +421 -19
  345. nautobot/project-static/docs/development/apps/api/platform-features/index.html +421 -19
  346. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +421 -19
  347. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +421 -19
  348. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +421 -19
  349. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +421 -19
  350. nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +424 -41
  351. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +421 -19
  352. nautobot/project-static/docs/development/apps/api/prometheus.html +421 -19
  353. nautobot/project-static/docs/development/apps/api/setup.html +425 -155
  354. nautobot/project-static/docs/development/apps/api/testing.html +421 -19
  355. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +421 -19
  356. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +421 -19
  357. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +421 -19
  358. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +421 -19
  359. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +701 -130
  360. nautobot/project-static/docs/development/apps/api/views/base-template.html +421 -19
  361. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +421 -19
  362. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +421 -19
  363. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +421 -19
  364. nautobot/project-static/docs/development/apps/api/views/index.html +423 -20
  365. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +425 -19
  366. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +451 -19
  367. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +421 -19
  368. nautobot/project-static/docs/development/apps/api/views/notes.html +421 -19
  369. nautobot/project-static/docs/development/apps/api/views/rest-api.html +421 -19
  370. nautobot/project-static/docs/development/apps/api/views/urls.html +421 -19
  371. nautobot/project-static/docs/development/apps/index.html +421 -19
  372. nautobot/project-static/docs/development/apps/migration/code-updates.html +422 -52
  373. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +422 -20
  374. nautobot/project-static/docs/development/apps/migration/from-v1.html +421 -19
  375. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +421 -19
  376. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +421 -19
  377. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +421 -19
  378. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +424 -22
  379. nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +9219 -0
  380. nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +9333 -0
  381. nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +9474 -0
  382. nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +9517 -0
  383. nautobot/project-static/docs/development/apps/porting-from-netbox.html +424 -22
  384. nautobot/project-static/docs/development/core/application-registry.html +421 -19
  385. nautobot/project-static/docs/development/core/best-practices.html +421 -19
  386. nautobot/project-static/docs/development/core/bootstrap-ui.html +421 -19
  387. nautobot/project-static/docs/development/core/caching.html +421 -19
  388. nautobot/project-static/docs/development/core/controllers.html +423 -19
  389. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +490 -45
  390. nautobot/project-static/docs/development/core/generic-views.html +421 -19
  391. nautobot/project-static/docs/development/core/getting-started.html +566 -179
  392. nautobot/project-static/docs/development/core/homepage.html +432 -30
  393. nautobot/project-static/docs/development/core/index.html +421 -19
  394. nautobot/project-static/docs/development/core/local-k8s.html +9453 -0
  395. nautobot/project-static/docs/development/core/model-checklist.html +424 -22
  396. nautobot/project-static/docs/development/core/model-features.html +421 -19
  397. nautobot/project-static/docs/development/core/natural-keys.html +421 -19
  398. nautobot/project-static/docs/development/core/navigation-menu.html +438 -26
  399. nautobot/project-static/docs/development/core/release-checklist.html +435 -45
  400. nautobot/project-static/docs/development/core/role-internals.html +421 -19
  401. nautobot/project-static/docs/development/core/settings.html +421 -19
  402. nautobot/project-static/docs/development/core/style-guide.html +421 -19
  403. nautobot/project-static/docs/development/core/templates.html +431 -22
  404. nautobot/project-static/docs/development/core/testing.html +421 -19
  405. nautobot/project-static/docs/development/core/ui-component-framework.html +11020 -0
  406. nautobot/project-static/docs/development/core/user-preferences.html +424 -22
  407. nautobot/project-static/docs/development/index.html +421 -19
  408. nautobot/project-static/docs/development/jobs/index.html +546 -160
  409. nautobot/project-static/docs/development/jobs/migration/from-v1.html +421 -19
  410. nautobot/project-static/docs/index.html +421 -19
  411. nautobot/project-static/docs/media/development/core/ui-component-framework/basic-panel-layout.png +0 -0
  412. nautobot/project-static/docs/media/development/core/ui-component-framework/button-example.png +0 -0
  413. nautobot/project-static/docs/media/development/core/ui-component-framework/dropdown-button-example.png +0 -0
  414. nautobot/project-static/docs/media/development/core/ui-component-framework/grouped-key-value-table-panel-example-1.png +0 -0
  415. nautobot/project-static/docs/media/development/core/ui-component-framework/grouped-key-value-table-panel-example-2.png +0 -0
  416. nautobot/project-static/docs/media/development/core/ui-component-framework/object-fields-panel-example.png +0 -0
  417. nautobot/project-static/docs/media/development/core/ui-component-framework/stats-panel-example.png +0 -0
  418. nautobot/project-static/docs/media/development/core/ui-component-framework/table-panels-family.png +0 -0
  419. nautobot/project-static/docs/media/development/core/ui-component-framework/text-panels-family.png +0 -0
  420. nautobot/project-static/docs/media/development/core/ui-component-framework/ui-framework-example.png +0 -0
  421. nautobot/project-static/docs/media/models/virtual_device_context_overview.drawio +73 -0
  422. nautobot/project-static/docs/media/models/virtual_device_context_overview.png +0 -0
  423. nautobot/project-static/docs/models/dcim/virtualdevicecontext.html +14 -0
  424. nautobot/project-static/docs/models/extras/jobqueue.html +14 -0
  425. nautobot/project-static/docs/models/wireless/radioprofile.html +14 -0
  426. nautobot/project-static/docs/models/wireless/supporteddatarate.html +14 -0
  427. nautobot/project-static/docs/models/wireless/wirelessnetwork.html +14 -0
  428. nautobot/project-static/docs/objects.inv +0 -0
  429. nautobot/project-static/docs/overview/application_stack.html +426 -20
  430. nautobot/project-static/docs/overview/design_philosophy.html +421 -19
  431. nautobot/project-static/docs/release-notes/index.html +445 -22
  432. nautobot/project-static/docs/release-notes/version-1.0.html +421 -19
  433. nautobot/project-static/docs/release-notes/version-1.1.html +421 -19
  434. nautobot/project-static/docs/release-notes/version-1.2.html +421 -19
  435. nautobot/project-static/docs/release-notes/version-1.3.html +421 -19
  436. nautobot/project-static/docs/release-notes/version-1.4.html +421 -19
  437. nautobot/project-static/docs/release-notes/version-1.5.html +421 -19
  438. nautobot/project-static/docs/release-notes/version-1.6.html +634 -667
  439. nautobot/project-static/docs/release-notes/version-2.0.html +421 -19
  440. nautobot/project-static/docs/release-notes/version-2.1.html +421 -19
  441. nautobot/project-static/docs/release-notes/version-2.2.html +421 -19
  442. nautobot/project-static/docs/release-notes/version-2.3.html +684 -886
  443. nautobot/project-static/docs/release-notes/version-2.4.html +10007 -0
  444. nautobot/project-static/docs/requirements.txt +2 -2
  445. nautobot/project-static/docs/search/search_index.json +1 -1
  446. nautobot/project-static/docs/sitemap.xml +334 -270
  447. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  448. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +421 -19
  449. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +421 -19
  450. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +423 -21
  451. nautobot/project-static/docs/user-guide/administration/configuration/index.html +433 -32
  452. nautobot/project-static/docs/user-guide/administration/configuration/redis.html +421 -19
  453. nautobot/project-static/docs/user-guide/administration/configuration/settings.html +765 -180
  454. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +421 -19
  455. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +421 -19
  456. nautobot/project-static/docs/user-guide/administration/guides/docker.html +434 -29
  457. nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +421 -19
  458. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +421 -19
  459. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +421 -19
  460. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +421 -19
  461. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +421 -19
  462. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +421 -19
  463. nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +421 -19
  464. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +421 -19
  465. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +421 -19
  466. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +421 -19
  467. nautobot/project-static/docs/user-guide/administration/installation/index.html +426 -20
  468. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +421 -19
  469. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +421 -19
  470. nautobot/project-static/docs/user-guide/administration/installation/services.html +421 -19
  471. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +421 -19
  472. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +442 -41
  473. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +435 -66
  474. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +435 -66
  475. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +421 -19
  476. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +421 -19
  477. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +421 -19
  478. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +421 -19
  479. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +421 -19
  480. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +421 -19
  481. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +421 -19
  482. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/tables/v2-code-nautobot-app-location.yaml +0 -16
  483. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +421 -19
  484. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +427 -21
  485. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +421 -19
  486. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +421 -19
  487. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +421 -19
  488. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +421 -19
  489. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +421 -19
  490. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +421 -19
  491. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +421 -19
  492. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +421 -19
  493. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +421 -19
  494. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +421 -19
  495. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +421 -19
  496. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +421 -19
  497. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +421 -19
  498. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +421 -19
  499. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +421 -19
  500. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +421 -19
  501. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +421 -19
  502. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +457 -20
  503. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +447 -22
  504. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +421 -19
  505. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +421 -19
  506. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +421 -19
  507. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +421 -19
  508. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +421 -19
  509. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +421 -19
  510. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +421 -19
  511. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +421 -19
  512. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +421 -19
  513. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +421 -19
  514. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +421 -19
  515. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +421 -19
  516. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +421 -19
  517. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +421 -19
  518. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +421 -19
  519. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +421 -19
  520. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +421 -19
  521. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +421 -19
  522. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +421 -19
  523. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +421 -19
  524. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +421 -19
  525. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +421 -19
  526. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +421 -19
  527. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +421 -19
  528. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +421 -19
  529. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +421 -19
  530. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +421 -19
  531. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +421 -19
  532. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +421 -19
  533. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +421 -19
  534. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +421 -19
  535. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +421 -19
  536. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +421 -19
  537. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +421 -19
  538. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +9333 -0
  539. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +424 -22
  540. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +421 -19
  541. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +421 -19
  542. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +421 -19
  543. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +421 -19
  544. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +421 -19
  545. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +421 -19
  546. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +421 -19
  547. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +421 -19
  548. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +421 -19
  549. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +421 -19
  550. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +421 -19
  551. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +421 -19
  552. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +421 -19
  553. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +421 -19
  554. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +421 -19
  555. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +421 -19
  556. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +421 -19
  557. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +421 -19
  558. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +421 -19
  559. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +424 -22
  560. nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +9271 -0
  561. nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +9175 -0
  562. nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +9169 -0
  563. nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +9235 -0
  564. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +421 -19
  565. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +421 -19
  566. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +421 -19
  567. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +421 -19
  568. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +421 -19
  569. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +421 -19
  570. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +421 -19
  571. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +421 -19
  572. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +421 -19
  573. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +421 -19
  574. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +421 -19
  575. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +421 -19
  576. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +421 -19
  577. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +421 -19
  578. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +421 -19
  579. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +421 -19
  580. nautobot/project-static/docs/user-guide/index.html +421 -19
  581. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +424 -22
  582. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +421 -19
  583. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +421 -19
  584. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +421 -19
  585. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +421 -19
  586. nautobot/project-static/docs/user-guide/platform-functionality/events.html +9575 -0
  587. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +424 -22
  588. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +421 -19
  589. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +421 -19
  590. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +421 -19
  591. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +421 -19
  592. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +421 -19
  593. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +426 -20
  594. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +424 -22
  595. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +421 -19
  596. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +421 -19
  597. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +9182 -0
  598. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +424 -22
  599. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +421 -19
  600. nautobot/project-static/docs/user-guide/platform-functionality/note.html +421 -19
  601. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +421 -19
  602. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +424 -22
  603. nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +9250 -0
  604. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +421 -19
  605. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +421 -19
  606. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +424 -22
  607. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +421 -19
  608. nautobot/project-static/docs/user-guide/platform-functionality/role.html +421 -19
  609. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +421 -19
  610. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +421 -19
  611. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +424 -22
  612. nautobot/project-static/docs/user-guide/platform-functionality/status.html +421 -19
  613. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +421 -19
  614. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +489 -56
  615. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +421 -19
  616. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +421 -19
  617. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +421 -19
  618. nautobot/project-static/img/jinja_logo.svg +97 -0
  619. nautobot/project-static/js/forms.js +5 -0
  620. nautobot/project-static/js/nav_menu.js +2 -1
  621. nautobot/tenancy/api/serializers.py +0 -2
  622. nautobot/tenancy/factory.py +1 -1
  623. nautobot/tenancy/navigation.py +0 -29
  624. nautobot/tenancy/templates/tenancy/tenant.html +4 -91
  625. nautobot/tenancy/tests/test_filters.py +29 -134
  626. nautobot/tenancy/views.py +32 -23
  627. nautobot/users/admin.py +3 -1
  628. nautobot/users/api/serializers.py +4 -5
  629. nautobot/users/api/views.py +1 -1
  630. nautobot/users/forms.py +19 -0
  631. nautobot/users/templates/users/preferences.html +22 -0
  632. nautobot/users/tests/test_filters.py +1 -19
  633. nautobot/users/tests/test_views.py +57 -0
  634. nautobot/users/utils.py +8 -0
  635. nautobot/users/views.py +48 -11
  636. nautobot/virtualization/api/serializers.py +4 -4
  637. nautobot/virtualization/filters.py +2 -20
  638. nautobot/virtualization/navigation.py +0 -48
  639. nautobot/virtualization/templates/virtualization/clustertype.html +0 -39
  640. nautobot/virtualization/tests/test_filters.py +57 -183
  641. nautobot/virtualization/views.py +18 -15
  642. nautobot/wireless/__init__.py +0 -0
  643. nautobot/wireless/api/__init__.py +0 -0
  644. nautobot/wireless/api/serializers.py +44 -0
  645. nautobot/wireless/api/urls.py +20 -0
  646. nautobot/wireless/api/views.py +34 -0
  647. nautobot/wireless/apps.py +8 -0
  648. nautobot/wireless/choices.py +345 -0
  649. nautobot/wireless/factory.py +138 -0
  650. nautobot/wireless/filters.py +167 -0
  651. nautobot/wireless/forms.py +283 -0
  652. nautobot/wireless/homepage.py +19 -0
  653. nautobot/wireless/migrations/0001_initial.py +223 -0
  654. nautobot/wireless/migrations/__init__.py +0 -0
  655. nautobot/wireless/models.py +207 -0
  656. nautobot/wireless/navigation.py +105 -0
  657. nautobot/wireless/tables.py +244 -0
  658. nautobot/wireless/templates/wireless/radioprofile_retrieve.html +81 -0
  659. nautobot/wireless/templates/wireless/supporteddatarate_retrieve.html +26 -0
  660. nautobot/wireless/templates/wireless/wirelessnetwork_create.html +88 -0
  661. nautobot/wireless/templates/wireless/wirelessnetwork_retrieve.html +64 -0
  662. nautobot/wireless/tests/__init__.py +0 -0
  663. nautobot/wireless/tests/test_api.py +247 -0
  664. nautobot/wireless/tests/test_filters.py +54 -0
  665. nautobot/wireless/tests/test_models.py +22 -0
  666. nautobot/wireless/tests/test_views.py +378 -0
  667. nautobot/wireless/urls.py +13 -0
  668. nautobot/wireless/views.py +129 -0
  669. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/METADATA +11 -14
  670. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/RECORD +674 -551
  671. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/WHEEL +1 -1
  672. nautobot/core/utils/navigation.py +0 -54
  673. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/LICENSE.txt +0 -0
  674. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/NOTICE +0 -0
  675. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/entry_points.txt +0 -0
@@ -18,7 +18,7 @@
18
18
 
19
19
 
20
20
  <link rel="icon" href="../../../../assets/favicon.ico">
21
- <meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.5.49">
21
+ <meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.5.46">
22
22
 
23
23
 
24
24
 
@@ -3944,6 +3944,27 @@
3944
3944
 
3945
3945
 
3946
3946
 
3947
+
3948
+
3949
+
3950
+
3951
+
3952
+
3953
+ <li class="md-nav__item">
3954
+ <a href="../../../../user-guide/core-data-model/dcim/virtualdevicecontext.html" class="md-nav__link">
3955
+
3956
+
3957
+ <span class="md-ellipsis">
3958
+ Virtual Device Context
3959
+ </span>
3960
+
3961
+
3962
+ </a>
3963
+ </li>
3964
+
3965
+
3966
+
3967
+
3947
3968
  </ul>
3948
3969
  </nav>
3949
3970
 
@@ -4556,6 +4577,123 @@
4556
4577
 
4557
4578
 
4558
4579
 
4580
+
4581
+
4582
+
4583
+
4584
+
4585
+
4586
+
4587
+
4588
+
4589
+
4590
+
4591
+
4592
+
4593
+ <li class="md-nav__item md-nav__item--nested">
4594
+
4595
+
4596
+
4597
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_3_9" >
4598
+
4599
+
4600
+
4601
+ <div class="md-nav__link md-nav__container">
4602
+ <a href="../../../../user-guide/core-data-model/wireless/index.html" class="md-nav__link ">
4603
+
4604
+
4605
+ <span class="md-ellipsis">
4606
+ Wireless
4607
+ </span>
4608
+
4609
+
4610
+ </a>
4611
+
4612
+
4613
+ <label class="md-nav__link " for="__nav_2_3_9" id="__nav_2_3_9_label" tabindex="0">
4614
+ <span class="md-nav__icon md-icon"></span>
4615
+ </label>
4616
+
4617
+ </div>
4618
+
4619
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_3_9_label" aria-expanded="false">
4620
+ <label class="md-nav__title" for="__nav_2_3_9">
4621
+ <span class="md-nav__icon md-icon"></span>
4622
+ Wireless
4623
+ </label>
4624
+ <ul class="md-nav__list" data-md-scrollfix>
4625
+
4626
+
4627
+
4628
+
4629
+
4630
+
4631
+
4632
+ <li class="md-nav__item">
4633
+ <a href="../../../../user-guide/core-data-model/wireless/supporteddatarate.html" class="md-nav__link">
4634
+
4635
+
4636
+ <span class="md-ellipsis">
4637
+ Supported Data Rate
4638
+ </span>
4639
+
4640
+
4641
+ </a>
4642
+ </li>
4643
+
4644
+
4645
+
4646
+
4647
+
4648
+
4649
+
4650
+
4651
+
4652
+
4653
+ <li class="md-nav__item">
4654
+ <a href="../../../../user-guide/core-data-model/wireless/radioprofile.html" class="md-nav__link">
4655
+
4656
+
4657
+ <span class="md-ellipsis">
4658
+ Radio Profile
4659
+ </span>
4660
+
4661
+
4662
+ </a>
4663
+ </li>
4664
+
4665
+
4666
+
4667
+
4668
+
4669
+
4670
+
4671
+
4672
+
4673
+
4674
+ <li class="md-nav__item">
4675
+ <a href="../../../../user-guide/core-data-model/wireless/wirelessnetwork.html" class="md-nav__link">
4676
+
4677
+
4678
+ <span class="md-ellipsis">
4679
+ Wireless Network
4680
+ </span>
4681
+
4682
+
4683
+ </a>
4684
+ </li>
4685
+
4686
+
4687
+
4688
+
4689
+ </ul>
4690
+ </nav>
4691
+
4692
+ </li>
4693
+
4694
+
4695
+
4696
+
4559
4697
  </ul>
4560
4698
  </nav>
4561
4699
 
@@ -4767,6 +4905,27 @@
4767
4905
 
4768
4906
 
4769
4907
 
4908
+ <li class="md-nav__item">
4909
+ <a href="../../../../user-guide/platform-functionality/events.html" class="md-nav__link">
4910
+
4911
+
4912
+ <span class="md-ellipsis">
4913
+ Event Notifications
4914
+ </span>
4915
+
4916
+
4917
+ </a>
4918
+ </li>
4919
+
4920
+
4921
+
4922
+
4923
+
4924
+
4925
+
4926
+
4927
+
4928
+
4770
4929
  <li class="md-nav__item">
4771
4930
  <a href="../../../../user-guide/platform-functionality/exporttemplate.html" class="md-nav__link">
4772
4931
 
@@ -4841,7 +5000,7 @@
4841
5000
 
4842
5001
 
4843
5002
 
4844
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_9" >
5003
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_10" >
4845
5004
 
4846
5005
 
4847
5006
 
@@ -4857,14 +5016,14 @@
4857
5016
  </a>
4858
5017
 
4859
5018
 
4860
- <label class="md-nav__link " for="__nav_2_4_9" id="__nav_2_4_9_label" tabindex="0">
5019
+ <label class="md-nav__link " for="__nav_2_4_10" id="__nav_2_4_10_label" tabindex="0">
4861
5020
  <span class="md-nav__icon md-icon"></span>
4862
5021
  </label>
4863
5022
 
4864
5023
  </div>
4865
5024
 
4866
- <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_9_label" aria-expanded="false">
4867
- <label class="md-nav__title" for="__nav_2_4_9">
5025
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_10_label" aria-expanded="false">
5026
+ <label class="md-nav__title" for="__nav_2_4_10">
4868
5027
  <span class="md-nav__icon md-icon"></span>
4869
5028
  GraphQL
4870
5029
  </label>
@@ -4937,7 +5096,7 @@
4937
5096
 
4938
5097
 
4939
5098
 
4940
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_11" >
5099
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_12" >
4941
5100
 
4942
5101
 
4943
5102
 
@@ -4953,14 +5112,14 @@
4953
5112
  </a>
4954
5113
 
4955
5114
 
4956
- <label class="md-nav__link " for="__nav_2_4_11" id="__nav_2_4_11_label" tabindex="0">
5115
+ <label class="md-nav__link " for="__nav_2_4_12" id="__nav_2_4_12_label" tabindex="0">
4957
5116
  <span class="md-nav__icon md-icon"></span>
4958
5117
  </label>
4959
5118
 
4960
5119
  </div>
4961
5120
 
4962
- <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_11_label" aria-expanded="false">
4963
- <label class="md-nav__title" for="__nav_2_4_11">
5121
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_12_label" aria-expanded="false">
5122
+ <label class="md-nav__title" for="__nav_2_4_12">
4964
5123
  <span class="md-nav__icon md-icon"></span>
4965
5124
  Jobs
4966
5125
  </label>
@@ -5035,6 +5194,27 @@
5035
5194
 
5036
5195
 
5037
5196
 
5197
+ <li class="md-nav__item">
5198
+ <a href="../../../../user-guide/platform-functionality/jobs/jobqueue.html" class="md-nav__link">
5199
+
5200
+
5201
+ <span class="md-ellipsis">
5202
+ Job Queues
5203
+ </span>
5204
+
5205
+
5206
+ </a>
5207
+ </li>
5208
+
5209
+
5210
+
5211
+
5212
+
5213
+
5214
+
5215
+
5216
+
5217
+
5038
5218
  <li class="md-nav__item">
5039
5219
  <a href="../../../../user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html" class="md-nav__link">
5040
5220
 
@@ -5148,6 +5328,27 @@
5148
5328
 
5149
5329
 
5150
5330
 
5331
+ <li class="md-nav__item">
5332
+ <a href="../../../../user-guide/platform-functionality/rendering-jinja-templates.html" class="md-nav__link">
5333
+
5334
+
5335
+ <span class="md-ellipsis">
5336
+ Rendering Jinja Templates
5337
+ </span>
5338
+
5339
+
5340
+ </a>
5341
+ </li>
5342
+
5343
+
5344
+
5345
+
5346
+
5347
+
5348
+
5349
+
5350
+
5351
+
5151
5352
 
5152
5353
 
5153
5354
 
@@ -5159,7 +5360,7 @@
5159
5360
 
5160
5361
 
5161
5362
 
5162
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_16" >
5363
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_18" >
5163
5364
 
5164
5365
 
5165
5366
 
@@ -5175,14 +5376,14 @@
5175
5376
  </a>
5176
5377
 
5177
5378
 
5178
- <label class="md-nav__link " for="__nav_2_4_16" id="__nav_2_4_16_label" tabindex="0">
5379
+ <label class="md-nav__link " for="__nav_2_4_18" id="__nav_2_4_18_label" tabindex="0">
5179
5380
  <span class="md-nav__icon md-icon"></span>
5180
5381
  </label>
5181
5382
 
5182
5383
  </div>
5183
5384
 
5184
- <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_16_label" aria-expanded="false">
5185
- <label class="md-nav__title" for="__nav_2_4_16">
5385
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_18_label" aria-expanded="false">
5386
+ <label class="md-nav__title" for="__nav_2_4_18">
5186
5387
  <span class="md-nav__icon md-icon"></span>
5187
5388
  REST API
5188
5389
  </label>
@@ -5402,10 +5603,10 @@
5402
5603
 
5403
5604
 
5404
5605
 
5405
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_23" >
5606
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_25" >
5406
5607
 
5407
5608
 
5408
- <label class="md-nav__link" for="__nav_2_4_23" id="__nav_2_4_23_label" tabindex="0">
5609
+ <label class="md-nav__link" for="__nav_2_4_25" id="__nav_2_4_25_label" tabindex="0">
5409
5610
 
5410
5611
 
5411
5612
  <span class="md-ellipsis">
@@ -5416,8 +5617,8 @@
5416
5617
  <span class="md-nav__icon md-icon"></span>
5417
5618
  </label>
5418
5619
 
5419
- <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_23_label" aria-expanded="false">
5420
- <label class="md-nav__title" for="__nav_2_4_23">
5620
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_25_label" aria-expanded="false">
5621
+ <label class="md-nav__title" for="__nav_2_4_25">
5421
5622
  <span class="md-nav__icon md-icon"></span>
5422
5623
  Users
5423
5624
  </label>
@@ -6628,24 +6829,96 @@
6628
6829
  </span>
6629
6830
  </a>
6630
6831
 
6832
+ <nav class="md-nav" aria-label="Extending Object Detail Views">
6833
+ <ul class="md-nav__list">
6834
+
6835
+ <li class="md-nav__item">
6836
+ <a href="#additional-methods-and-the-render-context" class="md-nav__link">
6837
+ <span class="md-ellipsis">
6838
+ Additional Methods and the Render Context
6839
+ </span>
6840
+ </a>
6841
+
6842
+ </li>
6843
+
6844
+ </ul>
6845
+ </nav>
6846
+
6631
6847
  </li>
6632
6848
 
6633
6849
  <li class="md-nav__item">
6634
- <a href="#adding-detail-tabs" class="md-nav__link">
6850
+ <a href="#adding-detail-panels" class="md-nav__link">
6635
6851
  <span class="md-ellipsis">
6636
- Adding Detail Tabs
6852
+ Adding Detail Panels
6853
+ </span>
6854
+ </a>
6855
+
6856
+ <nav class="md-nav" aria-label="Adding Detail Panels">
6857
+ <ul class="md-nav__list">
6858
+
6859
+ <li class="md-nav__item">
6860
+ <a href="#via-object_detail_panels" class="md-nav__link">
6861
+ <span class="md-ellipsis">
6862
+ Via object_detail_panels
6637
6863
  </span>
6638
6864
  </a>
6639
6865
 
6866
+ </li>
6867
+
6868
+ <li class="md-nav__item">
6869
+ <a href="#via-the-_page-methods-deprecated" class="md-nav__link">
6870
+ <span class="md-ellipsis">
6871
+ Via the *_page() Methods (Deprecated)
6872
+ </span>
6873
+ </a>
6874
+
6875
+ </li>
6876
+
6877
+ </ul>
6878
+ </nav>
6879
+
6640
6880
  </li>
6641
6881
 
6642
6882
  <li class="md-nav__item">
6643
- <a href="#example-adding-object-details-and-tabs" class="md-nav__link">
6883
+ <a href="#adding-detail-tabs" class="md-nav__link">
6644
6884
  <span class="md-ellipsis">
6645
- Example Adding Object Details and Tabs
6885
+ Adding Detail Tabs
6886
+ </span>
6887
+ </a>
6888
+
6889
+ <nav class="md-nav" aria-label="Adding Detail Tabs">
6890
+ <ul class="md-nav__list">
6891
+
6892
+ <li class="md-nav__item">
6893
+ <a href="#via-object_detail_tabs" class="md-nav__link">
6894
+ <span class="md-ellipsis">
6895
+ Via object_detail_tabs
6646
6896
  </span>
6647
6897
  </a>
6648
6898
 
6899
+ </li>
6900
+
6901
+ <li class="md-nav__item">
6902
+ <a href="#via-detail_tabs-deprecated" class="md-nav__link">
6903
+ <span class="md-ellipsis">
6904
+ Via detail_tabs() (Deprecated)
6905
+ </span>
6906
+ </a>
6907
+
6908
+ </li>
6909
+
6910
+ <li class="md-nav__item">
6911
+ <a href="#defining-distinct-tab-views" class="md-nav__link">
6912
+ <span class="md-ellipsis">
6913
+ Defining Distinct Tab Views
6914
+ </span>
6915
+ </a>
6916
+
6917
+ </li>
6918
+
6919
+ </ul>
6920
+ </nav>
6921
+
6649
6922
  </li>
6650
6923
 
6651
6924
  </ul>
@@ -6898,6 +7171,27 @@
6898
7171
 
6899
7172
 
6900
7173
 
7174
+ <li class="md-nav__item">
7175
+ <a href="../../../../code-reference/nautobot/apps/events.html" class="md-nav__link">
7176
+
7177
+
7178
+ <span class="md-ellipsis">
7179
+ nautobot.apps.events
7180
+ </span>
7181
+
7182
+
7183
+ </a>
7184
+ </li>
7185
+
7186
+
7187
+
7188
+
7189
+
7190
+
7191
+
7192
+
7193
+
7194
+
6901
7195
  <li class="md-nav__item">
6902
7196
  <a href="../../../../code-reference/nautobot/apps/exceptions.html" class="md-nav__link">
6903
7197
 
@@ -7446,6 +7740,123 @@
7446
7740
 
7447
7741
 
7448
7742
 
7743
+
7744
+
7745
+
7746
+
7747
+
7748
+
7749
+
7750
+
7751
+
7752
+
7753
+
7754
+
7755
+
7756
+ <li class="md-nav__item md-nav__item--nested">
7757
+
7758
+
7759
+
7760
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_2_9_5" >
7761
+
7762
+
7763
+
7764
+ <div class="md-nav__link md-nav__container">
7765
+ <a href="../../migration/ui-component-framework/index.html" class="md-nav__link ">
7766
+
7767
+
7768
+ <span class="md-ellipsis">
7769
+ UI Component Framework
7770
+ </span>
7771
+
7772
+
7773
+ </a>
7774
+
7775
+
7776
+ <label class="md-nav__link " for="__nav_3_2_9_5" id="__nav_3_2_9_5_label" tabindex="0">
7777
+ <span class="md-nav__icon md-icon"></span>
7778
+ </label>
7779
+
7780
+ </div>
7781
+
7782
+ <nav class="md-nav" data-md-level="4" aria-labelledby="__nav_3_2_9_5_label" aria-expanded="false">
7783
+ <label class="md-nav__title" for="__nav_3_2_9_5">
7784
+ <span class="md-nav__icon md-icon"></span>
7785
+ UI Component Framework
7786
+ </label>
7787
+ <ul class="md-nav__list" data-md-scrollfix>
7788
+
7789
+
7790
+
7791
+
7792
+
7793
+
7794
+
7795
+ <li class="md-nav__item">
7796
+ <a href="../../migration/ui-component-framework/migration-steps.html" class="md-nav__link">
7797
+
7798
+
7799
+ <span class="md-ellipsis">
7800
+ Migration steps
7801
+ </span>
7802
+
7803
+
7804
+ </a>
7805
+ </li>
7806
+
7807
+
7808
+
7809
+
7810
+
7811
+
7812
+
7813
+
7814
+
7815
+
7816
+ <li class="md-nav__item">
7817
+ <a href="../../migration/ui-component-framework/custom-content.html" class="md-nav__link">
7818
+
7819
+
7820
+ <span class="md-ellipsis">
7821
+ Custom content
7822
+ </span>
7823
+
7824
+
7825
+ </a>
7826
+ </li>
7827
+
7828
+
7829
+
7830
+
7831
+
7832
+
7833
+
7834
+
7835
+
7836
+
7837
+ <li class="md-nav__item">
7838
+ <a href="../../migration/ui-component-framework/best-practices.html" class="md-nav__link">
7839
+
7840
+
7841
+ <span class="md-ellipsis">
7842
+ Best practices
7843
+ </span>
7844
+
7845
+
7846
+ </a>
7847
+ </li>
7848
+
7849
+
7850
+
7851
+
7852
+ </ul>
7853
+ </nav>
7854
+
7855
+ </li>
7856
+
7857
+
7858
+
7859
+
7449
7860
  </ul>
7450
7861
  </nav>
7451
7862
 
@@ -7791,6 +8202,27 @@
7791
8202
 
7792
8203
 
7793
8204
 
8205
+ <li class="md-nav__item">
8206
+ <a href="../../../core/local-k8s.html" class="md-nav__link">
8207
+
8208
+
8209
+ <span class="md-ellipsis">
8210
+ Local Kubernetes Cluster
8211
+ </span>
8212
+
8213
+
8214
+ </a>
8215
+ </li>
8216
+
8217
+
8218
+
8219
+
8220
+
8221
+
8222
+
8223
+
8224
+
8225
+
7794
8226
  <li class="md-nav__item">
7795
8227
  <a href="../../../core/model-checklist.html" class="md-nav__link">
7796
8228
 
@@ -7980,6 +8412,27 @@
7980
8412
 
7981
8413
 
7982
8414
 
8415
+ <li class="md-nav__item">
8416
+ <a href="../../../core/ui-component-framework.html" class="md-nav__link">
8417
+
8418
+
8419
+ <span class="md-ellipsis">
8420
+ UI Component Framework
8421
+ </span>
8422
+
8423
+
8424
+ </a>
8425
+ </li>
8426
+
8427
+
8428
+
8429
+
8430
+
8431
+
8432
+
8433
+
8434
+
8435
+
7983
8436
  <li class="md-nav__item">
7984
8437
  <a href="../../../core/release-checklist.html" class="md-nav__link">
7985
8438
 
@@ -8062,6 +8515,27 @@
8062
8515
 
8063
8516
 
8064
8517
 
8518
+ <li class="md-nav__item">
8519
+ <a href="../../../../release-notes/version-2.4.html" class="md-nav__link">
8520
+
8521
+
8522
+ <span class="md-ellipsis">
8523
+ Version 2.4
8524
+ </span>
8525
+
8526
+
8527
+ </a>
8528
+ </li>
8529
+
8530
+
8531
+
8532
+
8533
+
8534
+
8535
+
8536
+
8537
+
8538
+
8065
8539
  <li class="md-nav__item">
8066
8540
  <a href="../../../../release-notes/version-2.3.html" class="md-nav__link">
8067
8541
 
@@ -8656,6 +9130,54 @@
8656
9130
  </span>
8657
9131
  </a>
8658
9132
 
9133
+ <nav class="md-nav" aria-label="Extending Object Detail Views">
9134
+ <ul class="md-nav__list">
9135
+
9136
+ <li class="md-nav__item">
9137
+ <a href="#additional-methods-and-the-render-context" class="md-nav__link">
9138
+ <span class="md-ellipsis">
9139
+ Additional Methods and the Render Context
9140
+ </span>
9141
+ </a>
9142
+
9143
+ </li>
9144
+
9145
+ </ul>
9146
+ </nav>
9147
+
9148
+ </li>
9149
+
9150
+ <li class="md-nav__item">
9151
+ <a href="#adding-detail-panels" class="md-nav__link">
9152
+ <span class="md-ellipsis">
9153
+ Adding Detail Panels
9154
+ </span>
9155
+ </a>
9156
+
9157
+ <nav class="md-nav" aria-label="Adding Detail Panels">
9158
+ <ul class="md-nav__list">
9159
+
9160
+ <li class="md-nav__item">
9161
+ <a href="#via-object_detail_panels" class="md-nav__link">
9162
+ <span class="md-ellipsis">
9163
+ Via object_detail_panels
9164
+ </span>
9165
+ </a>
9166
+
9167
+ </li>
9168
+
9169
+ <li class="md-nav__item">
9170
+ <a href="#via-the-_page-methods-deprecated" class="md-nav__link">
9171
+ <span class="md-ellipsis">
9172
+ Via the *_page() Methods (Deprecated)
9173
+ </span>
9174
+ </a>
9175
+
9176
+ </li>
9177
+
9178
+ </ul>
9179
+ </nav>
9180
+
8659
9181
  </li>
8660
9182
 
8661
9183
  <li class="md-nav__item">
@@ -8665,15 +9187,39 @@
8665
9187
  </span>
8666
9188
  </a>
8667
9189
 
9190
+ <nav class="md-nav" aria-label="Adding Detail Tabs">
9191
+ <ul class="md-nav__list">
9192
+
9193
+ <li class="md-nav__item">
9194
+ <a href="#via-object_detail_tabs" class="md-nav__link">
9195
+ <span class="md-ellipsis">
9196
+ Via object_detail_tabs
9197
+ </span>
9198
+ </a>
9199
+
8668
9200
  </li>
8669
-
8670
- <li class="md-nav__item">
8671
- <a href="#example-adding-object-details-and-tabs" class="md-nav__link">
9201
+
9202
+ <li class="md-nav__item">
9203
+ <a href="#via-detail_tabs-deprecated" class="md-nav__link">
8672
9204
  <span class="md-ellipsis">
8673
- Example Adding Object Details and Tabs
9205
+ Via detail_tabs() (Deprecated)
8674
9206
  </span>
8675
9207
  </a>
8676
9208
 
9209
+ </li>
9210
+
9211
+ <li class="md-nav__item">
9212
+ <a href="#defining-distinct-tab-views" class="md-nav__link">
9213
+ <span class="md-ellipsis">
9214
+ Defining Distinct Tab Views
9215
+ </span>
9216
+ </a>
9217
+
9218
+ </li>
9219
+
9220
+ </ul>
9221
+ </nav>
9222
+
8677
9223
  </li>
8678
9224
 
8679
9225
  </ul>
@@ -8696,21 +9242,31 @@
8696
9242
 
8697
9243
  <h1 id="extending-object-detail-views-and-tabs">Extending Object Detail Views and Tabs<a class="headerlink" href="#extending-object-detail-views-and-tabs" title="Permanent link">&para;</a></h1>
8698
9244
  <h2 id="extending-object-detail-views">Extending Object Detail Views<a class="headerlink" href="#extending-object-detail-views" title="Permanent link">&para;</a></h2>
8699
- <p>Apps can inject custom content into certain areas of the detail and list views of applicable models. This is accomplished by subclassing <code>TemplateExtension</code>, designating a particular Nautobot model, and defining the desired methods to render custom content. Six methods are available:</p>
9245
+ <p>Apps can inject custom content into certain areas of the detail and list views of applicable models. This is accomplished by subclassing <code>TemplateExtension</code>, designating a particular Nautobot model, and defining the desired attributes and/or methods to provide custom content. Several attributes and methods are available:</p>
8700
9246
  <ul>
8701
- <li><code>left_page()</code> - Inject content on the left side of the object detail page</li>
8702
- <li><code>right_page()</code> - Inject content on the right side of the object detail page</li>
8703
- <li><code>full_width_page()</code> - Inject content across the entire bottom of the object detail page</li>
8704
- <li><code>buttons()</code> - Add buttons to the top of the object detail page</li>
9247
+ <li><code>object_detail_tabs</code> - List of <code>Tab</code> instances to add to the detail view as additional tabs.</li>
9248
+ <li><code>object_detail_buttons</code> - List of <code>Button</code> instances to add to the detail view.</li>
9249
+ <li><code>object_detail_panels</code> - List of <code>Panel</code> instances to add to the main tab of the detail view.</li>
9250
+ <li><code>left_page()</code> - Inject content on the left side of the object detail page (deprecated since Nautobot 2.4.0; <code>object_detail_panels</code> is preferred)</li>
9251
+ <li><code>right_page()</code> - Inject content on the right side of the object detail page (deprecated since Nautobot 2.4.0; <code>object_detail_panels</code> is preferred)</li>
9252
+ <li><code>full_width_page()</code> - Inject content across the entire bottom of the object detail page (deprecated since Nautobot 2.4.0; <code>object_detail_panels</code> is preferred)</li>
9253
+ <li><code>buttons()</code> - Add buttons to the top of the object detail page (deprecated since Nautobot 2.4.0; <code>object_detail_buttons</code> is preferred)</li>
8705
9254
  <li><code>list_buttons()</code> - Add buttons to the object list page. This works in the same way as <code>buttons()</code> for the object detail page.</li>
8706
- <li><code>detail_tabs()</code> - Add extra tabs to the end of the list of tabs within the object detail page tabs navigation</li>
9255
+ <li><code>detail_tabs()</code> - Add extra tabs to the end of the list of tabs within the object detail page tabs navigation (deprecated since Nautobot 2.4.0; <code>object_detail_tabs</code> is preferred)</li>
8707
9256
  </ul>
8708
9257
  <details class="version-added">
8709
- <summary>Added in version 2.1.8</summary>
9258
+ <summary>Added in version 2.1.8 — <code>list_buttons()</code> support</summary>
8710
9259
  <p>Support for the <code>list_buttons()</code> method was added.</p>
8711
9260
  </details>
8712
- <p>Additionally, a <code>render()</code> method is available for convenience. This method accepts the name of a template to render, and any additional context data you want to pass. Its use is optional, however.</p>
8713
- <p>When a TemplateExtension is instantiated, context data is assigned to <code>self.context</code>. Available data include:</p>
9261
+ <details class="version-changed">
9262
+ <summary>Changed in version 2.4.0 <code>object_detail_tabs</code>, <code>object_detail_buttons</code>, <code>object_detail_panels</code> support, deprecation of some patterns</summary>
9263
+ <p>Support for the <code>object_detail_tabs</code>, <code>object_detail_buttons</code>, and <code>object_detail_panels</code> attributes was added. The <code>detail_tabs()</code>, <code>buttons()</code>, <code>left_page()</code>, <code>right_page()</code>, and <code>full_width_page()</code> methods were deprecated.</p>
9264
+ </details>
9265
+ <p>For details about the <code>Tab</code>, <code>Button</code>, and <code>Panel</code> classes and their subclasses, refer to the <a href="../../../../code-reference/nautobot/apps/ui.html">relevant section of documentation</a> for full details. You may also find the <a href="../../../core/ui-component-framework.html">UI Component Framework documentation</a> a useful reference as most of the concepts described therein apply to template extensions as well.</p>
9266
+ <p>Declared subclasses should be gathered into a list or tuple for integration with Nautobot. By default, Nautobot looks for an iterable named <code>template_extensions</code> within a <code>template_content.py</code> file. (This can be overridden by setting <code>template_extensions</code> to a custom value on the app's <code>NautobotAppConfig</code>.)</p>
9267
+ <h3 id="additional-methods-and-the-render-context">Additional Methods and the Render Context<a class="headerlink" href="#additional-methods-and-the-render-context" title="Permanent link">&para;</a></h3>
9268
+ <p>In support of the method APIs described above, a <code>render()</code> method is available for convenience. This method accepts the name of a template to render, and any additional context data you want to pass. Its use is optional, however.</p>
9269
+ <p>When a TemplateExtension is instantiated, context data is assigned to <code>self.context</code> for the method APIs to access as needed. Available data include:</p>
8714
9270
  <ul>
8715
9271
  <li><code>object</code> - The object being viewed (note that this will be the model class when accessed in the context of <code>list_buttons()</code>)</li>
8716
9272
  <li><code>request</code> - The current request</li>
@@ -8718,8 +9274,72 @@
8718
9274
  <li><code>config</code> - App-specific configuration parameters</li>
8719
9275
  </ul>
8720
9276
  <p>For example, accessing <code>{{ request.user }}</code> within a template will return the current user.</p>
8721
- <p>Declared subclasses should be gathered into a list or tuple for integration with Nautobot. By default, Nautobot looks for an iterable named <code>template_extensions</code> within a <code>template_content.py</code> file. (This can be overridden by setting <code>template_extensions</code> to a custom value on the app's <code>NautobotAppConfig</code>.) An example is <a href="#example-adding-object-details-and-tabs">below</a>.</p>
9277
+ <h2 id="adding-detail-panels">Adding Detail Panels<a class="headerlink" href="#adding-detail-panels" title="Permanent link">&para;</a></h2>
9278
+ <h3 id="via-object_detail_panels">Via <code>object_detail_panels</code><a class="headerlink" href="#via-object_detail_panels" title="Permanent link">&para;</a></h3>
9279
+ <details class="version-added">
9280
+ <summary>Added in version 2.4.0</summary>
9281
+ </details>
9282
+ <p>The <code>TemplateExtension.object_detail_panels</code> should be a list or tuple of Panel objects (as provided by the <code>nautobot.apps.ui</code> module). A variety of base classes are available; refer to the <a href="../../../../code-reference/nautobot/apps/ui.html">relevant section of documentation</a> for full details. You may also find the <a href="../../../core/ui-component-framework.html">UI Component Framework documentation</a> a useful reference as most of the concepts described therein apply to template extensions as well.</p>
9283
+ <p>For example:</p>
9284
+ <div class="highlight"><span class="filename">example_app/template_content.py</span><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.ui</span> <span class="kn">import</span> <span class="n">ObjectTextPanel</span><span class="p">,</span> <span class="n">SectionChoices</span><span class="p">,</span> <span class="n">TemplateExtension</span>
9285
+ <a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a>
9286
+ <a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a>
9287
+ <a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a><span class="k">class</span> <span class="nc">CircuitContent</span><span class="p">(</span><span class="n">TemplateExtension</span><span class="p">):</span>
9288
+ <a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a> <span class="n">model</span> <span class="o">=</span> <span class="s2">&quot;circuits.circuit&quot;</span>
9289
+ <a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a>
9290
+ <a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a> <span class="n">object_detail_panels</span> <span class="o">=</span> <span class="p">(</span>
9291
+ <a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a> <span class="n">ObjectTextPanel</span><span class="p">(</span>
9292
+ <a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a> <span class="n">weight</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span>
9293
+ <a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a> <span class="n">label</span><span class="o">=</span><span class="s2">&quot;Example App Text Panel&quot;</span><span class="p">,</span>
9294
+ <a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a> <span class="n">section</span><span class="o">=</span><span class="n">SectionChoices</span><span class="o">.</span><span class="n">LEFT_HALF</span><span class="p">,</span>
9295
+ <a id="__codelineno-0-12" name="__codelineno-0-12" href="#__codelineno-0-12"></a> <span class="n">render_as</span><span class="o">=</span><span class="n">ObjectTextPanel</span><span class="o">.</span><span class="n">RenderOptions</span><span class="o">.</span><span class="n">CODE</span><span class="p">,</span>
9296
+ <a id="__codelineno-0-13" name="__codelineno-0-13" href="#__codelineno-0-13"></a> <span class="n">object_field</span><span class="o">=</span><span class="s2">&quot;description&quot;</span><span class="p">,</span>
9297
+ <a id="__codelineno-0-14" name="__codelineno-0-14" href="#__codelineno-0-14"></a> <span class="p">),</span>
9298
+ <a id="__codelineno-0-15" name="__codelineno-0-15" href="#__codelineno-0-15"></a> <span class="p">)</span>
9299
+ <a id="__codelineno-0-16" name="__codelineno-0-16" href="#__codelineno-0-16"></a>
9300
+ <a id="__codelineno-0-17" name="__codelineno-0-17" href="#__codelineno-0-17"></a><span class="n">template_extensions</span> <span class="o">=</span> <span class="p">[</span><span class="n">CircuitContent</span><span class="p">]</span>
9301
+ </code></pre></div>
9302
+ <h3 id="via-the-_page-methods-deprecated">Via the <code>*_page()</code> Methods (Deprecated)<a class="headerlink" href="#via-the-_page-methods-deprecated" title="Permanent link">&para;</a></h3>
9303
+ <p>The <code>left_page()</code>, <code>right_page()</code>, and <code>full_width_page()</code> methods each simply return a fragment of HTML. You are responsible for ensuring that the returned HTML is properly constructed and doesn't break the page layout and rendering.</p>
8722
9304
  <h2 id="adding-detail-tabs">Adding Detail Tabs<a class="headerlink" href="#adding-detail-tabs" title="Permanent link">&para;</a></h2>
9305
+ <h3 id="via-object_detail_tabs">Via <code>object_detail_tabs</code><a class="headerlink" href="#via-object_detail_tabs" title="Permanent link">&para;</a></h3>
9306
+ <details class="version-added">
9307
+ <summary>Added in version 2.4.0</summary>
9308
+ </details>
9309
+ <p>The <code>TemplateExtension.object_detail_tabs</code> should be a list or tuple of Tab objects (as provided by the <code>nautobot.apps.ui</code> module). Two base classes are available:</p>
9310
+ <ul>
9311
+ <li><code>Tab</code> - add a tab and its contents to the main object detail page, rendered inline with the rest of that page. Best used for quick-rendering content.</li>
9312
+ <li><code>DistinctViewTab</code> - add a tab to the main object detail page that links to a distinct view of its own when clicked. Best used for more involved content.</li>
9313
+ </ul>
9314
+ <p>For example:</p>
9315
+ <div class="highlight"><span class="filename">example_app/template_content.py</span><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.ui</span> <span class="kn">import</span> <span class="n">DistinctViewTab</span><span class="p">,</span> <span class="n">Tab</span><span class="p">,</span> <span class="n">TemplateExtension</span>
9316
+ <a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a>
9317
+ <a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a>
9318
+ <a id="__codelineno-1-4" name="__codelineno-1-4" href="#__codelineno-1-4"></a><span class="k">class</span> <span class="nc">DeviceExtraTabs</span><span class="p">(</span><span class="n">TemplateExtension</span><span class="p">):</span>
9319
+ <a id="__codelineno-1-5" name="__codelineno-1-5" href="#__codelineno-1-5"></a> <span class="n">model</span> <span class="o">=</span> <span class="s2">&quot;dcim.device&quot;</span>
9320
+ <a id="__codelineno-1-6" name="__codelineno-1-6" href="#__codelineno-1-6"></a>
9321
+ <a id="__codelineno-1-7" name="__codelineno-1-7" href="#__codelineno-1-7"></a> <span class="n">object_detail_tabs</span> <span class="o">=</span> <span class="p">(</span>
9322
+ <a id="__codelineno-1-8" name="__codelineno-1-8" href="#__codelineno-1-8"></a> <span class="n">Tab</span><span class="p">(</span>
9323
+ <a id="__codelineno-1-9" name="__codelineno-1-9" href="#__codelineno-1-9"></a> <span class="n">weight</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span>
9324
+ <a id="__codelineno-1-10" name="__codelineno-1-10" href="#__codelineno-1-10"></a> <span class="n">tab_id</span><span class="o">=</span><span class="s2">&quot;example_app_inline_tab&quot;</span><span class="p">,</span>
9325
+ <a id="__codelineno-1-11" name="__codelineno-1-11" href="#__codelineno-1-11"></a> <span class="n">label</span><span class="o">=</span><span class="s2">&quot;Example App Inline Tab&quot;</span><span class="p">,</span>
9326
+ <a id="__codelineno-1-12" name="__codelineno-1-12" href="#__codelineno-1-12"></a> <span class="n">panels</span><span class="o">=</span><span class="p">[</span>
9327
+ <a id="__codelineno-1-13" name="__codelineno-1-13" href="#__codelineno-1-13"></a> <span class="n">ObjectFieldsPanel</span><span class="p">(</span><span class="n">weight</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span> <span class="n">fields</span><span class="o">=</span><span class="s2">&quot;__all__&quot;</span><span class="p">),</span>
9328
+ <a id="__codelineno-1-14" name="__codelineno-1-14" href="#__codelineno-1-14"></a> <span class="p">],</span>
9329
+ <a id="__codelineno-1-15" name="__codelineno-1-15" href="#__codelineno-1-15"></a> <span class="p">),</span>
9330
+ <a id="__codelineno-1-16" name="__codelineno-1-16" href="#__codelineno-1-16"></a> <span class="n">DistinctViewTab</span><span class="p">(</span>
9331
+ <a id="__codelineno-1-17" name="__codelineno-1-17" href="#__codelineno-1-17"></a> <span class="n">weight</span><span class="o">=</span><span class="mi">200</span><span class="p">,</span>
9332
+ <a id="__codelineno-1-18" name="__codelineno-1-18" href="#__codelineno-1-18"></a> <span class="n">tab_id</span><span class="o">=</span><span class="s2">&quot;example_app_distinct_view_tab&quot;</span><span class="p">,</span>
9333
+ <a id="__codelineno-1-19" name="__codelineno-1-19" href="#__codelineno-1-19"></a> <span class="n">label</span><span class="o">=</span><span class="s2">&quot;Example App Distinct View Tab&quot;</span><span class="p">,</span>
9334
+ <a id="__codelineno-1-20" name="__codelineno-1-20" href="#__codelineno-1-20"></a> <span class="n">url_name</span><span class="o">=</span><span class="s2">&quot;plugins:example_app:device_detail_tab_1&quot;</span><span class="p">,</span>
9335
+ <a id="__codelineno-1-21" name="__codelineno-1-21" href="#__codelineno-1-21"></a> <span class="p">),</span>
9336
+ <a id="__codelineno-1-22" name="__codelineno-1-22" href="#__codelineno-1-22"></a> <span class="p">)</span>
9337
+ <a id="__codelineno-1-23" name="__codelineno-1-23" href="#__codelineno-1-23"></a>
9338
+ <a id="__codelineno-1-24" name="__codelineno-1-24" href="#__codelineno-1-24"></a>
9339
+ <a id="__codelineno-1-25" name="__codelineno-1-25" href="#__codelineno-1-25"></a><span class="n">template_extensions</span> <span class="o">=</span> <span class="p">[</span><span class="n">DeviceExtraTabs</span><span class="p">]</span>
9340
+ </code></pre></div>
9341
+ <p>Note that a <code>Tab</code> defines its contents directly (as <code>panels</code>) while the <code>DistinctViewTab</code> instead provides a <code>url_name</code> to the related URL that it should link against.</p>
9342
+ <h3 id="via-detail_tabs-deprecated">Via <code>detail_tabs()</code> (Deprecated)<a class="headerlink" href="#via-detail_tabs-deprecated" title="Permanent link">&para;</a></h3>
8723
9343
  <details class="version-added">
8724
9344
  <summary>Added in version 1.4.0</summary>
8725
9345
  </details>
@@ -8730,109 +9350,60 @@
8730
9350
  <li>The template rendered by this view must extend the object's detail template</li>
8731
9351
  </ul>
8732
9352
  <p>For example:</p>
8733
- <div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="k">class</span> <span class="nc">DeviceExtraTabs</span><span class="p">(</span><span class="n">TemplateExtension</span><span class="p">):</span>
8734
- <a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Template extension to add extra tabs to the Device detail view.&quot;&quot;&quot;</span>
8735
- <a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a> <span class="n">model</span> <span class="o">=</span> <span class="s1">&#39;dcim.device&#39;</span>
8736
- <a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a>
8737
- <a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a> <span class="k">def</span> <span class="nf">detail_tabs</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
8738
- <a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a> <span class="k">return</span> <span class="p">[</span>
8739
- <a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a> <span class="p">{</span>
8740
- <a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a> <span class="s2">&quot;title&quot;</span><span class="p">:</span> <span class="s2">&quot;App Tab 1&quot;</span><span class="p">,</span>
8741
- <a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a> <span class="s2">&quot;url&quot;</span><span class="p">:</span> <span class="n">reverse</span><span class="p">(</span><span class="s2">&quot;plugins:example_app:device_detail_tab_1&quot;</span><span class="p">,</span> <span class="n">kwargs</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;pk&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">context</span><span class="p">[</span><span class="s2">&quot;object&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">pk</span><span class="p">}),</span>
8742
- <a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a> <span class="p">},</span>
8743
- <a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a> <span class="p">]</span>
9353
+ <div class="highlight"><span class="filename">example_app/template_content.py</span><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a><span class="k">class</span> <span class="nc">DeviceExtraTabs</span><span class="p">(</span><span class="n">TemplateExtension</span><span class="p">):</span>
9354
+ <a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Template extension to add extra tabs to the Device detail view.&quot;&quot;&quot;</span>
9355
+ <a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a> <span class="n">model</span> <span class="o">=</span> <span class="s2">&quot;dcim.device&quot;</span>
9356
+ <a id="__codelineno-2-4" name="__codelineno-2-4" href="#__codelineno-2-4"></a>
9357
+ <a id="__codelineno-2-5" name="__codelineno-2-5" href="#__codelineno-2-5"></a> <span class="k">def</span> <span class="nf">detail_tabs</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
9358
+ <a id="__codelineno-2-6" name="__codelineno-2-6" href="#__codelineno-2-6"></a> <span class="k">return</span> <span class="p">[</span>
9359
+ <a id="__codelineno-2-7" name="__codelineno-2-7" href="#__codelineno-2-7"></a> <span class="p">{</span>
9360
+ <a id="__codelineno-2-8" name="__codelineno-2-8" href="#__codelineno-2-8"></a> <span class="s2">&quot;title&quot;</span><span class="p">:</span> <span class="s2">&quot;App Tab 1&quot;</span><span class="p">,</span>
9361
+ <a id="__codelineno-2-9" name="__codelineno-2-9" href="#__codelineno-2-9"></a> <span class="s2">&quot;url&quot;</span><span class="p">:</span> <span class="n">reverse</span><span class="p">(</span><span class="s2">&quot;plugins:example_app:device_detail_tab_1&quot;</span><span class="p">,</span> <span class="n">kwargs</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;pk&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">context</span><span class="p">[</span><span class="s2">&quot;object&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">pk</span><span class="p">}),</span>
9362
+ <a id="__codelineno-2-10" name="__codelineno-2-10" href="#__codelineno-2-10"></a> <span class="p">},</span>
9363
+ <a id="__codelineno-2-11" name="__codelineno-2-11" href="#__codelineno-2-11"></a> <span class="p">]</span>
9364
+ <a id="__codelineno-2-12" name="__codelineno-2-12" href="#__codelineno-2-12"></a>
9365
+ <a id="__codelineno-2-13" name="__codelineno-2-13" href="#__codelineno-2-13"></a>
9366
+ <a id="__codelineno-2-14" name="__codelineno-2-14" href="#__codelineno-2-14"></a><span class="n">template_extensions</span> <span class="o">=</span> <span class="p">[</span><span class="n">DeviceExtraTabs</span><span class="p">]</span>
8744
9367
  </code></pre></div>
8745
- <div class="highlight"><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="cm">&lt;!-- example_app/tab_device_detail_1.html --&gt;</span>
8746
- <a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a>{% extends &#39;dcim/device.html&#39; %}
8747
- <a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a>
8748
- <a id="__codelineno-1-4" name="__codelineno-1-4" href="#__codelineno-1-4"></a>{% block content %}
8749
- <a id="__codelineno-1-5" name="__codelineno-1-5" href="#__codelineno-1-5"></a> <span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span>Device App Tab 1<span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span>
8750
- <a id="__codelineno-1-6" name="__codelineno-1-6" href="#__codelineno-1-6"></a> <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>I am some content for the Example App&#39;s device ({{ object.pk }}) detail tab 1.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
8751
- <a id="__codelineno-1-7" name="__codelineno-1-7" href="#__codelineno-1-7"></a>{% endblock %}
9368
+ <h3 id="defining-distinct-tab-views">Defining Distinct Tab Views<a class="headerlink" href="#defining-distinct-tab-views" title="Permanent link">&para;</a></h3>
9369
+ <p>In either of the above cases, you would need to define a new view for the <code>device_detail_tab_1</code> tab to display, following a pattern similar to the below.</p>
9370
+ <div class="highlight"><span class="filename">example_app/tab_device_detail_1.html</span><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a>{% extends &#39;dcim/device.html&#39; %}
9371
+ <a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a>
9372
+ <a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a>{% block content %}
9373
+ <a id="__codelineno-3-4" name="__codelineno-3-4" href="#__codelineno-3-4"></a> <span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span>Device App Tab 1<span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span>
9374
+ <a id="__codelineno-3-5" name="__codelineno-3-5" href="#__codelineno-3-5"></a> <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>I am some content for the Example App&#39;s device ({{ object.pk }}) detail tab 1.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
9375
+ <a id="__codelineno-3-6" name="__codelineno-3-6" href="#__codelineno-3-6"></a>{% endblock %}
8752
9376
  </code></pre></div>
8753
9377
  <p>Here's a basic example of a tab's view</p>
8754
- <div class="highlight"><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a><span class="c1"># views.py</span>
8755
- <a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a><span class="kn">from</span> <span class="nn">nautobot.apps.views</span> <span class="kn">import</span> <span class="n">ObjectView</span>
8756
- <a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a><span class="kn">from</span> <span class="nn">nautobot.dcim.models</span> <span class="kn">import</span> <span class="n">Device</span>
8757
- <a id="__codelineno-2-4" name="__codelineno-2-4" href="#__codelineno-2-4"></a>
8758
- <a id="__codelineno-2-5" name="__codelineno-2-5" href="#__codelineno-2-5"></a><span class="k">class</span> <span class="nc">DeviceDetailAppTabOne</span><span class="p">(</span><span class="n">ObjectView</span><span class="p">):</span>
8759
- <a id="__codelineno-2-6" name="__codelineno-2-6" href="#__codelineno-2-6"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
8760
- <a id="__codelineno-2-7" name="__codelineno-2-7" href="#__codelineno-2-7"></a><span class="sd"> This view&#39;s template extends the device detail template,</span>
8761
- <a id="__codelineno-2-8" name="__codelineno-2-8" href="#__codelineno-2-8"></a><span class="sd"> making it suitable to show as a tab on the device detail page.</span>
8762
- <a id="__codelineno-2-9" name="__codelineno-2-9" href="#__codelineno-2-9"></a>
8763
- <a id="__codelineno-2-10" name="__codelineno-2-10" href="#__codelineno-2-10"></a><span class="sd"> Views that are intended to be for an object detail tab&#39;s content rendering must</span>
8764
- <a id="__codelineno-2-11" name="__codelineno-2-11" href="#__codelineno-2-11"></a><span class="sd"> always inherit from nautobot.apps.views.ObjectView.</span>
8765
- <a id="__codelineno-2-12" name="__codelineno-2-12" href="#__codelineno-2-12"></a><span class="sd"> &quot;&quot;&quot;</span>
8766
- <a id="__codelineno-2-13" name="__codelineno-2-13" href="#__codelineno-2-13"></a>
8767
- <a id="__codelineno-2-14" name="__codelineno-2-14" href="#__codelineno-2-14"></a> <span class="n">queryset</span> <span class="o">=</span> <span class="n">Device</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
8768
- <a id="__codelineno-2-15" name="__codelineno-2-15" href="#__codelineno-2-15"></a> <span class="n">template_name</span> <span class="o">=</span> <span class="s2">&quot;example_app/tab_device_detail_1.html&quot;</span>
9378
+ <div class="highlight"><span class="filename">example_app/views.py</span><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.views</span> <span class="kn">import</span> <span class="n">ObjectView</span>
9379
+ <a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a><span class="kn">from</span> <span class="nn">nautobot.dcim.models</span> <span class="kn">import</span> <span class="n">Device</span>
9380
+ <a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a>
9381
+ <a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a><span class="k">class</span> <span class="nc">DeviceDetailAppTabOne</span><span class="p">(</span><span class="n">ObjectView</span><span class="p">):</span>
9382
+ <a id="__codelineno-4-5" name="__codelineno-4-5" href="#__codelineno-4-5"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
9383
+ <a id="__codelineno-4-6" name="__codelineno-4-6" href="#__codelineno-4-6"></a><span class="sd"> This view&#39;s template extends the device detail template,</span>
9384
+ <a id="__codelineno-4-7" name="__codelineno-4-7" href="#__codelineno-4-7"></a><span class="sd"> making it suitable to show as a tab on the device detail page.</span>
9385
+ <a id="__codelineno-4-8" name="__codelineno-4-8" href="#__codelineno-4-8"></a>
9386
+ <a id="__codelineno-4-9" name="__codelineno-4-9" href="#__codelineno-4-9"></a><span class="sd"> Views that are intended to be for an object detail tab&#39;s content rendering must</span>
9387
+ <a id="__codelineno-4-10" name="__codelineno-4-10" href="#__codelineno-4-10"></a><span class="sd"> always inherit from nautobot.apps.views.ObjectView.</span>
9388
+ <a id="__codelineno-4-11" name="__codelineno-4-11" href="#__codelineno-4-11"></a><span class="sd"> &quot;&quot;&quot;</span>
9389
+ <a id="__codelineno-4-12" name="__codelineno-4-12" href="#__codelineno-4-12"></a>
9390
+ <a id="__codelineno-4-13" name="__codelineno-4-13" href="#__codelineno-4-13"></a> <span class="n">queryset</span> <span class="o">=</span> <span class="n">Device</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
9391
+ <a id="__codelineno-4-14" name="__codelineno-4-14" href="#__codelineno-4-14"></a> <span class="n">template_name</span> <span class="o">=</span> <span class="s2">&quot;example_app/tab_device_detail_1.html&quot;</span>
8769
9392
  </code></pre></div>
8770
9393
  <p>You must also add the view to the <code>url_patterns</code> like so (make sure to read the note after this code snippet):</p>
8771
- <div class="highlight"><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a><span class="c1"># urls.py</span>
8772
- <a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a><span class="kn">from</span> <span class="nn">django.urls</span> <span class="kn">import</span> <span class="n">path</span>
8773
- <a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a>
8774
- <a id="__codelineno-3-4" name="__codelineno-3-4" href="#__codelineno-3-4"></a><span class="kn">from</span> <span class="nn">example_app</span> <span class="kn">import</span> <span class="n">views</span>
8775
- <a id="__codelineno-3-5" name="__codelineno-3-5" href="#__codelineno-3-5"></a>
8776
- <a id="__codelineno-3-6" name="__codelineno-3-6" href="#__codelineno-3-6"></a><span class="n">urlpatterns</span> <span class="o">=</span> <span class="p">[</span>
8777
- <a id="__codelineno-3-7" name="__codelineno-3-7" href="#__codelineno-3-7"></a> <span class="c1"># ... previously defined urls</span>
8778
- <a id="__codelineno-3-8" name="__codelineno-3-8" href="#__codelineno-3-8"></a> <span class="n">path</span><span class="p">(</span><span class="s2">&quot;devices/&lt;uuid:pk&gt;/example-app-tab-1/&quot;</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">DeviceDetailAppTabOne</span><span class="o">.</span><span class="n">as_view</span><span class="p">(),</span> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;device_detail_tab_1&quot;</span><span class="p">),</span>
8779
- <a id="__codelineno-3-9" name="__codelineno-3-9" href="#__codelineno-3-9"></a><span class="p">]</span>
9394
+ <div class="highlight"><span class="filename">example_app/urls.py</span><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a><span class="kn">from</span> <span class="nn">django.urls</span> <span class="kn">import</span> <span class="n">path</span>
9395
+ <a id="__codelineno-5-2" name="__codelineno-5-2" href="#__codelineno-5-2"></a>
9396
+ <a id="__codelineno-5-3" name="__codelineno-5-3" href="#__codelineno-5-3"></a><span class="kn">from</span> <span class="nn">example_app</span> <span class="kn">import</span> <span class="n">views</span>
9397
+ <a id="__codelineno-5-4" name="__codelineno-5-4" href="#__codelineno-5-4"></a>
9398
+ <a id="__codelineno-5-5" name="__codelineno-5-5" href="#__codelineno-5-5"></a><span class="n">urlpatterns</span> <span class="o">=</span> <span class="p">[</span>
9399
+ <a id="__codelineno-5-6" name="__codelineno-5-6" href="#__codelineno-5-6"></a> <span class="c1"># ... previously defined urls</span>
9400
+ <a id="__codelineno-5-7" name="__codelineno-5-7" href="#__codelineno-5-7"></a> <span class="n">path</span><span class="p">(</span><span class="s2">&quot;devices/&lt;uuid:pk&gt;/example-app-tab-1/&quot;</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">DeviceDetailAppTabOne</span><span class="o">.</span><span class="n">as_view</span><span class="p">(),</span> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;device_detail_tab_1&quot;</span><span class="p">),</span>
9401
+ <a id="__codelineno-5-8" name="__codelineno-5-8" href="#__codelineno-5-8"></a><span class="p">]</span>
8780
9402
  </code></pre></div>
8781
9403
  <div class="admonition note">
8782
9404
  <p class="admonition-title">Note</p>
8783
9405
  <p>For added tab views, we recommend for consistency that you follow the URL pattern established by the base model detail view and tabs (if any). For example, <code>nautobot/dcim/urls.py</code> references Device tab views with the URL pattern <code>devices/&lt;uuid:pk&gt;/TAB-NAME/</code>, so above we have followed that same pattern.</p>
8784
9406
  </div>
8785
- <h2 id="example-adding-object-details-and-tabs">Example Adding Object Details and Tabs<a class="headerlink" href="#example-adding-object-details-and-tabs" title="Permanent link">&para;</a></h2>
8786
- <div class="highlight"><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="c1"># template_content.py</span>
8787
- <a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a><span class="kn">from</span> <span class="nn">django.urls</span> <span class="kn">import</span> <span class="n">reverse</span>
8788
- <a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a><span class="kn">from</span> <span class="nn">nautobot.apps.ui</span> <span class="kn">import</span> <span class="n">TemplateExtension</span>
8789
- <a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a>
8790
- <a id="__codelineno-4-5" name="__codelineno-4-5" href="#__codelineno-4-5"></a><span class="kn">from</span> <span class="nn">.models</span> <span class="kn">import</span> <span class="n">Animal</span>
8791
- <a id="__codelineno-4-6" name="__codelineno-4-6" href="#__codelineno-4-6"></a>
8792
- <a id="__codelineno-4-7" name="__codelineno-4-7" href="#__codelineno-4-7"></a>
8793
- <a id="__codelineno-4-8" name="__codelineno-4-8" href="#__codelineno-4-8"></a><span class="k">class</span> <span class="nc">LocationAnimalCount</span><span class="p">(</span><span class="n">TemplateExtension</span><span class="p">):</span>
8794
- <a id="__codelineno-4-9" name="__codelineno-4-9" href="#__codelineno-4-9"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Template extension to display animal count on the right side of the page.&quot;&quot;&quot;</span>
8795
- <a id="__codelineno-4-10" name="__codelineno-4-10" href="#__codelineno-4-10"></a>
8796
- <a id="__codelineno-4-11" name="__codelineno-4-11" href="#__codelineno-4-11"></a> <span class="n">model</span> <span class="o">=</span> <span class="s1">&#39;dcim.location&#39;</span>
8797
- <a id="__codelineno-4-12" name="__codelineno-4-12" href="#__codelineno-4-12"></a>
8798
- <a id="__codelineno-4-13" name="__codelineno-4-13" href="#__codelineno-4-13"></a> <span class="k">def</span> <span class="nf">right_page</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
8799
- <a id="__codelineno-4-14" name="__codelineno-4-14" href="#__codelineno-4-14"></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="s1">&#39;nautobot_animal_sounds/inc/animal_count.html&#39;</span><span class="p">,</span> <span class="n">extra_context</span><span class="o">=</span><span class="p">{</span>
8800
- <a id="__codelineno-4-15" name="__codelineno-4-15" href="#__codelineno-4-15"></a> <span class="s1">&#39;animal_count&#39;</span><span class="p">:</span> <span class="n">Animal</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">count</span><span class="p">(),</span>
8801
- <a id="__codelineno-4-16" name="__codelineno-4-16" href="#__codelineno-4-16"></a> <span class="p">})</span>
8802
- <a id="__codelineno-4-17" name="__codelineno-4-17" href="#__codelineno-4-17"></a>
8803
- <a id="__codelineno-4-18" name="__codelineno-4-18" href="#__codelineno-4-18"></a>
8804
- <a id="__codelineno-4-19" name="__codelineno-4-19" href="#__codelineno-4-19"></a><span class="k">class</span> <span class="nc">DeviceExtraTabs</span><span class="p">(</span><span class="n">TemplateExtension</span><span class="p">):</span>
8805
- <a id="__codelineno-4-20" name="__codelineno-4-20" href="#__codelineno-4-20"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Template extension to add extra tabs to the object detail tabs.&quot;&quot;&quot;</span>
8806
- <a id="__codelineno-4-21" name="__codelineno-4-21" href="#__codelineno-4-21"></a>
8807
- <a id="__codelineno-4-22" name="__codelineno-4-22" href="#__codelineno-4-22"></a> <span class="n">model</span> <span class="o">=</span> <span class="s1">&#39;dcim.device&#39;</span>
8808
- <a id="__codelineno-4-23" name="__codelineno-4-23" href="#__codelineno-4-23"></a>
8809
- <a id="__codelineno-4-24" name="__codelineno-4-24" href="#__codelineno-4-24"></a> <span class="k">def</span> <span class="nf">detail_tabs</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
8810
- <a id="__codelineno-4-25" name="__codelineno-4-25" href="#__codelineno-4-25"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
8811
- <a id="__codelineno-4-26" name="__codelineno-4-26" href="#__codelineno-4-26"></a><span class="sd"> You may define extra tabs to render on a model&#39;s detail page by utilizing this method.</span>
8812
- <a id="__codelineno-4-27" name="__codelineno-4-27" href="#__codelineno-4-27"></a><span class="sd"> Each tab is defined as a dict in a list of dicts.</span>
8813
- <a id="__codelineno-4-28" name="__codelineno-4-28" href="#__codelineno-4-28"></a>
8814
- <a id="__codelineno-4-29" name="__codelineno-4-29" href="#__codelineno-4-29"></a><span class="sd"> For each of the tabs defined:</span>
8815
- <a id="__codelineno-4-30" name="__codelineno-4-30" href="#__codelineno-4-30"></a><span class="sd"> - The &lt;title&gt; key&#39;s value will become the tab link&#39;s title.</span>
8816
- <a id="__codelineno-4-31" name="__codelineno-4-31" href="#__codelineno-4-31"></a><span class="sd"> - The &lt;url&gt; key&#39;s value is used to render the HTML link for the tab</span>
8817
- <a id="__codelineno-4-32" name="__codelineno-4-32" href="#__codelineno-4-32"></a>
8818
- <a id="__codelineno-4-33" name="__codelineno-4-33" href="#__codelineno-4-33"></a><span class="sd"> These tabs will be visible (in this instance) on the Device model&#39;s detail page as</span>
8819
- <a id="__codelineno-4-34" name="__codelineno-4-34" href="#__codelineno-4-34"></a><span class="sd"> set by the DeviceContent.model attribute &quot;dcim.device&quot;</span>
8820
- <a id="__codelineno-4-35" name="__codelineno-4-35" href="#__codelineno-4-35"></a>
8821
- <a id="__codelineno-4-36" name="__codelineno-4-36" href="#__codelineno-4-36"></a><span class="sd"> This example demonstrates defining two tabs. The tabs will be ordered by their position in list.</span>
8822
- <a id="__codelineno-4-37" name="__codelineno-4-37" href="#__codelineno-4-37"></a><span class="sd"> &quot;&quot;&quot;</span>
8823
- <a id="__codelineno-4-38" name="__codelineno-4-38" href="#__codelineno-4-38"></a> <span class="k">return</span> <span class="p">[</span>
8824
- <a id="__codelineno-4-39" name="__codelineno-4-39" href="#__codelineno-4-39"></a> <span class="p">{</span>
8825
- <a id="__codelineno-4-40" name="__codelineno-4-40" href="#__codelineno-4-40"></a> <span class="s2">&quot;title&quot;</span><span class="p">:</span> <span class="s2">&quot;App Tab 1&quot;</span><span class="p">,</span>
8826
- <a id="__codelineno-4-41" name="__codelineno-4-41" href="#__codelineno-4-41"></a> <span class="s2">&quot;url&quot;</span><span class="p">:</span> <span class="n">reverse</span><span class="p">(</span><span class="s2">&quot;plugins:example_app:device_detail_tab_1&quot;</span><span class="p">,</span> <span class="n">kwargs</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;pk&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">context</span><span class="p">[</span><span class="s2">&quot;object&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">pk</span><span class="p">}),</span>
8827
- <a id="__codelineno-4-42" name="__codelineno-4-42" href="#__codelineno-4-42"></a> <span class="p">},</span>
8828
- <a id="__codelineno-4-43" name="__codelineno-4-43" href="#__codelineno-4-43"></a> <span class="p">{</span>
8829
- <a id="__codelineno-4-44" name="__codelineno-4-44" href="#__codelineno-4-44"></a> <span class="s2">&quot;title&quot;</span><span class="p">:</span> <span class="s2">&quot;App Tab 2&quot;</span><span class="p">,</span>
8830
- <a id="__codelineno-4-45" name="__codelineno-4-45" href="#__codelineno-4-45"></a> <span class="s2">&quot;url&quot;</span><span class="p">:</span> <span class="n">reverse</span><span class="p">(</span><span class="s2">&quot;plugins:example_app:device_detail_tab_2&quot;</span><span class="p">,</span> <span class="n">kwargs</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;pk&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">context</span><span class="p">[</span><span class="s2">&quot;object&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">pk</span><span class="p">}),</span>
8831
- <a id="__codelineno-4-46" name="__codelineno-4-46" href="#__codelineno-4-46"></a> <span class="p">},</span>
8832
- <a id="__codelineno-4-47" name="__codelineno-4-47" href="#__codelineno-4-47"></a> <span class="p">]</span>
8833
- <a id="__codelineno-4-48" name="__codelineno-4-48" href="#__codelineno-4-48"></a>
8834
- <a id="__codelineno-4-49" name="__codelineno-4-49" href="#__codelineno-4-49"></a><span class="n">template_extensions</span> <span class="o">=</span> <span class="p">[</span><span class="n">DeviceExtraTabs</span><span class="p">,</span> <span class="n">LocationAnimalCount</span><span class="p">]</span>
8835
- </code></pre></div>
8836
9407
 
8837
9408
 
8838
9409
 
@@ -8976,10 +9547,10 @@
8976
9547
  </div>
8977
9548
 
8978
9549
 
8979
- <script id="__config" type="application/json">{"base": "../../../..", "features": ["content.code.copy", "content.tabs.link", "navigation.footer", "navigation.tabs", "navigation.tabs.sticky", "navigation.tracking", "search.highlight", "search.share", "search.suggest"], "search": "../../../../assets/javascripts/workers/search.6ce7567c.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}}</script>
9550
+ <script id="__config" type="application/json">{"base": "../../../..", "features": ["content.code.annotate", "content.code.copy", "content.tabs.link", "navigation.footer", "navigation.tabs", "navigation.tabs.sticky", "navigation.tracking", "search.highlight", "search.share", "search.suggest"], "search": "../../../../assets/javascripts/workers/search.6ce7567c.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}}</script>
8980
9551
 
8981
9552
 
8982
- <script src="../../../../assets/javascripts/bundle.88dd0f4e.min.js"></script>
9553
+ <script src="../../../../assets/javascripts/bundle.83f73b43.min.js"></script>
8983
9554
 
8984
9555
  <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
8985
9556