nautobot 2.2.8__py3-none-any.whl → 2.3.0__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 (704) hide show
  1. nautobot/apps/forms.py +4 -0
  2. nautobot/apps/models.py +10 -1
  3. nautobot/circuits/__init__.py +0 -1
  4. nautobot/circuits/apps.py +1 -0
  5. nautobot/circuits/factory.py +15 -3
  6. nautobot/circuits/filters.py +13 -0
  7. nautobot/circuits/forms.py +13 -0
  8. nautobot/circuits/migrations/0021_alter_circuit_status_alter_circuittermination__path.py +32 -0
  9. nautobot/circuits/migrations/0022_circuittermination_cloud_network.py +25 -0
  10. nautobot/circuits/models.py +16 -3
  11. nautobot/circuits/tables.py +16 -2
  12. nautobot/circuits/templates/circuits/circuittermination_create.html +10 -2
  13. nautobot/circuits/templates/circuits/circuittermination_retrieve.html +6 -0
  14. nautobot/circuits/templates/circuits/inc/circuit_termination.html +6 -1
  15. nautobot/circuits/tests/test_api.py +7 -5
  16. nautobot/circuits/tests/test_filters.py +12 -5
  17. nautobot/circuits/tests/test_models.py +33 -2
  18. nautobot/circuits/views.py +2 -3
  19. nautobot/cloud/__init__.py +0 -0
  20. nautobot/cloud/api/__init__.py +0 -0
  21. nautobot/cloud/api/serializers.py +54 -0
  22. nautobot/cloud/api/urls.py +16 -0
  23. nautobot/cloud/api/views.py +48 -0
  24. nautobot/cloud/apps.py +13 -0
  25. nautobot/cloud/factory.py +113 -0
  26. nautobot/cloud/filters.py +187 -0
  27. nautobot/cloud/forms.py +339 -0
  28. nautobot/cloud/homepage.py +43 -0
  29. nautobot/cloud/migrations/0001_initial.py +304 -0
  30. nautobot/cloud/migrations/__init__.py +0 -0
  31. nautobot/cloud/models.py +246 -0
  32. nautobot/cloud/navigation.py +85 -0
  33. nautobot/cloud/tables.py +157 -0
  34. nautobot/cloud/templates/cloud/cloudaccount_retrieve.html +43 -0
  35. nautobot/cloud/templates/cloud/cloudnetwork_retrieve.html +122 -0
  36. nautobot/cloud/templates/cloud/cloudnetwork_update.html +33 -0
  37. nautobot/cloud/templates/cloud/cloudresourcetype_retrieve.html +111 -0
  38. nautobot/cloud/templates/cloud/cloudservice_retrieve.html +69 -0
  39. nautobot/cloud/templates/cloud/cloudservice_update.html +25 -0
  40. nautobot/cloud/tests/__init__.py +0 -0
  41. nautobot/cloud/tests/test_api.py +248 -0
  42. nautobot/cloud/tests/test_filters.py +125 -0
  43. nautobot/cloud/tests/test_models.py +43 -0
  44. nautobot/cloud/tests/test_views.py +153 -0
  45. nautobot/cloud/urls.py +14 -0
  46. nautobot/cloud/views.py +181 -0
  47. nautobot/core/__init__.py +0 -3
  48. nautobot/core/api/metadata.py +1 -0
  49. nautobot/core/api/parsers.py +7 -1
  50. nautobot/core/api/urls.py +1 -0
  51. nautobot/core/api/utils.py +1 -0
  52. nautobot/core/api/views.py +4 -0
  53. nautobot/core/apps/__init__.py +6 -3
  54. nautobot/core/constants.py +8 -0
  55. nautobot/core/factory.py +32 -1
  56. nautobot/core/filters.py +110 -14
  57. nautobot/core/forms/fields.py +10 -4
  58. nautobot/core/forms/forms.py +11 -3
  59. nautobot/core/forms/widgets.py +18 -1
  60. nautobot/core/graphql/generators.py +2 -2
  61. nautobot/core/graphql/schema.py +28 -7
  62. nautobot/core/jobs/__init__.py +20 -3
  63. nautobot/core/jobs/cleanup.py +100 -0
  64. nautobot/core/jobs/groups.py +38 -0
  65. nautobot/core/management/commands/generate_test_data.py +116 -3
  66. nautobot/core/models/__init__.py +34 -9
  67. nautobot/core/models/generics.py +19 -3
  68. nautobot/core/models/name_color_content_types.py +7 -28
  69. nautobot/core/models/querysets.py +4 -3
  70. nautobot/core/models/tree_queries.py +1 -1
  71. nautobot/core/models/utils.py +21 -5
  72. nautobot/core/settings.py +15 -19
  73. nautobot/core/settings.yaml +48 -13
  74. nautobot/core/settings_funcs.py +103 -0
  75. nautobot/core/tables.py +130 -56
  76. nautobot/core/templates/admin/search_form.html +1 -1
  77. nautobot/core/templates/buttons/add.html +11 -3
  78. nautobot/core/templates/buttons/consolidated_bulk_action_buttons.html +13 -0
  79. nautobot/core/templates/buttons/consolidated_detail_view_action_buttons.html +13 -0
  80. nautobot/core/templates/buttons/export.html +101 -53
  81. nautobot/core/templates/buttons/job_import.html +11 -3
  82. nautobot/core/templates/generic/object_bulk_destroy.html +3 -1
  83. nautobot/core/templates/generic/object_bulk_update.html +3 -1
  84. nautobot/core/templates/generic/object_changelog.html +0 -9
  85. nautobot/core/templates/generic/object_list.html +156 -17
  86. nautobot/core/templates/generic/object_retrieve.html +80 -16
  87. nautobot/core/templates/inc/extras_features_edit_form_fields.html +8 -0
  88. nautobot/core/templates/inc/javascript.html +2 -0
  89. nautobot/core/templates/inc/media.html +2 -2
  90. nautobot/core/templates/inc/nav_menu.html +1 -0
  91. nautobot/core/templates/inc/paginator.html +7 -7
  92. nautobot/core/templates/inc/search_panel.html +2 -2
  93. nautobot/core/templates/inc/table.html +2 -2
  94. nautobot/core/templates/nautobot_config.py.j2 +28 -8
  95. nautobot/core/templates/utilities/templatetags/dynamic_group_assignment_modal.html +37 -0
  96. nautobot/core/templates/utilities/templatetags/filter_form_modal.html +2 -2
  97. nautobot/core/templates/utilities/templatetags/saved_view_modal.html +38 -0
  98. nautobot/core/templates/utilities/theme_preview.html +25 -8
  99. nautobot/core/templates/utilities/worker_status.html +152 -0
  100. nautobot/core/templatetags/buttons.py +335 -38
  101. nautobot/core/templatetags/form_helpers.py +1 -1
  102. nautobot/core/templatetags/helpers.py +181 -11
  103. nautobot/core/testing/api.py +5 -4
  104. nautobot/core/testing/filters.py +63 -14
  105. nautobot/core/testing/mixins.py +46 -0
  106. nautobot/core/testing/models.py +22 -0
  107. nautobot/core/testing/schema.py +4 -8
  108. nautobot/core/testing/views.py +31 -14
  109. nautobot/core/tests/integration/test_general_functionality.py +1 -1
  110. nautobot/core/tests/integration/test_import_objects_ui.py +1 -0
  111. nautobot/core/tests/integration/test_swagger.py +1 -1
  112. nautobot/core/tests/nautobot_config.py +0 -1
  113. nautobot/core/tests/runner.py +2 -2
  114. nautobot/core/tests/test_api.py +1 -0
  115. nautobot/core/tests/test_authentication.py +7 -2
  116. nautobot/core/tests/test_filters.py +11 -9
  117. nautobot/core/tests/test_forms.py +9 -0
  118. nautobot/core/tests/test_graphql.py +27 -16
  119. nautobot/core/tests/test_jobs.py +204 -2
  120. nautobot/core/tests/test_tables.py +3 -1
  121. nautobot/core/tests/test_templatetags_helpers.py +12 -5
  122. nautobot/core/tests/test_templatetags_netutils.py +3 -3
  123. nautobot/core/tests/test_utils.py +31 -20
  124. nautobot/core/tests/test_views.py +6 -6
  125. nautobot/core/urls.py +8 -3
  126. nautobot/core/utils/deprecation.py +29 -0
  127. nautobot/core/utils/filtering.py +12 -9
  128. nautobot/core/utils/lookup.py +37 -2
  129. nautobot/core/utils/requests.py +4 -1
  130. nautobot/core/views/__init__.py +137 -24
  131. nautobot/core/views/generic.py +119 -67
  132. nautobot/core/views/mixins.py +105 -36
  133. nautobot/core/views/paginator.py +9 -3
  134. nautobot/core/views/renderers.py +121 -56
  135. nautobot/core/views/utils.py +81 -1
  136. nautobot/dcim/__init__.py +0 -1
  137. nautobot/dcim/api/serializers.py +180 -44
  138. nautobot/dcim/api/urls.py +7 -3
  139. nautobot/dcim/api/views.py +53 -7
  140. nautobot/dcim/apps.py +3 -0
  141. nautobot/dcim/choices.py +25 -0
  142. nautobot/dcim/constants.py +7 -0
  143. nautobot/dcim/factory.py +252 -18
  144. nautobot/dcim/filters/__init__.py +373 -193
  145. nautobot/dcim/filters/mixins.py +274 -1
  146. nautobot/dcim/forms.py +834 -121
  147. nautobot/dcim/graphql/types.py +2 -2
  148. nautobot/dcim/homepage.py +1 -1
  149. nautobot/dcim/migrations/0059_add_role_field_to_interface_models.py +27 -0
  150. nautobot/dcim/migrations/0060_alter_cable_status_alter_consoleport__path_and_more.py +303 -0
  151. nautobot/dcim/migrations/0061_module_models.py +862 -0
  152. nautobot/dcim/migrations/0062_module_data_migration.py +25 -0
  153. nautobot/dcim/models/__init__.py +8 -0
  154. nautobot/dcim/models/cables.py +15 -0
  155. nautobot/dcim/models/device_component_templates.py +207 -53
  156. nautobot/dcim/models/device_components.py +282 -99
  157. nautobot/dcim/models/devices.py +472 -13
  158. nautobot/dcim/models/racks.py +0 -1
  159. nautobot/dcim/navigation.py +47 -0
  160. nautobot/dcim/signals.py +3 -3
  161. nautobot/dcim/tables/__init__.py +35 -23
  162. nautobot/dcim/tables/devices.py +248 -47
  163. nautobot/dcim/tables/devicetypes.py +65 -9
  164. nautobot/dcim/tables/racks.py +5 -1
  165. nautobot/dcim/tables/template_code.py +46 -26
  166. nautobot/dcim/templates/dcim/cable_connect.html +76 -3
  167. nautobot/dcim/templates/dcim/console_port_connection_list.html +7 -5
  168. nautobot/dcim/templates/dcim/device/base.html +14 -6
  169. nautobot/dcim/templates/dcim/device/consoleports.html +2 -3
  170. nautobot/dcim/templates/dcim/device/consoleserverports.html +2 -3
  171. nautobot/dcim/templates/dcim/device/devicebays.html +6 -7
  172. nautobot/dcim/templates/dcim/device/frontports.html +2 -3
  173. nautobot/dcim/templates/dcim/device/interfaces.html +2 -3
  174. nautobot/dcim/templates/dcim/device/inventory.html +2 -3
  175. nautobot/dcim/templates/dcim/device/modulebays.html +49 -0
  176. nautobot/dcim/templates/dcim/device/poweroutlets.html +2 -3
  177. nautobot/dcim/templates/dcim/device/powerports.html +2 -3
  178. nautobot/dcim/templates/dcim/device/rearports.html +2 -3
  179. nautobot/dcim/templates/dcim/device.html +45 -1
  180. nautobot/dcim/templates/dcim/device_component.html +13 -5
  181. nautobot/dcim/templates/dcim/device_list.html +2 -1
  182. nautobot/dcim/templates/dcim/deviceredundancygroup_retrieve.html +6 -0
  183. nautobot/dcim/templates/dcim/devicetype.html +99 -98
  184. nautobot/dcim/templates/dcim/devicetype_list.html +8 -16
  185. nautobot/dcim/templates/dcim/inc/devicetype_component_table.html +1 -1
  186. nautobot/dcim/templates/dcim/inc/moduletype_component_table.html +39 -0
  187. nautobot/dcim/templates/dcim/interface.html +17 -2
  188. nautobot/dcim/templates/dcim/interface_connection_list.html +7 -5
  189. nautobot/dcim/templates/dcim/interface_edit.html +1 -0
  190. nautobot/dcim/templates/dcim/manufacturer.html +24 -0
  191. nautobot/dcim/templates/dcim/module/base.html +97 -0
  192. nautobot/dcim/templates/dcim/module_bulk_destroy.html +5 -0
  193. nautobot/dcim/templates/dcim/module_consoleports.html +53 -0
  194. nautobot/dcim/templates/dcim/module_consoleserverports.html +53 -0
  195. nautobot/dcim/templates/dcim/module_destroy.html +5 -0
  196. nautobot/dcim/templates/dcim/module_frontports.html +53 -0
  197. nautobot/dcim/templates/dcim/module_interfaces.html +57 -0
  198. nautobot/dcim/templates/dcim/module_list.html +20 -0
  199. nautobot/dcim/templates/dcim/module_modulebays.html +49 -0
  200. nautobot/dcim/templates/dcim/module_poweroutlets.html +53 -0
  201. nautobot/dcim/templates/dcim/module_powerports.html +53 -0
  202. nautobot/dcim/templates/dcim/module_rearports.html +53 -0
  203. nautobot/dcim/templates/dcim/module_retrieve.html +63 -0
  204. nautobot/dcim/templates/dcim/module_update.html +71 -0
  205. nautobot/dcim/templates/dcim/modulebay_bulk_destroy.html +5 -0
  206. nautobot/dcim/templates/dcim/modulebay_destroy.html +8 -0
  207. nautobot/dcim/templates/dcim/modulebay_retrieve.html +101 -0
  208. nautobot/dcim/templates/dcim/moduletype_list.html +11 -0
  209. nautobot/dcim/templates/dcim/moduletype_retrieve.html +159 -0
  210. nautobot/dcim/templates/dcim/power_port_connection_list.html +7 -5
  211. nautobot/dcim/templates/dcim/softwareimagefile_retrieve.html +65 -19
  212. nautobot/dcim/tests/integration/test_cable_connect_form.py +4 -4
  213. nautobot/dcim/tests/test_api.py +693 -208
  214. nautobot/dcim/tests/test_filters.py +843 -217
  215. nautobot/dcim/tests/test_models.py +1103 -8
  216. nautobot/dcim/tests/test_views.py +1525 -343
  217. nautobot/dcim/urls.py +17 -2
  218. nautobot/dcim/utils.py +2 -3
  219. nautobot/dcim/views.py +1109 -113
  220. nautobot/extras/__init__.py +0 -1
  221. nautobot/extras/api/serializers.py +115 -3
  222. nautobot/extras/api/urls.py +12 -0
  223. nautobot/extras/api/views.py +73 -59
  224. nautobot/extras/apps.py +2 -2
  225. nautobot/extras/choices.py +43 -0
  226. nautobot/extras/context_managers.py +13 -8
  227. nautobot/extras/datasources/git.py +2 -0
  228. nautobot/extras/factory.py +460 -9
  229. nautobot/extras/filters/__init__.py +174 -3
  230. nautobot/extras/filters/mixins.py +46 -43
  231. nautobot/extras/forms/base.py +24 -5
  232. nautobot/extras/forms/forms.py +227 -8
  233. nautobot/extras/forms/mixins.py +93 -0
  234. nautobot/extras/graphql/types.py +23 -10
  235. nautobot/extras/homepage.py +26 -3
  236. nautobot/extras/jobs.py +2 -2
  237. nautobot/extras/management/__init__.py +1 -0
  238. nautobot/extras/management/commands/refresh_dynamic_group_member_caches.py +1 -16
  239. nautobot/extras/migrations/0021_customfield_changelog_data.py +1 -0
  240. nautobot/extras/migrations/0109_dynamicgroup_group_type_dynamicgroup_tags_and_more.py +108 -0
  241. nautobot/extras/migrations/0110_alter_configcontext_cluster_groups_and_more.py +111 -0
  242. nautobot/extras/migrations/0111_metadata.py +162 -0
  243. nautobot/extras/migrations/0112_dynamic_group_group_type_data_migration.py +28 -0
  244. nautobot/extras/migrations/0113_saved_views.py +77 -0
  245. nautobot/extras/models/__init__.py +15 -1
  246. nautobot/extras/models/change_logging.py +3 -3
  247. nautobot/extras/models/contacts.py +4 -0
  248. nautobot/extras/models/customfields.py +18 -3
  249. nautobot/extras/models/groups.py +389 -225
  250. nautobot/extras/models/jobs.py +87 -3
  251. nautobot/extras/models/metadata.py +441 -0
  252. nautobot/extras/models/mixins.py +72 -62
  253. nautobot/extras/models/models.py +118 -9
  254. nautobot/extras/models/relationships.py +9 -2
  255. nautobot/extras/models/tags.py +13 -2
  256. nautobot/extras/navigation.py +57 -0
  257. nautobot/extras/plugins/__init__.py +3 -1
  258. nautobot/extras/querysets.py +30 -66
  259. nautobot/extras/signals.py +109 -101
  260. nautobot/extras/tables.py +201 -17
  261. nautobot/extras/templates/extras/dynamicgroup.html +44 -15
  262. nautobot/extras/templates/extras/dynamicgroup_edit.html +2 -0
  263. nautobot/extras/templates/extras/job.html +1 -1
  264. nautobot/extras/templates/extras/job_detail.html +11 -0
  265. nautobot/extras/templates/extras/jobresult.html +61 -74
  266. nautobot/extras/templates/extras/metadatatype_create.html +89 -0
  267. nautobot/extras/templates/extras/metadatatype_retrieve.html +67 -0
  268. nautobot/extras/templates/extras/object_dynamicgroups.html +7 -0
  269. nautobot/extras/templates/extras/objectchange_list.html +0 -12
  270. nautobot/extras/templates/extras/plugins_list.html +1 -3
  271. nautobot/extras/templates/extras/role_retrieve.html +48 -0
  272. nautobot/extras/templates/extras/staticgroupassociation_retrieve.html +20 -0
  273. nautobot/extras/tests/integration/test_customfields.py +1 -0
  274. nautobot/extras/tests/test_api.py +509 -23
  275. nautobot/extras/tests/test_changelog.py +20 -9
  276. nautobot/extras/tests/test_context_managers.py +22 -15
  277. nautobot/extras/tests/test_datasources.py +13 -1
  278. nautobot/extras/tests/test_dynamicgroups.py +201 -171
  279. nautobot/extras/tests/test_filters.py +211 -12
  280. nautobot/extras/tests/test_jobs.py +6 -6
  281. nautobot/extras/tests/test_models.py +501 -4
  282. nautobot/extras/tests/test_relationships.py +1 -0
  283. nautobot/extras/tests/test_views.py +586 -8
  284. nautobot/extras/tests/test_webhooks.py +1 -1
  285. nautobot/extras/urls.py +5 -0
  286. nautobot/extras/utils.py +85 -16
  287. nautobot/extras/views.py +562 -122
  288. nautobot/ipam/__init__.py +0 -1
  289. nautobot/ipam/apps.py +1 -0
  290. nautobot/ipam/factory.py +17 -19
  291. nautobot/ipam/filters.py +13 -0
  292. nautobot/ipam/forms.py +8 -4
  293. nautobot/ipam/graphql/types.py +2 -2
  294. nautobot/ipam/migrations/0047_alter_ipaddress_role_alter_ipaddress_status_and_more.py +59 -0
  295. nautobot/ipam/models.py +20 -20
  296. nautobot/ipam/querysets.py +1 -1
  297. nautobot/ipam/signals.py +4 -2
  298. nautobot/ipam/tables.py +5 -0
  299. nautobot/ipam/templates/ipam/ipaddress_interfaces.html +1 -1
  300. nautobot/ipam/templates/ipam/ipaddress_vm_interfaces.html +1 -1
  301. nautobot/ipam/templates/ipam/prefix.html +1 -0
  302. nautobot/ipam/tests/test_api.py +37 -18
  303. nautobot/ipam/tests/test_filters.py +26 -2
  304. nautobot/ipam/tests/test_models.py +9 -2
  305. nautobot/ipam/tests/test_querysets.py +1 -1
  306. nautobot/ipam/tests/test_views.py +3 -2
  307. nautobot/ipam/urls.py +2 -2
  308. nautobot/ipam/views.py +20 -34
  309. nautobot/project-static/css/base.css +21 -0
  310. nautobot/project-static/css/dark.css +11 -0
  311. nautobot/project-static/docs/404.html +894 -90
  312. nautobot/project-static/docs/apps/index.html +894 -90
  313. nautobot/project-static/docs/apps/nautobot-apps.html +894 -90
  314. nautobot/project-static/docs/assets/_mkdocstrings.css +5 -0
  315. nautobot/project-static/docs/assets/stylesheets/main.3cba04c6.min.css +1 -0
  316. nautobot/project-static/docs/assets/stylesheets/main.3cba04c6.min.css.map +1 -0
  317. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +921 -122
  318. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +906 -103
  319. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +1620 -905
  320. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +937 -146
  321. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +979 -190
  322. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +903 -101
  323. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +899 -95
  324. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +993 -195
  325. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +976 -133
  326. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +1080 -274
  327. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +1244 -336
  328. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +1729 -877
  329. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +1166 -383
  330. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +2090 -1376
  331. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +2248 -1424
  332. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +914 -113
  333. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +965 -165
  334. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +1012 -225
  335. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +1915 -1279
  336. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +1848 -1104
  337. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +906 -103
  338. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +2335 -1701
  339. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +1804 -1026
  340. nautobot/project-static/docs/development/apps/api/configuration-view.html +894 -90
  341. nautobot/project-static/docs/development/apps/api/database-backend-config.html +894 -90
  342. nautobot/project-static/docs/development/apps/api/models/django-admin.html +894 -90
  343. nautobot/project-static/docs/development/apps/api/models/global-search.html +894 -90
  344. nautobot/project-static/docs/development/apps/api/models/graphql.html +894 -90
  345. nautobot/project-static/docs/development/apps/api/models/index.html +944 -92
  346. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +894 -90
  347. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +894 -90
  348. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +894 -90
  349. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +894 -90
  350. nautobot/project-static/docs/development/apps/api/platform-features/index.html +894 -90
  351. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +894 -90
  352. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +894 -90
  353. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +894 -90
  354. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +894 -90
  355. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +894 -90
  356. nautobot/project-static/docs/development/apps/api/prometheus.html +894 -90
  357. nautobot/project-static/docs/development/apps/api/setup.html +894 -90
  358. nautobot/project-static/docs/development/apps/api/testing.html +894 -90
  359. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +894 -90
  360. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +894 -90
  361. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +894 -90
  362. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +894 -90
  363. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +894 -90
  364. nautobot/project-static/docs/development/apps/api/views/base-template.html +894 -90
  365. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +894 -90
  366. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +894 -90
  367. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +894 -90
  368. nautobot/project-static/docs/development/apps/api/views/index.html +894 -90
  369. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +894 -90
  370. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +894 -90
  371. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +894 -90
  372. nautobot/project-static/docs/development/apps/api/views/notes.html +894 -90
  373. nautobot/project-static/docs/development/apps/api/views/rest-api.html +894 -90
  374. nautobot/project-static/docs/development/apps/api/views/urls.html +894 -90
  375. nautobot/project-static/docs/development/apps/index.html +894 -90
  376. nautobot/project-static/docs/development/apps/migration/code-updates.html +894 -90
  377. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +894 -90
  378. nautobot/project-static/docs/development/apps/migration/from-v1.html +894 -90
  379. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +894 -90
  380. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +894 -90
  381. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +894 -90
  382. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +894 -90
  383. nautobot/project-static/docs/development/apps/porting-from-netbox.html +894 -90
  384. nautobot/project-static/docs/development/core/application-registry.html +894 -90
  385. nautobot/project-static/docs/development/core/best-practices.html +895 -90
  386. nautobot/project-static/docs/development/core/bootstrap-ui.html +894 -90
  387. nautobot/project-static/docs/development/core/caching.html +894 -90
  388. nautobot/project-static/docs/development/core/controllers.html +894 -90
  389. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +894 -90
  390. nautobot/project-static/docs/development/core/generic-views.html +894 -90
  391. nautobot/project-static/docs/development/core/getting-started.html +894 -90
  392. nautobot/project-static/docs/development/core/homepage.html +894 -90
  393. nautobot/project-static/docs/development/core/index.html +905 -90
  394. nautobot/project-static/docs/development/core/model-checklist.html +903 -91
  395. nautobot/project-static/docs/development/core/model-features.html +894 -90
  396. nautobot/project-static/docs/development/core/natural-keys.html +894 -90
  397. nautobot/project-static/docs/development/core/navigation-menu.html +894 -90
  398. nautobot/project-static/docs/development/core/release-checklist.html +897 -93
  399. nautobot/project-static/docs/development/core/role-internals.html +894 -90
  400. nautobot/project-static/docs/development/core/settings.html +894 -90
  401. nautobot/project-static/docs/development/core/style-guide.html +895 -91
  402. nautobot/project-static/docs/development/core/templates.html +906 -91
  403. nautobot/project-static/docs/development/core/testing.html +894 -90
  404. nautobot/project-static/docs/development/core/user-preferences.html +894 -90
  405. nautobot/project-static/docs/development/index.html +894 -90
  406. nautobot/project-static/docs/development/jobs/index.html +1271 -453
  407. nautobot/project-static/docs/development/jobs/migration/from-v1.html +894 -90
  408. nautobot/project-static/docs/index.html +9032 -13
  409. nautobot/project-static/docs/media/models/cloud_aws_direct_connect_dark.png +0 -0
  410. nautobot/project-static/docs/media/models/cloud_aws_direct_connect_light.png +0 -0
  411. nautobot/project-static/docs/models/cloud/cloudaccount.html +15 -0
  412. nautobot/project-static/docs/models/cloud/cloudnetwork.html +15 -0
  413. nautobot/project-static/docs/models/cloud/cloudnetworkprefixassignment.html +15 -0
  414. nautobot/project-static/docs/models/cloud/cloudresourcetype.html +15 -0
  415. nautobot/project-static/docs/models/cloud/cloudservice.html +15 -0
  416. nautobot/project-static/docs/models/cloud/cloudservicenetworkassignment.html +15 -0
  417. nautobot/project-static/docs/models/dcim/module.html +15 -0
  418. nautobot/project-static/docs/models/dcim/modulebay.html +15 -0
  419. nautobot/project-static/docs/models/dcim/modulebaytemplate.html +15 -0
  420. nautobot/project-static/docs/models/dcim/moduletype.html +15 -0
  421. nautobot/project-static/docs/models/extras/metadatachoice.html +15 -0
  422. nautobot/project-static/docs/models/extras/metadatatype.html +15 -0
  423. nautobot/project-static/docs/models/extras/objectmetadata.html +15 -0
  424. nautobot/project-static/docs/models/extras/role.html +15 -0
  425. nautobot/project-static/docs/models/extras/savedview.html +15 -0
  426. nautobot/project-static/docs/models/extras/staticgroupassociation.html +15 -0
  427. nautobot/project-static/docs/models/extras/status.html +15 -0
  428. nautobot/project-static/docs/objects.inv +0 -0
  429. nautobot/project-static/docs/overview/application_stack.html +902 -91
  430. nautobot/project-static/docs/overview/design_philosophy.html +896 -92
  431. nautobot/project-static/docs/overview/index.html +13 -8228
  432. nautobot/project-static/docs/release-notes/index.html +1131 -94
  433. nautobot/project-static/docs/release-notes/version-1.0.html +894 -90
  434. nautobot/project-static/docs/release-notes/version-1.1.html +894 -90
  435. nautobot/project-static/docs/release-notes/version-1.2.html +894 -90
  436. nautobot/project-static/docs/release-notes/version-1.3.html +894 -90
  437. nautobot/project-static/docs/release-notes/version-1.4.html +894 -90
  438. nautobot/project-static/docs/release-notes/version-1.5.html +895 -91
  439. nautobot/project-static/docs/release-notes/version-1.6.html +895 -91
  440. nautobot/project-static/docs/release-notes/version-2.0.html +894 -90
  441. nautobot/project-static/docs/release-notes/version-2.1.html +894 -90
  442. nautobot/project-static/docs/release-notes/version-2.2.html +1137 -196
  443. nautobot/project-static/docs/release-notes/version-2.3.html +9954 -0
  444. nautobot/project-static/docs/requirements.txt +5 -5
  445. nautobot/project-static/docs/search/search_index.json +1 -1
  446. nautobot/project-static/docs/sitemap.xml +335 -260
  447. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  448. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +894 -90
  449. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +894 -90
  450. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +894 -90
  451. nautobot/project-static/docs/user-guide/administration/configuration/index.html +894 -90
  452. nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +1025 -175
  453. nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +894 -90
  454. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +894 -90
  455. nautobot/project-static/docs/user-guide/administration/guides/caching.html +894 -90
  456. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +902 -90
  457. nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +894 -90
  458. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +894 -90
  459. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +894 -90
  460. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +894 -90
  461. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +894 -90
  462. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +894 -90
  463. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +894 -90
  464. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +894 -90
  465. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +946 -155
  466. nautobot/project-static/docs/user-guide/administration/installation/index.html +903 -95
  467. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +936 -124
  468. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +956 -159
  469. nautobot/project-static/docs/user-guide/administration/installation/services.html +915 -114
  470. nautobot/project-static/docs/user-guide/administration/installation-extras/docker.html +910 -101
  471. nautobot/project-static/docs/user-guide/administration/installation-extras/health-checks.html +894 -90
  472. nautobot/project-static/docs/user-guide/administration/installation-extras/selinux-troubleshooting.html +894 -90
  473. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +894 -90
  474. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +894 -90
  475. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +977 -121
  476. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +894 -90
  477. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +894 -90
  478. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +894 -90
  479. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +894 -90
  480. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +894 -90
  481. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +894 -90
  482. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +894 -90
  483. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +894 -90
  484. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +894 -90
  485. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +894 -90
  486. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +894 -90
  487. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +895 -91
  488. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +894 -90
  489. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +898 -90
  490. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +897 -93
  491. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +8984 -0
  492. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +8828 -0
  493. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +8829 -0
  494. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +8828 -0
  495. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +8829 -0
  496. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +8833 -0
  497. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +8828 -0
  498. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +908 -104
  499. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +925 -107
  500. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +925 -107
  501. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +920 -102
  502. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +925 -107
  503. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +908 -104
  504. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +908 -104
  505. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +915 -107
  506. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +922 -118
  507. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +923 -119
  508. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +920 -116
  509. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +908 -104
  510. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +916 -107
  511. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +928 -110
  512. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +938 -120
  513. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +930 -108
  514. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +908 -104
  515. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +939 -121
  516. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +930 -112
  517. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +920 -116
  518. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +923 -119
  519. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +925 -117
  520. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +8828 -0
  521. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +8846 -0
  522. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +8843 -0
  523. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +8823 -0
  524. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +918 -114
  525. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +908 -104
  526. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +942 -85
  527. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +926 -108
  528. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +908 -104
  529. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +945 -88
  530. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +923 -105
  531. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +931 -127
  532. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +920 -116
  533. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +908 -104
  534. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +924 -106
  535. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +926 -108
  536. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +908 -104
  537. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +908 -104
  538. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +908 -104
  539. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +938 -90
  540. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +894 -90
  541. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +899 -91
  542. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +899 -91
  543. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +894 -90
  544. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +894 -90
  545. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +894 -90
  546. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +894 -90
  547. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +894 -90
  548. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +894 -90
  549. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +894 -90
  550. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +894 -90
  551. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +894 -90
  552. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +894 -90
  553. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +903 -98
  554. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +894 -90
  555. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +894 -90
  556. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +894 -90
  557. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +894 -90
  558. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +894 -90
  559. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +899 -91
  560. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +894 -90
  561. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +894 -90
  562. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +894 -90
  563. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +894 -90
  564. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +894 -90
  565. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +894 -90
  566. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +894 -90
  567. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +894 -90
  568. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +894 -90
  569. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +894 -90
  570. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +894 -90
  571. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +894 -90
  572. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +894 -90
  573. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/clear-view-button.png +0 -0
  574. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/cleared-view.png +0 -0
  575. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/config-table-columns-to-locations.png +0 -0
  576. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/configure-button.png +0 -0
  577. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/create-saved-view-success.png +0 -0
  578. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/current-saved-view-drop-down-menu.png +0 -0
  579. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/default-location-list-view.png +0 -0
  580. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/dropdown-button-after-new-saved-view.png +0 -0
  581. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/filter-application-to-locations.png +0 -0
  582. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/filter-button.png +0 -0
  583. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/global-default-location-list-view.png +0 -0
  584. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/location-list-view-with-saved-views.png +0 -0
  585. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/navigation-menu.png +0 -0
  586. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/save-as-new-view-drop-down.png +0 -0
  587. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/save-view-modal.png +0 -0
  588. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-admin-edit-buttons.png +0 -0
  589. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-admin-edit-success.png +0 -0
  590. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-admin-edit-view-unchecked.png +0 -0
  591. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-admin-edit-view.png +0 -0
  592. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-different-user.png +0 -0
  593. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-modal-unchecked.png +0 -0
  594. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/set-as-my-default-button.png +0 -0
  595. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/set-as-my-default-success.png +0 -0
  596. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/unsaved-saved-view.png +0 -0
  597. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/updated-saved-view.png +0 -0
  598. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +894 -90
  599. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +894 -90
  600. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +894 -90
  601. nautobot/project-static/docs/user-guide/index.html +894 -90
  602. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +894 -90
  603. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +894 -90
  604. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +894 -90
  605. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +894 -90
  606. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +1260 -787
  607. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +897 -93
  608. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +894 -90
  609. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +894 -90
  610. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +894 -90
  611. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +894 -90
  612. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +894 -90
  613. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +894 -90
  614. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +894 -90
  615. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +894 -90
  616. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +894 -90
  617. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +898 -90
  618. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +894 -90
  619. nautobot/project-static/docs/user-guide/platform-functionality/note.html +897 -93
  620. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +9061 -0
  621. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +897 -93
  622. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +894 -90
  623. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +894 -90
  624. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +894 -90
  625. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +894 -90
  626. nautobot/project-static/docs/user-guide/platform-functionality/role.html +897 -93
  627. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +9137 -0
  628. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +897 -93
  629. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +8933 -0
  630. nautobot/project-static/docs/user-guide/platform-functionality/status.html +894 -90
  631. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +894 -90
  632. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +952 -123
  633. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +894 -90
  634. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +894 -90
  635. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +894 -90
  636. nautobot/project-static/js/forms.js +71 -0
  637. nautobot/project-static/js/table_sorting_indicator.js +46 -0
  638. nautobot/project-static/js/tableconfig.js +6 -1
  639. nautobot/project-static/materialdesignicons-7.4.47/css/materialdesignicons.min.css +3 -0
  640. nautobot/project-static/{materialdesignicons-6.5.95 → materialdesignicons-7.4.47}/fonts/materialdesignicons-webfont.eot +0 -0
  641. nautobot/project-static/{materialdesignicons-6.5.95 → materialdesignicons-7.4.47}/fonts/materialdesignicons-webfont.ttf +0 -0
  642. nautobot/project-static/materialdesignicons-7.4.47/fonts/materialdesignicons-webfont.woff +0 -0
  643. nautobot/project-static/materialdesignicons-7.4.47/fonts/materialdesignicons-webfont.woff2 +0 -0
  644. nautobot/tenancy/__init__.py +0 -1
  645. nautobot/tenancy/apps.py +1 -0
  646. nautobot/tenancy/factory.py +3 -2
  647. nautobot/tenancy/filters/__init__.py +1 -0
  648. nautobot/tenancy/forms.py +1 -1
  649. nautobot/tenancy/templates/tenancy/tenant.html +24 -20
  650. nautobot/tenancy/views.py +11 -10
  651. nautobot/users/__init__.py +0 -1
  652. nautobot/users/api/serializers.py +1 -1
  653. nautobot/users/api/views.py +4 -2
  654. nautobot/users/apps.py +3 -2
  655. nautobot/users/factory.py +3 -3
  656. nautobot/users/migrations/0010_user_default_saved_views.py +20 -0
  657. nautobot/users/models.py +12 -0
  658. nautobot/users/tests/test_filters.py +6 -3
  659. nautobot/users/urls.py +8 -0
  660. nautobot/virtualization/__init__.py +0 -1
  661. nautobot/virtualization/apps.py +1 -0
  662. nautobot/virtualization/filters.py +6 -1
  663. nautobot/virtualization/forms.py +11 -3
  664. nautobot/virtualization/graphql/types.py +2 -2
  665. nautobot/virtualization/migrations/0029_add_role_field_to_interface_models.py +27 -0
  666. nautobot/virtualization/migrations/0030_alter_virtualmachine_local_config_context_data_owner_content_type_and_more.py +67 -0
  667. nautobot/virtualization/models.py +0 -2
  668. nautobot/virtualization/tables.py +12 -8
  669. nautobot/virtualization/templates/virtualization/virtualmachine.html +1 -1
  670. nautobot/virtualization/templates/virtualization/vminterface.html +7 -1
  671. nautobot/virtualization/templates/virtualization/vminterface_edit.html +1 -0
  672. nautobot/virtualization/tests/test_api.py +9 -4
  673. nautobot/virtualization/tests/test_filters.py +22 -0
  674. nautobot/virtualization/tests/test_models.py +7 -3
  675. nautobot/virtualization/tests/test_views.py +19 -3
  676. nautobot/virtualization/urls.py +2 -2
  677. nautobot/virtualization/views.py +10 -32
  678. {nautobot-2.2.8.dist-info → nautobot-2.3.0.dist-info}/METADATA +21 -19
  679. {nautobot-2.2.8.dist-info → nautobot-2.3.0.dist-info}/RECORD +684 -564
  680. nautobot/project-static/docs/assets/stylesheets/main.76a95c52.min.css +0 -1
  681. nautobot/project-static/docs/assets/stylesheets/main.76a95c52.min.css.map +0 -1
  682. nautobot/project-static/materialdesignicons-6.5.95/.github/ISSUE_TEMPLATE.md +0 -3
  683. nautobot/project-static/materialdesignicons-6.5.95/README.md +0 -25
  684. nautobot/project-static/materialdesignicons-6.5.95/css/materialdesignicons.css +0 -26654
  685. nautobot/project-static/materialdesignicons-6.5.95/css/materialdesignicons.css.map +0 -16
  686. nautobot/project-static/materialdesignicons-6.5.95/css/materialdesignicons.min.css +0 -3
  687. nautobot/project-static/materialdesignicons-6.5.95/css/materialdesignicons.min.css.map +0 -16
  688. nautobot/project-static/materialdesignicons-6.5.95/fonts/materialdesignicons-webfont.woff +0 -0
  689. nautobot/project-static/materialdesignicons-6.5.95/fonts/materialdesignicons-webfont.woff2 +0 -0
  690. nautobot/project-static/materialdesignicons-6.5.95/package.json +0 -28
  691. nautobot/project-static/materialdesignicons-6.5.95/preview.html +0 -717
  692. nautobot/project-static/materialdesignicons-6.5.95/scss/_animated.scss +0 -27
  693. nautobot/project-static/materialdesignicons-6.5.95/scss/_core.scss +0 -10
  694. nautobot/project-static/materialdesignicons-6.5.95/scss/_extras.scss +0 -65
  695. nautobot/project-static/materialdesignicons-6.5.95/scss/_functions.scss +0 -20
  696. nautobot/project-static/materialdesignicons-6.5.95/scss/_icons.scss +0 -10
  697. nautobot/project-static/materialdesignicons-6.5.95/scss/_path.scss +0 -10
  698. nautobot/project-static/materialdesignicons-6.5.95/scss/_variables.scss +0 -6606
  699. nautobot/project-static/materialdesignicons-6.5.95/scss/materialdesignicons.scss +0 -8
  700. /nautobot/project-static/{materialdesignicons-6.5.95 → materialdesignicons-7.4.47}/LICENSE +0 -0
  701. {nautobot-2.2.8.dist-info → nautobot-2.3.0.dist-info}/LICENSE.txt +0 -0
  702. {nautobot-2.2.8.dist-info → nautobot-2.3.0.dist-info}/NOTICE +0 -0
  703. {nautobot-2.2.8.dist-info → nautobot-2.3.0.dist-info}/WHEEL +0 -0
  704. {nautobot-2.2.8.dist-info → nautobot-2.3.0.dist-info}/entry_points.txt +0 -0
