nautobot 2.2.9__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 (697) 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 +95 -13
  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/schema.py +26 -4
  61. nautobot/core/jobs/__init__.py +16 -2
  62. nautobot/core/jobs/cleanup.py +100 -0
  63. nautobot/core/jobs/groups.py +38 -0
  64. nautobot/core/management/commands/generate_test_data.py +116 -3
  65. nautobot/core/models/__init__.py +34 -9
  66. nautobot/core/models/generics.py +19 -3
  67. nautobot/core/models/name_color_content_types.py +7 -28
  68. nautobot/core/models/querysets.py +4 -3
  69. nautobot/core/models/tree_queries.py +1 -1
  70. nautobot/core/models/utils.py +21 -5
  71. nautobot/core/settings.py +2 -17
  72. nautobot/core/settings.yaml +34 -13
  73. nautobot/core/settings_funcs.py +103 -0
  74. nautobot/core/tables.py +130 -56
  75. nautobot/core/templates/admin/search_form.html +1 -1
  76. nautobot/core/templates/buttons/add.html +11 -3
  77. nautobot/core/templates/buttons/consolidated_bulk_action_buttons.html +13 -0
  78. nautobot/core/templates/buttons/consolidated_detail_view_action_buttons.html +13 -0
  79. nautobot/core/templates/buttons/export.html +101 -53
  80. nautobot/core/templates/buttons/job_import.html +11 -3
  81. nautobot/core/templates/generic/object_bulk_destroy.html +3 -1
  82. nautobot/core/templates/generic/object_bulk_update.html +3 -1
  83. nautobot/core/templates/generic/object_changelog.html +0 -9
  84. nautobot/core/templates/generic/object_list.html +156 -17
  85. nautobot/core/templates/generic/object_retrieve.html +80 -16
  86. nautobot/core/templates/inc/extras_features_edit_form_fields.html +8 -0
  87. nautobot/core/templates/inc/javascript.html +2 -0
  88. nautobot/core/templates/inc/media.html +2 -2
  89. nautobot/core/templates/inc/nav_menu.html +1 -0
  90. nautobot/core/templates/inc/paginator.html +7 -7
  91. nautobot/core/templates/inc/search_panel.html +2 -2
  92. nautobot/core/templates/inc/table.html +2 -2
  93. nautobot/core/templates/nautobot_config.py.j2 +13 -8
  94. nautobot/core/templates/utilities/templatetags/dynamic_group_assignment_modal.html +37 -0
  95. nautobot/core/templates/utilities/templatetags/filter_form_modal.html +2 -2
  96. nautobot/core/templates/utilities/templatetags/saved_view_modal.html +38 -0
  97. nautobot/core/templates/utilities/theme_preview.html +25 -8
  98. nautobot/core/templates/utilities/worker_status.html +152 -0
  99. nautobot/core/templatetags/buttons.py +335 -38
  100. nautobot/core/templatetags/form_helpers.py +1 -1
  101. nautobot/core/templatetags/helpers.py +181 -11
  102. nautobot/core/testing/api.py +5 -4
  103. nautobot/core/testing/filters.py +63 -14
  104. nautobot/core/testing/mixins.py +46 -0
  105. nautobot/core/testing/models.py +22 -0
  106. nautobot/core/testing/schema.py +4 -8
  107. nautobot/core/testing/views.py +31 -14
  108. nautobot/core/tests/integration/test_import_objects_ui.py +1 -0
  109. nautobot/core/tests/integration/test_swagger.py +1 -1
  110. nautobot/core/tests/nautobot_config.py +0 -1
  111. nautobot/core/tests/runner.py +2 -2
  112. nautobot/core/tests/test_api.py +1 -0
  113. nautobot/core/tests/test_authentication.py +7 -2
  114. nautobot/core/tests/test_filters.py +11 -9
  115. nautobot/core/tests/test_forms.py +9 -0
  116. nautobot/core/tests/test_graphql.py +27 -16
  117. nautobot/core/tests/test_jobs.py +122 -0
  118. nautobot/core/tests/test_tables.py +3 -1
  119. nautobot/core/tests/test_templatetags_helpers.py +12 -5
  120. nautobot/core/tests/test_utils.py +31 -20
  121. nautobot/core/tests/test_views.py +6 -6
  122. nautobot/core/urls.py +8 -3
  123. nautobot/core/utils/deprecation.py +29 -0
  124. nautobot/core/utils/filtering.py +12 -9
  125. nautobot/core/utils/lookup.py +37 -2
  126. nautobot/core/utils/requests.py +4 -1
  127. nautobot/core/views/__init__.py +137 -24
  128. nautobot/core/views/generic.py +119 -67
  129. nautobot/core/views/mixins.py +105 -36
  130. nautobot/core/views/paginator.py +9 -3
  131. nautobot/core/views/renderers.py +121 -56
  132. nautobot/core/views/utils.py +81 -1
  133. nautobot/dcim/__init__.py +0 -1
  134. nautobot/dcim/api/serializers.py +180 -44
  135. nautobot/dcim/api/urls.py +7 -3
  136. nautobot/dcim/api/views.py +53 -7
  137. nautobot/dcim/apps.py +3 -0
  138. nautobot/dcim/choices.py +25 -0
  139. nautobot/dcim/constants.py +7 -0
  140. nautobot/dcim/factory.py +252 -18
  141. nautobot/dcim/filters/__init__.py +373 -193
  142. nautobot/dcim/filters/mixins.py +274 -1
  143. nautobot/dcim/forms.py +834 -121
  144. nautobot/dcim/graphql/types.py +2 -2
  145. nautobot/dcim/homepage.py +1 -1
  146. nautobot/dcim/migrations/0059_add_role_field_to_interface_models.py +27 -0
  147. nautobot/dcim/migrations/0060_alter_cable_status_alter_consoleport__path_and_more.py +303 -0
  148. nautobot/dcim/migrations/0061_module_models.py +862 -0
  149. nautobot/dcim/migrations/0062_module_data_migration.py +25 -0
  150. nautobot/dcim/models/__init__.py +8 -0
  151. nautobot/dcim/models/cables.py +15 -0
  152. nautobot/dcim/models/device_component_templates.py +207 -53
  153. nautobot/dcim/models/device_components.py +275 -99
  154. nautobot/dcim/models/devices.py +468 -13
  155. nautobot/dcim/models/racks.py +0 -1
  156. nautobot/dcim/navigation.py +47 -0
  157. nautobot/dcim/signals.py +3 -3
  158. nautobot/dcim/tables/__init__.py +35 -23
  159. nautobot/dcim/tables/devices.py +229 -43
  160. nautobot/dcim/tables/devicetypes.py +65 -9
  161. nautobot/dcim/tables/racks.py +5 -1
  162. nautobot/dcim/tables/template_code.py +46 -26
  163. nautobot/dcim/templates/dcim/cable_connect.html +76 -3
  164. nautobot/dcim/templates/dcim/console_port_connection_list.html +7 -5
  165. nautobot/dcim/templates/dcim/device/base.html +14 -6
  166. nautobot/dcim/templates/dcim/device/consoleports.html +2 -3
  167. nautobot/dcim/templates/dcim/device/consoleserverports.html +2 -3
  168. nautobot/dcim/templates/dcim/device/devicebays.html +6 -7
  169. nautobot/dcim/templates/dcim/device/frontports.html +2 -3
  170. nautobot/dcim/templates/dcim/device/interfaces.html +2 -3
  171. nautobot/dcim/templates/dcim/device/inventory.html +2 -3
  172. nautobot/dcim/templates/dcim/device/modulebays.html +49 -0
  173. nautobot/dcim/templates/dcim/device/poweroutlets.html +2 -3
  174. nautobot/dcim/templates/dcim/device/powerports.html +2 -3
  175. nautobot/dcim/templates/dcim/device/rearports.html +2 -3
  176. nautobot/dcim/templates/dcim/device.html +45 -1
  177. nautobot/dcim/templates/dcim/device_component.html +13 -5
  178. nautobot/dcim/templates/dcim/device_list.html +2 -1
  179. nautobot/dcim/templates/dcim/devicetype.html +99 -98
  180. nautobot/dcim/templates/dcim/devicetype_list.html +8 -16
  181. nautobot/dcim/templates/dcim/inc/devicetype_component_table.html +1 -1
  182. nautobot/dcim/templates/dcim/inc/moduletype_component_table.html +39 -0
  183. nautobot/dcim/templates/dcim/interface.html +17 -2
  184. nautobot/dcim/templates/dcim/interface_connection_list.html +7 -5
  185. nautobot/dcim/templates/dcim/interface_edit.html +1 -0
  186. nautobot/dcim/templates/dcim/manufacturer.html +24 -0
  187. nautobot/dcim/templates/dcim/module/base.html +97 -0
  188. nautobot/dcim/templates/dcim/module_bulk_destroy.html +5 -0
  189. nautobot/dcim/templates/dcim/module_consoleports.html +53 -0
  190. nautobot/dcim/templates/dcim/module_consoleserverports.html +53 -0
  191. nautobot/dcim/templates/dcim/module_destroy.html +5 -0
  192. nautobot/dcim/templates/dcim/module_frontports.html +53 -0
  193. nautobot/dcim/templates/dcim/module_interfaces.html +57 -0
  194. nautobot/dcim/templates/dcim/module_list.html +20 -0
  195. nautobot/dcim/templates/dcim/module_modulebays.html +49 -0
  196. nautobot/dcim/templates/dcim/module_poweroutlets.html +53 -0
  197. nautobot/dcim/templates/dcim/module_powerports.html +53 -0
  198. nautobot/dcim/templates/dcim/module_rearports.html +53 -0
  199. nautobot/dcim/templates/dcim/module_retrieve.html +63 -0
  200. nautobot/dcim/templates/dcim/module_update.html +71 -0
  201. nautobot/dcim/templates/dcim/modulebay_bulk_destroy.html +5 -0
  202. nautobot/dcim/templates/dcim/modulebay_destroy.html +8 -0
  203. nautobot/dcim/templates/dcim/modulebay_retrieve.html +101 -0
  204. nautobot/dcim/templates/dcim/moduletype_list.html +11 -0
  205. nautobot/dcim/templates/dcim/moduletype_retrieve.html +159 -0
  206. nautobot/dcim/templates/dcim/power_port_connection_list.html +7 -5
  207. nautobot/dcim/templates/dcim/softwareimagefile_retrieve.html +65 -19
  208. nautobot/dcim/tests/integration/test_cable_connect_form.py +4 -4
  209. nautobot/dcim/tests/test_api.py +693 -208
  210. nautobot/dcim/tests/test_filters.py +843 -217
  211. nautobot/dcim/tests/test_models.py +1072 -8
  212. nautobot/dcim/tests/test_views.py +1510 -341
  213. nautobot/dcim/urls.py +17 -2
  214. nautobot/dcim/utils.py +2 -3
  215. nautobot/dcim/views.py +1106 -116
  216. nautobot/extras/__init__.py +0 -1
  217. nautobot/extras/api/serializers.py +115 -3
  218. nautobot/extras/api/urls.py +12 -0
  219. nautobot/extras/api/views.py +66 -0
  220. nautobot/extras/apps.py +2 -2
  221. nautobot/extras/choices.py +43 -0
  222. nautobot/extras/context_managers.py +13 -8
  223. nautobot/extras/datasources/git.py +2 -0
  224. nautobot/extras/factory.py +460 -9
  225. nautobot/extras/filters/__init__.py +174 -3
  226. nautobot/extras/filters/mixins.py +46 -43
  227. nautobot/extras/forms/base.py +24 -5
  228. nautobot/extras/forms/forms.py +227 -8
  229. nautobot/extras/forms/mixins.py +93 -0
  230. nautobot/extras/graphql/types.py +23 -10
  231. nautobot/extras/homepage.py +14 -1
  232. nautobot/extras/management/__init__.py +1 -0
  233. nautobot/extras/management/commands/refresh_dynamic_group_member_caches.py +1 -16
  234. nautobot/extras/migrations/0021_customfield_changelog_data.py +1 -0
  235. nautobot/extras/migrations/0109_dynamicgroup_group_type_dynamicgroup_tags_and_more.py +108 -0
  236. nautobot/extras/migrations/0110_alter_configcontext_cluster_groups_and_more.py +111 -0
  237. nautobot/extras/migrations/0111_metadata.py +162 -0
  238. nautobot/extras/migrations/0112_dynamic_group_group_type_data_migration.py +28 -0
  239. nautobot/extras/migrations/0113_saved_views.py +77 -0
  240. nautobot/extras/models/__init__.py +15 -1
  241. nautobot/extras/models/change_logging.py +3 -3
  242. nautobot/extras/models/contacts.py +4 -0
  243. nautobot/extras/models/customfields.py +18 -3
  244. nautobot/extras/models/groups.py +389 -225
  245. nautobot/extras/models/jobs.py +6 -3
  246. nautobot/extras/models/metadata.py +441 -0
  247. nautobot/extras/models/mixins.py +72 -62
  248. nautobot/extras/models/models.py +118 -9
  249. nautobot/extras/models/relationships.py +9 -2
  250. nautobot/extras/models/tags.py +13 -2
  251. nautobot/extras/navigation.py +57 -0
  252. nautobot/extras/plugins/__init__.py +3 -1
  253. nautobot/extras/querysets.py +30 -66
  254. nautobot/extras/signals.py +95 -100
  255. nautobot/extras/tables.py +165 -12
  256. nautobot/extras/templates/extras/dynamicgroup.html +44 -15
  257. nautobot/extras/templates/extras/dynamicgroup_edit.html +2 -0
  258. nautobot/extras/templates/extras/job.html +1 -1
  259. nautobot/extras/templates/extras/jobresult.html +61 -74
  260. nautobot/extras/templates/extras/metadatatype_create.html +89 -0
  261. nautobot/extras/templates/extras/metadatatype_retrieve.html +67 -0
  262. nautobot/extras/templates/extras/object_dynamicgroups.html +7 -0
  263. nautobot/extras/templates/extras/objectchange_list.html +0 -12
  264. nautobot/extras/templates/extras/plugins_list.html +1 -3
  265. nautobot/extras/templates/extras/role_retrieve.html +48 -0
  266. nautobot/extras/templates/extras/staticgroupassociation_retrieve.html +20 -0
  267. nautobot/extras/tests/integration/test_customfields.py +1 -0
  268. nautobot/extras/tests/test_api.py +509 -23
  269. nautobot/extras/tests/test_changelog.py +20 -9
  270. nautobot/extras/tests/test_context_managers.py +22 -15
  271. nautobot/extras/tests/test_datasources.py +13 -1
  272. nautobot/extras/tests/test_dynamicgroups.py +201 -171
  273. nautobot/extras/tests/test_filters.py +211 -12
  274. nautobot/extras/tests/test_jobs.py +6 -6
  275. nautobot/extras/tests/test_models.py +501 -4
  276. nautobot/extras/tests/test_relationships.py +1 -0
  277. nautobot/extras/tests/test_views.py +565 -8
  278. nautobot/extras/tests/test_webhooks.py +1 -1
  279. nautobot/extras/urls.py +5 -0
  280. nautobot/extras/utils.py +51 -11
  281. nautobot/extras/views.py +542 -76
  282. nautobot/ipam/__init__.py +0 -1
  283. nautobot/ipam/apps.py +1 -0
  284. nautobot/ipam/factory.py +17 -19
  285. nautobot/ipam/filters.py +13 -0
  286. nautobot/ipam/forms.py +8 -4
  287. nautobot/ipam/graphql/types.py +2 -2
  288. nautobot/ipam/migrations/0047_alter_ipaddress_role_alter_ipaddress_status_and_more.py +59 -0
  289. nautobot/ipam/models.py +11 -8
  290. nautobot/ipam/querysets.py +1 -1
  291. nautobot/ipam/signals.py +4 -2
  292. nautobot/ipam/tables.py +5 -0
  293. nautobot/ipam/templates/ipam/ipaddress_interfaces.html +1 -1
  294. nautobot/ipam/templates/ipam/ipaddress_vm_interfaces.html +1 -1
  295. nautobot/ipam/templates/ipam/prefix.html +1 -0
  296. nautobot/ipam/tests/test_api.py +37 -18
  297. nautobot/ipam/tests/test_filters.py +26 -2
  298. nautobot/ipam/tests/test_models.py +6 -0
  299. nautobot/ipam/tests/test_querysets.py +1 -1
  300. nautobot/ipam/tests/test_views.py +3 -2
  301. nautobot/ipam/urls.py +2 -2
  302. nautobot/ipam/views.py +18 -26
  303. nautobot/project-static/css/base.css +20 -0
  304. nautobot/project-static/css/dark.css +11 -0
  305. nautobot/project-static/docs/404.html +892 -88
  306. nautobot/project-static/docs/apps/index.html +892 -88
  307. nautobot/project-static/docs/apps/nautobot-apps.html +892 -88
  308. nautobot/project-static/docs/assets/_mkdocstrings.css +5 -0
  309. nautobot/project-static/docs/assets/stylesheets/main.3cba04c6.min.css +1 -0
  310. nautobot/project-static/docs/assets/stylesheets/main.3cba04c6.min.css.map +1 -0
  311. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +919 -120
  312. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +904 -101
  313. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +1618 -903
  314. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +935 -144
  315. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +977 -188
  316. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +901 -99
  317. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +897 -93
  318. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +991 -193
  319. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +974 -131
  320. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +1078 -272
  321. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +1242 -334
  322. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +1727 -875
  323. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +1164 -381
  324. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +2088 -1374
  325. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +2246 -1422
  326. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +912 -111
  327. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +963 -163
  328. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +1010 -223
  329. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +1913 -1277
  330. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +1846 -1102
  331. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +904 -101
  332. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +2331 -1699
  333. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +1802 -1024
  334. nautobot/project-static/docs/development/apps/api/configuration-view.html +892 -88
  335. nautobot/project-static/docs/development/apps/api/database-backend-config.html +892 -88
  336. nautobot/project-static/docs/development/apps/api/models/django-admin.html +892 -88
  337. nautobot/project-static/docs/development/apps/api/models/global-search.html +892 -88
  338. nautobot/project-static/docs/development/apps/api/models/graphql.html +892 -88
  339. nautobot/project-static/docs/development/apps/api/models/index.html +942 -90
  340. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +892 -88
  341. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +892 -88
  342. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +892 -88
  343. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +892 -88
  344. nautobot/project-static/docs/development/apps/api/platform-features/index.html +892 -88
  345. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +892 -88
  346. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +892 -88
  347. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +892 -88
  348. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +892 -88
  349. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +892 -88
  350. nautobot/project-static/docs/development/apps/api/prometheus.html +892 -88
  351. nautobot/project-static/docs/development/apps/api/setup.html +892 -88
  352. nautobot/project-static/docs/development/apps/api/testing.html +892 -88
  353. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +892 -88
  354. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +892 -88
  355. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +892 -88
  356. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +892 -88
  357. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +892 -88
  358. nautobot/project-static/docs/development/apps/api/views/base-template.html +892 -88
  359. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +892 -88
  360. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +892 -88
  361. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +892 -88
  362. nautobot/project-static/docs/development/apps/api/views/index.html +892 -88
  363. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +892 -88
  364. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +892 -88
  365. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +892 -88
  366. nautobot/project-static/docs/development/apps/api/views/notes.html +892 -88
  367. nautobot/project-static/docs/development/apps/api/views/rest-api.html +892 -88
  368. nautobot/project-static/docs/development/apps/api/views/urls.html +892 -88
  369. nautobot/project-static/docs/development/apps/index.html +892 -88
  370. nautobot/project-static/docs/development/apps/migration/code-updates.html +892 -88
  371. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +892 -88
  372. nautobot/project-static/docs/development/apps/migration/from-v1.html +892 -88
  373. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +892 -88
  374. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +892 -88
  375. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +892 -88
  376. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +892 -88
  377. nautobot/project-static/docs/development/apps/porting-from-netbox.html +892 -88
  378. nautobot/project-static/docs/development/core/application-registry.html +892 -88
  379. nautobot/project-static/docs/development/core/best-practices.html +893 -88
  380. nautobot/project-static/docs/development/core/bootstrap-ui.html +892 -88
  381. nautobot/project-static/docs/development/core/caching.html +892 -88
  382. nautobot/project-static/docs/development/core/controllers.html +892 -88
  383. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +892 -88
  384. nautobot/project-static/docs/development/core/generic-views.html +892 -88
  385. nautobot/project-static/docs/development/core/getting-started.html +892 -88
  386. nautobot/project-static/docs/development/core/homepage.html +892 -88
  387. nautobot/project-static/docs/development/core/index.html +892 -88
  388. nautobot/project-static/docs/development/core/model-checklist.html +901 -89
  389. nautobot/project-static/docs/development/core/model-features.html +892 -88
  390. nautobot/project-static/docs/development/core/natural-keys.html +892 -88
  391. nautobot/project-static/docs/development/core/navigation-menu.html +892 -88
  392. nautobot/project-static/docs/development/core/release-checklist.html +895 -91
  393. nautobot/project-static/docs/development/core/role-internals.html +892 -88
  394. nautobot/project-static/docs/development/core/settings.html +892 -88
  395. nautobot/project-static/docs/development/core/style-guide.html +893 -89
  396. nautobot/project-static/docs/development/core/templates.html +904 -89
  397. nautobot/project-static/docs/development/core/testing.html +892 -88
  398. nautobot/project-static/docs/development/core/user-preferences.html +892 -88
  399. nautobot/project-static/docs/development/index.html +892 -88
  400. nautobot/project-static/docs/development/jobs/index.html +893 -89
  401. nautobot/project-static/docs/development/jobs/migration/from-v1.html +892 -88
  402. nautobot/project-static/docs/index.html +892 -88
  403. nautobot/project-static/docs/media/models/cloud_aws_direct_connect_dark.png +0 -0
  404. nautobot/project-static/docs/media/models/cloud_aws_direct_connect_light.png +0 -0
  405. nautobot/project-static/docs/models/cloud/cloudaccount.html +15 -0
  406. nautobot/project-static/docs/models/cloud/cloudnetwork.html +15 -0
  407. nautobot/project-static/docs/models/cloud/cloudnetworkprefixassignment.html +15 -0
  408. nautobot/project-static/docs/models/cloud/cloudresourcetype.html +15 -0
  409. nautobot/project-static/docs/models/cloud/cloudservice.html +15 -0
  410. nautobot/project-static/docs/models/cloud/cloudservicenetworkassignment.html +15 -0
  411. nautobot/project-static/docs/models/dcim/module.html +15 -0
  412. nautobot/project-static/docs/models/dcim/modulebay.html +15 -0
  413. nautobot/project-static/docs/models/dcim/modulebaytemplate.html +15 -0
  414. nautobot/project-static/docs/models/dcim/moduletype.html +15 -0
  415. nautobot/project-static/docs/models/extras/metadatachoice.html +15 -0
  416. nautobot/project-static/docs/models/extras/metadatatype.html +15 -0
  417. nautobot/project-static/docs/models/extras/objectmetadata.html +15 -0
  418. nautobot/project-static/docs/models/extras/role.html +15 -0
  419. nautobot/project-static/docs/models/extras/savedview.html +15 -0
  420. nautobot/project-static/docs/models/extras/staticgroupassociation.html +15 -0
  421. nautobot/project-static/docs/models/extras/status.html +15 -0
  422. nautobot/project-static/docs/objects.inv +0 -0
  423. nautobot/project-static/docs/overview/application_stack.html +900 -89
  424. nautobot/project-static/docs/overview/design_philosophy.html +892 -88
  425. nautobot/project-static/docs/release-notes/index.html +1129 -92
  426. nautobot/project-static/docs/release-notes/version-1.0.html +892 -88
  427. nautobot/project-static/docs/release-notes/version-1.1.html +892 -88
  428. nautobot/project-static/docs/release-notes/version-1.2.html +892 -88
  429. nautobot/project-static/docs/release-notes/version-1.3.html +892 -88
  430. nautobot/project-static/docs/release-notes/version-1.4.html +892 -88
  431. nautobot/project-static/docs/release-notes/version-1.5.html +893 -89
  432. nautobot/project-static/docs/release-notes/version-1.6.html +893 -89
  433. nautobot/project-static/docs/release-notes/version-2.0.html +892 -88
  434. nautobot/project-static/docs/release-notes/version-2.1.html +892 -88
  435. nautobot/project-static/docs/release-notes/version-2.2.html +895 -91
  436. nautobot/project-static/docs/release-notes/version-2.3.html +9954 -0
  437. nautobot/project-static/docs/requirements.txt +5 -5
  438. nautobot/project-static/docs/search/search_index.json +1 -1
  439. nautobot/project-static/docs/sitemap.xml +331 -256
  440. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  441. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +892 -88
  442. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +892 -88
  443. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +892 -88
  444. nautobot/project-static/docs/user-guide/administration/configuration/index.html +892 -88
  445. nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +992 -174
  446. nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +892 -88
  447. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +892 -88
  448. nautobot/project-static/docs/user-guide/administration/guides/caching.html +892 -88
  449. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +896 -88
  450. nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +892 -88
  451. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +892 -88
  452. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +892 -88
  453. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +892 -88
  454. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +892 -88
  455. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +892 -88
  456. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +892 -88
  457. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +892 -88
  458. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +944 -153
  459. nautobot/project-static/docs/user-guide/administration/installation/index.html +901 -93
  460. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +934 -122
  461. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +954 -157
  462. nautobot/project-static/docs/user-guide/administration/installation/services.html +913 -112
  463. nautobot/project-static/docs/user-guide/administration/installation-extras/docker.html +908 -99
  464. nautobot/project-static/docs/user-guide/administration/installation-extras/health-checks.html +892 -88
  465. nautobot/project-static/docs/user-guide/administration/installation-extras/selinux-troubleshooting.html +892 -88
  466. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +892 -88
  467. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +892 -88
  468. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +893 -89
  469. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +892 -88
  470. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +892 -88
  471. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +892 -88
  472. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +892 -88
  473. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +892 -88
  474. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +892 -88
  475. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +892 -88
  476. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +892 -88
  477. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +892 -88
  478. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +892 -88
  479. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +892 -88
  480. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +893 -89
  481. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +892 -88
  482. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +896 -88
  483. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +895 -91
  484. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +8984 -0
  485. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +8828 -0
  486. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +8829 -0
  487. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +8828 -0
  488. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +8829 -0
  489. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +8833 -0
  490. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +8828 -0
  491. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +906 -102
  492. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +923 -105
  493. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +923 -105
  494. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +918 -100
  495. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +923 -105
  496. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +906 -102
  497. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +906 -102
  498. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +913 -105
  499. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +920 -116
  500. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +921 -117
  501. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +918 -114
  502. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +906 -102
  503. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +914 -105
  504. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +926 -108
  505. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +936 -118
  506. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +928 -106
  507. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +906 -102
  508. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +937 -119
  509. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +928 -110
  510. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +918 -114
  511. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +921 -117
  512. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +923 -115
  513. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +8828 -0
  514. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +8846 -0
  515. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +8843 -0
  516. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +8823 -0
  517. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +916 -112
  518. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +906 -102
  519. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +940 -83
  520. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +924 -106
  521. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +906 -102
  522. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +943 -86
  523. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +921 -103
  524. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +929 -125
  525. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +918 -114
  526. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +906 -102
  527. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +922 -104
  528. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +924 -106
  529. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +906 -102
  530. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +906 -102
  531. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +906 -102
  532. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +936 -88
  533. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +892 -88
  534. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +897 -89
  535. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +897 -89
  536. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +892 -88
  537. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +892 -88
  538. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +892 -88
  539. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +892 -88
  540. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +892 -88
  541. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +892 -88
  542. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +892 -88
  543. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +892 -88
  544. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +892 -88
  545. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +892 -88
  546. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +901 -96
  547. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +892 -88
  548. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +892 -88
  549. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +892 -88
  550. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +892 -88
  551. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +892 -88
  552. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +897 -89
  553. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +892 -88
  554. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +892 -88
  555. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +892 -88
  556. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +892 -88
  557. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +892 -88
  558. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +892 -88
  559. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +892 -88
  560. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +892 -88
  561. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +892 -88
  562. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +892 -88
  563. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +892 -88
  564. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +892 -88
  565. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +892 -88
  566. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/clear-view-button.png +0 -0
  567. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/cleared-view.png +0 -0
  568. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/config-table-columns-to-locations.png +0 -0
  569. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/configure-button.png +0 -0
  570. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/create-saved-view-success.png +0 -0
  571. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/current-saved-view-drop-down-menu.png +0 -0
  572. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/default-location-list-view.png +0 -0
  573. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/dropdown-button-after-new-saved-view.png +0 -0
  574. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/filter-application-to-locations.png +0 -0
  575. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/filter-button.png +0 -0
  576. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/global-default-location-list-view.png +0 -0
  577. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/location-list-view-with-saved-views.png +0 -0
  578. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/navigation-menu.png +0 -0
  579. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/save-as-new-view-drop-down.png +0 -0
  580. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/save-view-modal.png +0 -0
  581. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-admin-edit-buttons.png +0 -0
  582. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-admin-edit-success.png +0 -0
  583. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-admin-edit-view-unchecked.png +0 -0
  584. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-admin-edit-view.png +0 -0
  585. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-different-user.png +0 -0
  586. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-modal-unchecked.png +0 -0
  587. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/set-as-my-default-button.png +0 -0
  588. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/set-as-my-default-success.png +0 -0
  589. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/unsaved-saved-view.png +0 -0
  590. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/updated-saved-view.png +0 -0
  591. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +892 -88
  592. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +892 -88
  593. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +892 -88
  594. nautobot/project-static/docs/user-guide/index.html +892 -88
  595. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +892 -88
  596. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +892 -88
  597. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +892 -88
  598. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +892 -88
  599. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +1258 -785
  600. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +895 -91
  601. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +892 -88
  602. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +892 -88
  603. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +892 -88
  604. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +892 -88
  605. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +892 -88
  606. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +892 -88
  607. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +892 -88
  608. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +892 -88
  609. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +892 -88
  610. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +896 -88
  611. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +892 -88
  612. nautobot/project-static/docs/user-guide/platform-functionality/note.html +895 -91
  613. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +9061 -0
  614. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +895 -91
  615. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +892 -88
  616. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +892 -88
  617. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +892 -88
  618. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +892 -88
  619. nautobot/project-static/docs/user-guide/platform-functionality/role.html +895 -91
  620. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +9137 -0
  621. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +895 -91
  622. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +8933 -0
  623. nautobot/project-static/docs/user-guide/platform-functionality/status.html +892 -88
  624. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +892 -88
  625. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +950 -121
  626. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +892 -88
  627. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +892 -88
  628. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +892 -88
  629. nautobot/project-static/js/forms.js +71 -0
  630. nautobot/project-static/js/table_sorting_indicator.js +46 -0
  631. nautobot/project-static/js/tableconfig.js +6 -1
  632. nautobot/project-static/materialdesignicons-7.4.47/css/materialdesignicons.min.css +3 -0
  633. nautobot/project-static/{materialdesignicons-6.5.95 → materialdesignicons-7.4.47}/fonts/materialdesignicons-webfont.eot +0 -0
  634. nautobot/project-static/{materialdesignicons-6.5.95 → materialdesignicons-7.4.47}/fonts/materialdesignicons-webfont.ttf +0 -0
  635. nautobot/project-static/materialdesignicons-7.4.47/fonts/materialdesignicons-webfont.woff +0 -0
  636. nautobot/project-static/materialdesignicons-7.4.47/fonts/materialdesignicons-webfont.woff2 +0 -0
  637. nautobot/tenancy/__init__.py +0 -1
  638. nautobot/tenancy/apps.py +1 -0
  639. nautobot/tenancy/factory.py +3 -2
  640. nautobot/tenancy/filters/__init__.py +1 -0
  641. nautobot/tenancy/forms.py +1 -1
  642. nautobot/tenancy/templates/tenancy/tenant.html +24 -20
  643. nautobot/tenancy/views.py +11 -10
  644. nautobot/users/__init__.py +0 -1
  645. nautobot/users/api/serializers.py +1 -1
  646. nautobot/users/api/views.py +4 -2
  647. nautobot/users/apps.py +3 -2
  648. nautobot/users/factory.py +3 -3
  649. nautobot/users/migrations/0010_user_default_saved_views.py +20 -0
  650. nautobot/users/models.py +12 -0
  651. nautobot/users/tests/test_filters.py +6 -3
  652. nautobot/users/urls.py +8 -0
  653. nautobot/virtualization/__init__.py +0 -1
  654. nautobot/virtualization/apps.py +1 -0
  655. nautobot/virtualization/filters.py +6 -1
  656. nautobot/virtualization/forms.py +11 -3
  657. nautobot/virtualization/graphql/types.py +2 -2
  658. nautobot/virtualization/migrations/0029_add_role_field_to_interface_models.py +27 -0
  659. nautobot/virtualization/migrations/0030_alter_virtualmachine_local_config_context_data_owner_content_type_and_more.py +67 -0
  660. nautobot/virtualization/models.py +0 -2
  661. nautobot/virtualization/tables.py +10 -3
  662. nautobot/virtualization/templates/virtualization/virtualmachine.html +1 -1
  663. nautobot/virtualization/templates/virtualization/vminterface.html +7 -1
  664. nautobot/virtualization/templates/virtualization/vminterface_edit.html +1 -0
  665. nautobot/virtualization/tests/test_api.py +9 -4
  666. nautobot/virtualization/tests/test_filters.py +22 -0
  667. nautobot/virtualization/tests/test_models.py +7 -3
  668. nautobot/virtualization/tests/test_views.py +19 -3
  669. nautobot/virtualization/urls.py +2 -2
  670. nautobot/virtualization/views.py +10 -32
  671. {nautobot-2.2.9.dist-info → nautobot-2.3.0.dist-info}/METADATA +20 -18
  672. {nautobot-2.2.9.dist-info → nautobot-2.3.0.dist-info}/RECORD +677 -557
  673. nautobot/project-static/docs/assets/stylesheets/main.76a95c52.min.css +0 -1
  674. nautobot/project-static/docs/assets/stylesheets/main.76a95c52.min.css.map +0 -1
  675. nautobot/project-static/materialdesignicons-6.5.95/.github/ISSUE_TEMPLATE.md +0 -3
  676. nautobot/project-static/materialdesignicons-6.5.95/README.md +0 -25
  677. nautobot/project-static/materialdesignicons-6.5.95/css/materialdesignicons.css +0 -26654
  678. nautobot/project-static/materialdesignicons-6.5.95/css/materialdesignicons.css.map +0 -16
  679. nautobot/project-static/materialdesignicons-6.5.95/css/materialdesignicons.min.css +0 -3
  680. nautobot/project-static/materialdesignicons-6.5.95/css/materialdesignicons.min.css.map +0 -16
  681. nautobot/project-static/materialdesignicons-6.5.95/fonts/materialdesignicons-webfont.woff +0 -0
  682. nautobot/project-static/materialdesignicons-6.5.95/fonts/materialdesignicons-webfont.woff2 +0 -0
  683. nautobot/project-static/materialdesignicons-6.5.95/package.json +0 -28
  684. nautobot/project-static/materialdesignicons-6.5.95/preview.html +0 -717
  685. nautobot/project-static/materialdesignicons-6.5.95/scss/_animated.scss +0 -27
  686. nautobot/project-static/materialdesignicons-6.5.95/scss/_core.scss +0 -10
  687. nautobot/project-static/materialdesignicons-6.5.95/scss/_extras.scss +0 -65
  688. nautobot/project-static/materialdesignicons-6.5.95/scss/_functions.scss +0 -20
  689. nautobot/project-static/materialdesignicons-6.5.95/scss/_icons.scss +0 -10
  690. nautobot/project-static/materialdesignicons-6.5.95/scss/_path.scss +0 -10
  691. nautobot/project-static/materialdesignicons-6.5.95/scss/_variables.scss +0 -6606
  692. nautobot/project-static/materialdesignicons-6.5.95/scss/materialdesignicons.scss +0 -8
  693. /nautobot/project-static/{materialdesignicons-6.5.95 → materialdesignicons-7.4.47}/LICENSE +0 -0
  694. {nautobot-2.2.9.dist-info → nautobot-2.3.0.dist-info}/LICENSE.txt +0 -0
  695. {nautobot-2.2.9.dist-info → nautobot-2.3.0.dist-info}/NOTICE +0 -0
  696. {nautobot-2.2.9.dist-info → nautobot-2.3.0.dist-info}/WHEEL +0 -0
  697. {nautobot-2.2.9.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">