@@ -2,8 +2,10 @@
2
2
 
3
3
  from collections import namedtuple
4
4
  import os
5
+ import sys
5
6
 
6
7
  from django.conf import settings
8
+ import structlog
7
9
 
8
10
  ConstanceConfigItem = namedtuple("ConstanceConfigItem", ["default", "help_text", "field_type"], defaults=[str])
9
11
 
@@ -82,3 +84,104 @@ def parse_redis_connection(redis_database):
82
84
  return f"{redis_scheme}://{redis_creds}{redis_host}?db={redis_database}"
83
85
  else:
84
86
  return f"{redis_scheme}://{redis_creds}{redis_host}:{redis_port}/{redis_database}"
87
+
88
+
89
+ def setup_structlog_logging(
90
+ django_logging: dict,
91
+ django_apps: list,
92
+ django_middleware: list,
93
+ log_level="INFO",
94
+ root_level="INFO",
95
+ debug_db=False,
96
+ plain_format=False,
97
+ ) -> None:
98
+ """Set up structlog logging for Nautobot.
99
+
100
+ This function disables logging if running tests, otherwise:
101
+
102
+ * Overwrites all `formatters` and `handlers` to avoid logging duplication.
103
+ It's possible to add custom `formatters` and `handlers` after calling this function.
104
+ * Updates all `loggers` to use structlog with the specified `log_level`.
105
+ * Adds or updates the root logger to use structlog with the specified `root_level`.
106
+ * Uses a human-readable structlog format if `plain_format` is True, otherwise uses JSON.
107
+ * Adds database query logging if `debug_db` is True.
108
+ * Adds necessary Django apps and middleware for structlog.
109
+ """
110
+ django_logging["version"] = 1
111
+ django_logging["disable_existing_loggers"] = True
112
+ if "test" in sys.argv:
113
+ django_logging["handlers"] = {
114
+ "null_handler": {
115
+ "level": "INFO",
116
+ "class": "logging.NullHandler",
117
+ },
118
+ }
119
+ for logger in django_logging["loggers"].values():
120
+ logger["handlers"] = ["null_handler"]
121
+ logger["level"] = "INFO"
122
+
123
+ return
124
+
125
+ django_apps.append("django_structlog")
126
+ django_middleware.append("django_structlog.middlewares.RequestMiddleware")
127
+
128
+ processors = (
129
+ # Add the log level to the event dict under the level key.
130
+ structlog.stdlib.add_log_level,
131
+ # Add the logger name to the event dict.
132
+ structlog.stdlib.add_logger_name,
133
+ # Apply stdlib-like string formatting to the event key.
134
+ structlog.stdlib.PositionalArgumentsFormatter(),
135
+ # A processor that merges in a global (context-local) context.
136
+ structlog.contextvars.merge_contextvars,
137
+ # Add a timestamp to event_dict in ISO 8601 format.
138
+ structlog.processors.TimeStamper(fmt="iso"),
139
+ # Replace an exc_info field with an exception string field using Python's built-in traceback formatting.
140
+ structlog.processors.format_exc_info,
141
+ # Add stack information with key stack if stack_info is True.
142
+ structlog.processors.StackInfoRenderer(),
143
+ # Decode byte string values in event_dict.
144
+ structlog.processors.UnicodeDecoder(),
145
+ )
146
+
147
+ django_logging["formatters"] = {
148
+ "default_formatter": {
149
+ "()": structlog.stdlib.ProcessorFormatter,
150
+ "foreign_pre_chain": processors,
151
+ "processor": structlog.dev.ConsoleRenderer() if plain_format else structlog.processors.JSONRenderer(),
152
+ },
153
+ }
154
+
155
+ django_logging["handlers"] = {
156
+ "default_handler": {
157
+ "level": "DEBUG",
158
+ "class": "logging.StreamHandler",
159
+ "formatter": "default_formatter",
160
+ },
161
+ }
162
+
163
+ django_logging["root"] = {
164
+ "handlers": ["default_handler"],
165
+ "level": root_level,
166
+ }
167
+
168
+ if debug_db:
169
+ django_logging["loggers"]["django.db.backends"] = {"level": "DEBUG"}
170
+
171
+ for logger in django_logging["loggers"].values():
172
+ if "level" not in logger:
173
+ logger["level"] = log_level
174
+ logger["propagate"] = False
175
+ logger["handlers"] = ["default_handler"]
176
+
177
+ structlog.configure(
178
+ processors=[
179
+ # Filter out log records below the configured log level.
180
+ structlog.stdlib.filter_by_level,
181
+ *processors,
182
+ # Must be the final processor in structlog's processor chain.
183
+ structlog.stdlib.ProcessorFormatter.wrap_for_formatter,
184
+ ],
185
+ logger_factory=structlog.stdlib.LoggerFactory(),
186
+ cache_logger_on_first_use=True,
187
+ )
nautobot/core/tables.py CHANGED
@@ -1,8 +1,9 @@
1
+ import contextlib
1
2
  import logging
2
3
 
3
4
  from django.contrib.auth.models import AnonymousUser
4
5
  from django.contrib.contenttypes.fields import GenericForeignKey
5
- from django.core.exceptions import FieldDoesNotExist
6
+ from django.core.exceptions import FieldDoesNotExist, FieldError
6
7
  from django.db import NotSupportedError
7
8
  from django.db.models.fields.related import ForeignKey, RelatedField
8
9
  from django.db.models.fields.reverse_related import ManyToOneRel
@@ -15,6 +16,7 @@ from django_tables2.data import TableQuerysetData
15
16
  from django_tables2.utils import Accessor, OrderBy, OrderByTuple
16
17
  from tree_queries.models import TreeNode
17
18
 
19
+ from nautobot.core.models.querysets import count_related
18
20
  from nautobot.core.templatetags import helpers
19
21
  from nautobot.core.utils import lookup
20
22
  from nautobot.extras import choices, models
@@ -34,10 +36,27 @@ class BaseTable(django_tables2.Table):
34
36
  "class": "table table-hover table-headings",
35
37
  }
36
38
 
37
- def __init__(self, *args, user=None, hide_hierarchy_ui=False, **kwargs):
39
+ def __init__(
40
+ self,
41
+ *args,
42
+ table_changes_pending=False,
43
+ saved_view=None,
44
+ user=None,
45
+ hide_hierarchy_ui=False,
46
+ order_by=None,
47
+ **kwargs,
48
+ ):
38
49
  # Add custom field columns
39
50
  model = self._meta.model
40
51
 
52
+ if model.is_dynamic_group_associable_model:
53
+ self.base_columns["dynamic_group_count"] = LinkedCountColumn(
54
+ viewname="extras:dynamicgroup_list",
55
+ url_params={"member_id": "pk"},
56
+ verbose_name="Dynamic Groups",
57
+ reverse_lookup="static_group_associations__associated_object_id",
58
+ )
59
+
41
60
  for cf in models.CustomField.objects.get_for_model(model):
42
61
  name = cf.add_prefix_to_cf_key()
43
62
  self.base_columns[name] = CustomFieldColumn(cf)
@@ -62,8 +81,16 @@ class BaseTable(django_tables2.Table):
62
81
  )
63
82
  # symmetric relationships are already handled above in the source_type case
64
83
 
84
+ if order_by is None and saved_view is not None:
85
+ order_by = saved_view.config.get("sort_order", None)
86
+
65
87
  # Init table
66
- super().__init__(*args, **kwargs)
88
+ super().__init__(*args, order_by=order_by, **kwargs)
89
+
90
+ # Don't show hierarchy if we're sorted
91
+ if order_by is not None and hide_hierarchy_ui is None:
92
+ hide_hierarchy_ui = True
93
+
67
94
  self.hide_hierarchy_ui = hide_hierarchy_ui
68
95
 
69
96
  # Set default empty_text if none was provided
@@ -79,65 +106,92 @@ class BaseTable(django_tables2.Table):
79
106
  # Hide the column if it is non-default *and* not manually specified as an extra column
80
107
  self.columns.hide(column.name)
81
108
 
82
- # Apply custom column ordering for user
83
- if user is not None and not isinstance(user, AnonymousUser):
84
- columns = user.get_config(f"tables.{self.__class__.__name__}.columns")
85
- if columns:
86
- pk = self.base_columns.pop("pk", None)
87
- actions = self.base_columns.pop("actions", None)
88
-
89
- for name, column in self.base_columns.items():
90
- if name in columns:
91
- self.columns.show(name)
92
- else:
93
- self.columns.hide(name)
94
- self.sequence = [c for c in columns if c in self.base_columns]
95
-
96
- # Always include PK and actions column, if defined on the table
97
- if pk:
98
- self.base_columns["pk"] = pk
99
- self.sequence.insert(0, "pk")
100
- if actions:
101
- self.base_columns["actions"] = actions
102
- self.sequence.append("actions")
109
+ # Apply custom column ordering for SavedView if it is available
110
+ # Takes precedence before user config
111
+ columns = []
112
+ pk = self.base_columns.pop("pk", None)
113
+ actions = self.base_columns.pop("actions", None)
114
+ if saved_view is not None and not table_changes_pending:
115
+ view_table_config = saved_view.config.get("table_config", {}).get(f"{self.__class__.__name__}", None)
116
+ if view_table_config is not None:
117
+ columns = view_table_config.get("columns", [])
118
+ else:
119
+ if user is not None and not isinstance(user, AnonymousUser):
120
+ columns = user.get_config(f"tables.{self.__class__.__name__}.columns")
121
+ if columns:
122
+ for name, column in self.base_columns.items():
123
+ if name in columns:
124
+ self.columns.show(name)
125
+ else:
126
+ self.columns.hide(name)
127
+ self.sequence = [c for c in columns if c in self.base_columns]
128
+
129
+ # Always include PK and actions columns, if defined on the table, as first and last columns respectively
130
+ if pk:
131
+ with contextlib.suppress(ValueError):
132
+ self.sequence.remove("pk")
133
+ self.base_columns["pk"] = pk
134
+ self.sequence.insert(0, "pk")
135
+ if actions:
136
+ with contextlib.suppress(ValueError):
137
+ self.sequence.remove("actions")
138
+ self.base_columns["actions"] = actions
139
+ self.sequence.append("actions")
103
140
 
104
141
  # Dynamically update the table's QuerySet to ensure related fields are pre-fetched
105
142
  if isinstance(self.data, TableQuerysetData):
106
143
  queryset = self.data.data
144
+
145
+ if hasattr(queryset, "with_tree_fields") and not self.hide_hierarchy_ui:
146
+ queryset = queryset.with_tree_fields()
147
+ elif hasattr(queryset, "without_tree_fields") and self.hide_hierarchy_ui:
148
+ queryset = queryset.without_tree_fields()
149
+
107
150
  select_fields = []
108
151
  prefetch_fields = []
152
+ count_fields = []
109
153
  for column in self.columns:
110
- if column.visible:
111
- column_model = model
112
- accessor = column.accessor
113
- select_path = []
114
- prefetch_path = []
115
- for field_name in accessor.split(accessor.SEPARATOR):
116
- try:
117
- field = column_model._meta.get_field(field_name)
118
- except FieldDoesNotExist:
119
- break
120
- if isinstance(field, ForeignKey) and not prefetch_path:
121
- # Follow ForeignKeys to the related model via select_related
122
- select_path.append(field_name)
123
- column_model = field.remote_field.model
124
- elif isinstance(field, (RelatedField, ManyToOneRel)) and not select_path:
125
- # Follow O2M and M2M relations to the related model via prefetch_related
126
- prefetch_path.append(field_name)
127
- column_model = field.remote_field.model
128
- elif isinstance(field, GenericForeignKey) and not select_path:
129
- # Can't prefetch beyond a GenericForeignKey
130
- prefetch_path.append(field_name)
131
- break
132
- else:
133
- # Need to stop processing once field is not a RelatedField or GFK
134
- # Ex: ["_custom_field_data", "tenant_id"] needs to exit
135
- # the loop as "tenant_id" would be misidentified as a RelatedField.
136
- break
137
- if select_path:
138
- select_fields.append("__".join(select_path))
139
- elif prefetch_path:
140
- prefetch_fields.append("__".join(prefetch_path))
154
+ if not column.visible:
155
+ continue
156
+ if isinstance(column.column, LinkedCountColumn):
157
+ column_model = lookup.get_model_for_view_name(column.column.viewname)
158
+ if column_model is None:
159
+ logger.error("Couldn't find model for %s", column.column.viewname)
160
+ continue
161
+ reverse_lookup = column.column.reverse_lookup or next(iter(column.column.url_params.keys()))
162
+ count_fields.append((column.name, column_model, reverse_lookup))
163
+ continue
164
+
165
+ column_model = model
166
+ accessor = column.accessor
167
+ select_path = []
168
+ prefetch_path = []
169
+ for field_name in accessor.split(accessor.SEPARATOR):
170
+ try:
171
+ field = column_model._meta.get_field(field_name)
172
+ except FieldDoesNotExist:
173
+ break
174
+ if isinstance(field, ForeignKey) and not prefetch_path:
175
+ # Follow ForeignKeys to the related model via select_related
176
+ select_path.append(field_name)
177
+ column_model = field.remote_field.model
178
+ elif isinstance(field, (RelatedField, ManyToOneRel)) and not select_path:
179
+ # Follow O2M and M2M relations to the related model via prefetch_related
180
+ prefetch_path.append(field_name)
181
+ column_model = field.remote_field.model
182
+ elif isinstance(field, GenericForeignKey) and not select_path:
183
+ # Can't prefetch beyond a GenericForeignKey
184
+ prefetch_path.append(field_name)
185
+ break
186
+ else:
187
+ # Need to stop processing once field is not a RelatedField or GFK
188
+ # Ex: ["_custom_field_data", "tenant_id"] needs to exit
189
+ # the loop as "tenant_id" would be misidentified as a RelatedField.
190
+ break
191
+ if select_path:
192
+ select_fields.append("__".join(select_path))
193
+ elif prefetch_path:
194
+ prefetch_fields.append("__".join(prefetch_path))
141
195
 
142
196
  if select_fields:
143
197
  # Django doesn't allow .select_related() on a QuerySet that had .values()/.values_list() applied, or
@@ -186,6 +240,23 @@ class BaseTable(django_tables2.Table):
186
240
  exc,
187
241
  )
188
242
 
243
+ if count_fields:
244
+ for column_name, column_model, lookup_name in count_fields:
245
+ if hasattr(queryset.first(), column_name):
246
+ continue
247
+ try:
248
+ logger.debug(
249
+ "Applying .annotate(%s=count_related(%s, %r) to %s QuerySet",
250
+ column_name,
251
+ column_model.__name__,
252
+ lookup_name,
253
+ model.__name__,
254
+ )
255
+ queryset = queryset.annotate(**{column_name: count_related(column_model, lookup_name)})
256
+ except FieldError:
257
+ # No error message logged here as the above is *very much* best-effort
258
+ pass
259
+
189
260
  self.data.data = queryset
190
261
 
191
262
  @property
@@ -396,12 +467,15 @@ class LinkedCountColumn(django_tables2.Column):
396
467
  :param viewname: The view name to use for URL resolution
397
468
  :param view_kwargs: Additional kwargs to pass for URL resolution (optional)
398
469
  :param url_params: A dict of query parameters to append to the URL (e.g. ?foo=bar) (optional)
470
+ :param reverse_lookup: The reverse lookup parameter to use to derive the count. If not specified, the first key
471
+ in `url_params` will be implicitly used as the `reverse_lookup` value.
399
472
  """
400
473
 
401
- def __init__(self, viewname, *args, view_kwargs=None, url_params=None, default=0, **kwargs):
474
+ def __init__(self, viewname, *args, view_kwargs=None, url_params=None, reverse_lookup=None, default=0, **kwargs):
402
475
  self.viewname = viewname
403
476
  self.view_kwargs = view_kwargs or {}
404
477
  self.url_params = url_params
478
+ self.reverse_lookup = reverse_lookup
405
479
  super().__init__(*args, default=default, **kwargs)
406
480
 
407
481
  def render(self, record, value): # pylint: disable=arguments-differ
@@ -11,7 +11,7 @@
11
11
  </span>
12
12
  </div>
13
13
  {% for pair in cl.params.items %}
14
- {% ifnotequal pair.0 search_var %}<input type="hidden" name="{{ pair.0 }}" value="{{ pair.1 }}"/>{% endifnotequal %}
14
+ {% if pair.0 != search_var %}<input type="hidden" name="{{ pair.0 }}" value="{{ pair.1 }}"/>{% endif %}
15
15
  {% endfor %}
16
16
  </form>
17
17
  <script type="text/javascript">document.getElementById("searchbar").focus();</script>
@@ -1,5 +1,13 @@
1
1
  {% if add_url %}
2
- <a href="{{ add_url }}" class="btn btn-primary" id="add-button">
3
- <span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add
4
- </a>
2
+ {% if list_element %}
3
+ <li>
4
+ <a href="{{ add_url }}" id="add-button">
5
+ <span class="mdi mdi-plus-thick text-muted" aria-hidden="true"></span> Add {{ verbose_name }}
6
+ </a>
7
+ </li>
8
+ {% else %}
9
+ <a href="{{ add_url }}" class="btn btn-primary" id="add-button">
10
+ <span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add {{ verbose_name }}
11
+ </a>
12
+ {% endif %}
5
13
  {% endif %}
@@ -0,0 +1,13 @@
1
+ {% if bulk_action_buttons|length > 1 %}
2
+ <div class="btn-group dropup">
3
+ {% for button in bulk_action_buttons %}
4
+ {{ button }}
5
+ {% if forloop.first %}
6
+ <ul class="dropdown-menu">
7
+ {% endif %}
8
+ {% endfor %}
9
+ </ul>
10
+ </div>
11
+ {% elif bulk_action_buttons|length == 1 %}
12
+ {{ bulk_action_buttons|first }}
13
+ {% endif %}
@@ -0,0 +1,13 @@
1
+ {% if detail_view_action_buttons|length > 1 %}
2
+ <div class="btn-group">
3
+ {% for button in detail_view_action_buttons %}
4
+ {{ button }}
5
+ {% if forloop.first %}
6
+ <ul class="dropdown-menu pull-right" role="menu">
7
+ {% endif %}
8
+ {% endfor %}
9
+ </ul>
10
+ </div>
11
+ {% elif detail_view_action_buttons|length == 1 %}
12
+ {{ detail_view_action_buttons|first }}
13
+ {% endif %}
@@ -1,69 +1,117 @@
1
1
  {% if export_url %}
2
- {% if export_templates or include_yaml_option %}
3
- <div class="btn-group">
4
- <button type="submit" class="btn btn-success" form="export_default">
5
- <span class="mdi mdi-database-export" aria-hidden="true"></span>
6
- Export
7
- </button>
8
- <form id="export_default" style="display: inline-block" action="{{ export_url }}" method="post">
2
+ {% if list_element %}
3
+ {% if export_templates %}
4
+ <li class="text-center">Export Templates</li>
5
+ {% endif %}
6
+ {% if include_yaml_option %}
7
+ <li>
8
+ <form action="{{ export_url }}" method="post">
9
+ {% csrf_token %}
10
+ <input type="hidden" name="content_type" value="{{ content_type.pk }}">
11
+ <input type="hidden" name="query_string" value="{{ query_string }}">
12
+ <input type="hidden" name="_schedule_type" value="immediately">
13
+ <input type="hidden" name="export_format" value="yaml">
14
+ <button type="submit">
15
+ <span class="mdi mdi-database-export text-muted" aria-hidden="true"></span> Export as YAML
16
+ </button>
17
+ </form>
18
+ </li>
19
+ {% endif %}
20
+ <li>
21
+ <form action="{{ export_url }}" method="post">
9
22
  {% csrf_token %}
10
23
  <input type="hidden" name="content_type" value="{{ content_type.pk }}">
11
24
  <input type="hidden" name="query_string" value="{{ query_string }}">
12
- <input type="hidden" name="export_format"
13
- value="{% if include_yaml_option %}yaml{% else %}csv{% endif %}">
14
25
  <input type="hidden" name="_schedule_type" value="immediately">
26
+ <input type="hidden" name="export_format" value="csv">
27
+ <button type="submit">
28
+ <span class="mdi mdi-database-export text-muted" aria-hidden="true"></span> Export as CSV
29
+ </button>
15
30
  </form>
16
- <button type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
17
- <span class="caret"></span>
18
- <span class="sr-only">Toggle Dropdown</span>
19
- </button>
20
- <ul class="dropdown-menu dropdown-menu-right">
21
- {% if include_yaml_option %}
22
- <li>
23
- <button type="submit" class="btn btn-link" form="export_default">YAML format</button>
24
- </li>
25
- <li>
26
- <form action="{{ export_url }}" method="post">
27
- {% csrf_token %}
28
- <input type="hidden" name="content_type" value="{{ content_type.pk }}">
29
- <input type="hidden" name="query_string" value="{{ query_string }}">
30
- <input type="hidden" name="_schedule_type" value="immediately">
31
- <button type="submit" class="btn btn-link">CSV format</button>
32
- </form>
33
- </li>
34
- {% else %}
35
- <li>
36
- <button type="submit" class="btn btn-link" form="export_default">CSV format</button>
37
- </li>
38
- {% endif %}
39
- {% if export_templates %}
40
- <li class="divider"></li>
41
- {% for et in export_templates %}
31
+ </li>
32
+ {% if export_templates %}
33
+ {% for et in export_templates %}
34
+ <li>
35
+ <form action="{{ export_url }}" method="post">
36
+ {% csrf_token %}
37
+ <input type="hidden" name="content_type" value="{{ content_type.pk }}">
38
+ <input type="hidden" name="export_template" value="{{ et.pk }}">
39
+ <input type="hidden" name="query_string" value="{{ query_string }}">
40
+ <input type="hidden" name="_schedule_type" value="immediately">
41
+ <button type="submit"
42
+ {% if et.description %}title="{{ et.description }}"{% endif %}
43
+ ><span class="mdi mdi-database-export text-muted" aria-hidden="true"></span> {{ et.name }}</button>
44
+ </form>
45
+ </li>
46
+ {% endfor %}
47
+ {% endif %}
48
+ {% else %}
49
+ {% if export_templates or include_yaml_option %}
50
+ <div class="btn-group">
51
+ <button type="submit" class="btn btn-success" form="export_default">
52
+ <span class="mdi mdi-database-export" aria-hidden="true"></span>
53
+ Export
54
+ </button>
55
+ <form id="export_default" style="display: inline-block" action="{{ export_url }}" method="post">
56
+ {% csrf_token %}
57
+ <input type="hidden" name="content_type" value="{{ content_type.pk }}">
58
+ <input type="hidden" name="query_string" value="{{ query_string }}">
59
+ <input type="hidden" name="export_format"
60
+ value="{% if include_yaml_option %}yaml{% else %}csv{% endif %}">
61
+ <input type="hidden" name="_schedule_type" value="immediately">
62
+ </form>
63
+ <button type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
64
+ <span class="caret"></span>
65
+ <span class="sr-only">Toggle Dropdown</span>
66
+ </button>
67
+ <ul class="dropdown-menu dropdown-menu-right">
68
+ {% if include_yaml_option %}
69
+ <li>
70
+ <button type="submit" class="btn btn-link" form="export_default">Export as YAML</button>
71
+ </li>
42
72
  <li>
43
73
  <form action="{{ export_url }}" method="post">
44
74
  {% csrf_token %}
45
75
  <input type="hidden" name="content_type" value="{{ content_type.pk }}">
46
- <input type="hidden" name="export_template" value="{{ et.pk }}">
47
76
  <input type="hidden" name="query_string" value="{{ query_string }}">
48
77
  <input type="hidden" name="_schedule_type" value="immediately">
49
- <button type="submit" class="btn btn-link"
50
- {% if et.description %}title="{{ et.description }}"{% endif %}
51
- >{{ et.name }}</button>
78
+ <button type="submit" class="btn btn-link">Export as CSV</button>
52
79
  </form>
53
80
  </li>
54
- {% endfor %}
55
- {% endif %}
56
- </ul>
57
- </div>
58
- {% else %}
59
- <form style="display: inline-block" action="{{ export_url }}" method="post">
60
- {% csrf_token %}
61
- <input type="hidden" name="content_type" value="{{ content_type.pk }}">
62
- <input type="hidden" name="query_string" value="{{ query_string }}">
63
- <input type="hidden" name="_schedule_type" value="immediately">
64
- <button type="submit" class="btn btn-success">
65
- <span class="mdi mdi-database-export" aria-hidden="true"></span> Export
66
- </button>
67
- </form>
81
+ {% else %}
82
+ <li>
83
+ <button type="submit" class="btn btn-link" form="export_default">CSV format</button>
84
+ </li>
85
+ {% endif %}
86
+ {% if export_templates %}
87
+ <li class="divider"></li>
88
+ {% for et in export_templates %}
89
+ <li>
90
+ <form action="{{ export_url }}" method="post">
91
+ {% csrf_token %}
92
+ <input type="hidden" name="content_type" value="{{ content_type.pk }}">
93
+ <input type="hidden" name="export_template" value="{{ et.pk }}">
94
+ <input type="hidden" name="query_string" value="{{ query_string }}">
95
+ <input type="hidden" name="_schedule_type" value="immediately">
96
+ <button type="submit" class="btn btn-link"
97
+ {% if et.description %}title="{{ et.description }}"{% endif %}
98
+ >{{ et.name }}</button>
99
+ </form>
100
+ </li>
101
+ {% endfor %}
102
+ {% endif %}
103
+ </ul>
104
+ </div>
105
+ {% else %}
106
+ <form style="display: inline-block" action="{{ export_url }}" method="post">
107
+ {% csrf_token %}
108
+ <input type="hidden" name="content_type" value="{{ content_type.pk }}">
109
+ <input type="hidden" name="query_string" value="{{ query_string }}">
110
+ <input type="hidden" name="_schedule_type" value="immediately">
111
+ <button type="submit" class="btn btn-success">
112
+ <span class="mdi mdi-database-export" aria-hidden="true"></span> Export
113
+ </button>
114
+ </form>
115
+ {% endif %}
68
116
  {% endif %}
69
117
  {% endif %}
@@ -1,5 +1,13 @@
1
1
  {% if import_url %}
2
- <a id="import-button" href="{{ import_url }}" class="btn btn-info">
3
- <span class="mdi mdi-database-import" aria-hidden="true"></span> Import
4
- </a>
2
+ {% if list_element %}
3
+ <li>
4
+ <a id="import-button" href="{{ import_url }}">
5
+ <span class="mdi mdi-database-import text-muted" aria-hidden="true"></span> Import from CSV
6
+ </a>
7
+ </li>
8
+ {% else %}
9
+ <a id="import-button" href="{{ import_url }}" class="btn btn-info">
10
+ <span class="mdi mdi-database-import" aria-hidden="true"></span> Import
11
+ </a>
12
+ {% endif %}
5
13
  {% endif %}
@@ -19,7 +19,9 @@
19
19
  <div class="row">
20
20
  <div class="col-md-8 col-md-offset-2">
21
21
  <div class="panel panel-default">
22
- {% render_table table 'inc/table.html' %}
22
+ <div class="table-responsive">
23
+ {% render_table table 'inc/table.html' %}
24
+ </div>
23
25
  </div>
24
26
  </div>
25
27
  </div>
@@ -29,7 +29,9 @@
29
29
  <div class="row">
30
30
  <div class="col-md-8">
31
31
  <div class="panel panel-default">
32
- {% render_table table 'inc/table.html' %}
32
+ <div class="table-responsive">
33
+ {% render_table table 'inc/table.html' %}
34
+ </div>
33
35
  </div>
34
36
  </div>
35
37
  <div class="col-md-4">