nautobot 2.4.18__py3-none-any.whl → 2.4.19__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 (583) hide show
  1. nautobot/apps/ui.py +6 -0
  2. nautobot/circuits/tables.py +1 -1
  3. nautobot/circuits/templates/circuits/circuit_create.html +7 -7
  4. nautobot/circuits/templates/circuits/circuit_retrieve.html +1 -5
  5. nautobot/circuits/templates/circuits/circuittermination_create.html +26 -26
  6. nautobot/circuits/templates/circuits/inc/circuit_termination.html +20 -20
  7. nautobot/circuits/templates/circuits/inc/circuit_termination_header_extra_content.html +3 -3
  8. nautobot/circuits/templates/circuits/inc/circuit_termination_speed_fragment.html +7 -7
  9. nautobot/circuits/templates/circuits/providernetwork_retrieve.html +1 -3
  10. nautobot/circuits/views.py +26 -9
  11. nautobot/cloud/templates/cloud/cloudaccount_retrieve.html +1 -4
  12. nautobot/cloud/templates/cloud/cloudnetwork_retrieve.html +1 -7
  13. nautobot/cloud/templates/cloud/cloudresourcetype_retrieve.html +1 -3
  14. nautobot/cloud/templates/cloud/cloudservice_retrieve.html +1 -5
  15. nautobot/cloud/views.py +45 -0
  16. nautobot/core/graphql/generators.py +5 -2
  17. nautobot/core/jobs/bulk_actions.py +48 -85
  18. nautobot/core/models/querysets.py +2 -1
  19. nautobot/core/templates/40x.html +15 -15
  20. nautobot/core/templates/500.html +21 -21
  21. nautobot/core/templates/admin/app_index.html +8 -8
  22. nautobot/core/templates/admin/base.html +104 -104
  23. nautobot/core/templates/admin/change_form.html +65 -65
  24. nautobot/core/templates/admin/change_list.html +60 -60
  25. nautobot/core/templates/admin/change_list_results.html +39 -39
  26. nautobot/core/templates/admin/config/config.html +47 -47
  27. nautobot/core/templates/admin/delete_confirmation.html +47 -47
  28. nautobot/core/templates/admin/edit_inline/stacked.html +124 -124
  29. nautobot/core/templates/admin/edit_inline/tabular.html +60 -60
  30. nautobot/core/templates/admin/includes/fieldset.html +4 -4
  31. nautobot/core/templates/admin/index.html +60 -60
  32. nautobot/core/templates/admin/prepopulated_fields_js.html +18 -18
  33. nautobot/core/templates/admin/submit_line.html +4 -4
  34. nautobot/core/templates/base_django.html +46 -46
  35. nautobot/core/templates/buttons/consolidated_bulk_action_buttons.html +8 -8
  36. nautobot/core/templates/buttons/consolidated_detail_view_action_buttons.html +8 -8
  37. nautobot/core/templates/buttons/export.html +3 -3
  38. nautobot/core/templates/components/breadcrumbs.html +5 -5
  39. nautobot/core/templates/components/button/default.html +3 -3
  40. nautobot/core/templates/components/button/dropdown.html +7 -7
  41. nautobot/core/templates/components/button/formbutton.html +4 -4
  42. nautobot/core/templates/components/panel/body_content_data_table.html +1 -1
  43. nautobot/core/templates/components/panel/body_wrapper_generic_table.html +3 -0
  44. nautobot/core/templates/components/panel/footer_content_table.html +3 -1
  45. nautobot/core/templates/components/panel/header_extra_content_table.html +10 -1
  46. nautobot/core/templates/components/tab/content_wrapper.html +1 -1
  47. nautobot/core/templates/components/tab/label_wrapper.html +1 -1
  48. nautobot/core/templates/components/tab/label_wrapper_distinct_view.html +10 -3
  49. nautobot/core/templates/generic/object_bulk_add_component.html +40 -40
  50. nautobot/core/templates/generic/object_bulk_create.html +3 -3
  51. nautobot/core/templates/generic/object_bulk_destroy.html +6 -6
  52. nautobot/core/templates/generic/object_bulk_update.html +52 -52
  53. nautobot/core/templates/generic/object_import.html +33 -33
  54. nautobot/core/templates/generic/object_list.html +267 -267
  55. nautobot/core/templates/generic/object_retrieve.html +261 -261
  56. nautobot/core/templates/graphene/graphiql.html +127 -127
  57. nautobot/core/templates/home.html +62 -62
  58. nautobot/core/templates/inc/computed_fields/panel_data.html +13 -13
  59. nautobot/core/templates/inc/created_updated.html +8 -8
  60. nautobot/core/templates/inc/custom_fields/panel_data.html +13 -13
  61. nautobot/core/templates/inc/dynamic_groups_panel.html +11 -11
  62. nautobot/core/templates/inc/footer.html +19 -19
  63. nautobot/core/templates/inc/javascript.html +1 -1
  64. nautobot/core/templates/inc/media.html +46 -46
  65. nautobot/core/templates/inc/nav_menu.html +1 -1
  66. nautobot/core/templates/inc/relationships_table_rows.html +22 -22
  67. nautobot/core/templates/inc/tenant_table_row.html +1 -1
  68. nautobot/core/templates/login.html +77 -77
  69. nautobot/core/templates/media_failure.html +38 -38
  70. nautobot/core/templates/panel_table.html +1 -1
  71. nautobot/core/templates/rest_framework/api.html +3 -3
  72. nautobot/core/templates/search.html +1 -1
  73. nautobot/core/templates/swagger_ui.html +9 -9
  74. nautobot/core/templates/utilities/confirmation_form.html +18 -18
  75. nautobot/core/templates/utilities/render_field.html +1 -1
  76. nautobot/core/templates/utilities/render_jinja2.html +43 -43
  77. nautobot/core/templates/utilities/templatetags/filter_form_modal.html +56 -56
  78. nautobot/core/templates/utilities/templatetags/utilization_graph.html +1 -1
  79. nautobot/core/templates/utilities/theme_preview.html +799 -799
  80. nautobot/core/templates/utilities/worker_status.html +122 -122
  81. nautobot/core/templates/widgets/clearable_file.html +3 -3
  82. nautobot/core/templates/widgets/sluginput.html +1 -1
  83. nautobot/core/templatetags/buttons.py +8 -2
  84. nautobot/core/templatetags/helpers.py +1 -1
  85. nautobot/core/testing/integration.py +7 -4
  86. nautobot/core/testing/views.py +24 -5
  87. nautobot/core/tests/test_breadcrumbs.py +78 -4
  88. nautobot/core/tests/test_commands.py +7 -4
  89. nautobot/core/tests/test_graphql.py +20 -5
  90. nautobot/core/tests/test_jobs.py +34 -21
  91. nautobot/core/tests/test_ui.py +175 -1
  92. nautobot/core/tests/test_utils.py +35 -0
  93. nautobot/core/tests/test_views_generic.py +43 -0
  94. nautobot/core/tests/test_views_utils.py +239 -5
  95. nautobot/core/ui/breadcrumbs.py +208 -21
  96. nautobot/core/ui/bulk_buttons.py +8 -0
  97. nautobot/core/ui/object_detail.py +138 -55
  98. nautobot/core/ui/titles.py +1 -0
  99. nautobot/core/utils/requests.py +27 -2
  100. nautobot/core/views/generic.py +41 -31
  101. nautobot/core/views/mixins.py +80 -110
  102. nautobot/core/views/utils.py +153 -1
  103. nautobot/dcim/api/serializers.py +8 -2
  104. nautobot/dcim/constants.py +1 -0
  105. nautobot/dcim/factory.py +4 -3
  106. nautobot/dcim/filters/mixins.py +1 -2
  107. nautobot/dcim/forms.py +5 -1
  108. nautobot/dcim/migrations/0074_alter_rack_u_height.py +21 -0
  109. nautobot/dcim/models/devices.py +26 -1
  110. nautobot/dcim/models/racks.py +2 -2
  111. nautobot/dcim/templates/dcim/cable.html +53 -53
  112. nautobot/dcim/templates/dcim/cable_connect.html +182 -182
  113. nautobot/dcim/templates/dcim/cable_trace.html +1 -1
  114. nautobot/dcim/templates/dcim/console_port_connection_list.html +5 -5
  115. nautobot/dcim/templates/dcim/consoleport.html +86 -86
  116. nautobot/dcim/templates/dcim/consoleserverport.html +86 -86
  117. nautobot/dcim/templates/dcim/controller_create.html +34 -34
  118. nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +68 -68
  119. nautobot/dcim/templates/dcim/device/base.html +1 -104
  120. nautobot/dcim/templates/dcim/device/config.html +17 -17
  121. nautobot/dcim/templates/dcim/device/consoleports.html +1 -52
  122. nautobot/dcim/templates/dcim/device/consoleserverports.html +1 -52
  123. nautobot/dcim/templates/dcim/device/devicebays.html +1 -48
  124. nautobot/dcim/templates/dcim/device/frontports.html +1 -52
  125. nautobot/dcim/templates/dcim/device/interfaces.html +1 -56
  126. nautobot/dcim/templates/dcim/device/inventory.html +1 -48
  127. nautobot/dcim/templates/dcim/device/lldp_neighbors.html +64 -64
  128. nautobot/dcim/templates/dcim/device/modulebays.html +1 -48
  129. nautobot/dcim/templates/dcim/device/poweroutlets.html +1 -52
  130. nautobot/dcim/templates/dcim/device/powerports.html +1 -52
  131. nautobot/dcim/templates/dcim/device/rearports.html +1 -52
  132. nautobot/dcim/templates/dcim/device/status.html +66 -66
  133. nautobot/dcim/templates/dcim/device/wireless.html +1 -72
  134. nautobot/dcim/templates/dcim/device.html +4 -422
  135. nautobot/dcim/templates/dcim/device_component_add.html +25 -25
  136. nautobot/dcim/templates/dcim/device_create.html +229 -0
  137. nautobot/dcim/templates/dcim/device_edit.html +2 -227
  138. nautobot/dcim/templates/dcim/devicebay.html +41 -41
  139. nautobot/dcim/templates/dcim/devicebay_populate.html +32 -32
  140. nautobot/dcim/templates/dcim/devicetype_component_add.html +28 -28
  141. nautobot/dcim/templates/dcim/devicetype_retrieve.html +1 -3
  142. nautobot/dcim/templates/dcim/frontport.html +84 -84
  143. nautobot/dcim/templates/dcim/inc/cable_toggle_buttons.html +1 -1
  144. nautobot/dcim/templates/dcim/inc/device_interface_filter.html +8 -0
  145. nautobot/dcim/templates/dcim/inc/device_napalm_tabs.html +1 -15
  146. nautobot/dcim/templates/dcim/inc/location_hierarchy.html +22 -22
  147. nautobot/dcim/templates/dcim/interface.html +206 -206
  148. nautobot/dcim/templates/dcim/interface_connection_list.html +5 -5
  149. nautobot/dcim/templates/dcim/interfaceredundancygroupassociation_create.html +6 -6
  150. nautobot/dcim/templates/dcim/inventoryitem.html +44 -44
  151. nautobot/dcim/templates/dcim/inventoryitem_add.html +32 -32
  152. nautobot/dcim/templates/dcim/inventoryitem_edit.html +22 -22
  153. nautobot/dcim/templates/dcim/location_migrate_data_to_contact.html +46 -46
  154. nautobot/dcim/templates/dcim/location_retrieve.html +1 -7
  155. nautobot/dcim/templates/dcim/locationtype.html +1 -6
  156. nautobot/dcim/templates/dcim/locationtype_retrieve.html +1 -7
  157. nautobot/dcim/templates/dcim/module/base.html +85 -85
  158. nautobot/dcim/templates/dcim/module_interfaces.html +1 -1
  159. nautobot/dcim/templates/dcim/module_modulebays.html +1 -1
  160. nautobot/dcim/templates/dcim/module_retrieve.html +52 -52
  161. nautobot/dcim/templates/dcim/module_update.html +61 -61
  162. nautobot/dcim/templates/dcim/modulebay_destroy.html +1 -1
  163. nautobot/dcim/templates/dcim/modulebay_retrieve.html +85 -85
  164. nautobot/dcim/templates/dcim/modulebay_update.html +33 -33
  165. nautobot/dcim/templates/dcim/modulefamily_retrieve.html +1 -1
  166. nautobot/dcim/templates/dcim/moduletype_retrieve.html +140 -144
  167. nautobot/dcim/templates/dcim/platform_create.html +38 -38
  168. nautobot/dcim/templates/dcim/power_port_connection_list.html +5 -5
  169. nautobot/dcim/templates/dcim/powerfeed_retrieve.html +1 -8
  170. nautobot/dcim/templates/dcim/poweroutlet.html +85 -85
  171. nautobot/dcim/templates/dcim/powerpanel_retrieve.html +1 -8
  172. nautobot/dcim/templates/dcim/powerport.html +91 -91
  173. nautobot/dcim/templates/dcim/rack_elevation_list.html +18 -18
  174. nautobot/dcim/templates/dcim/rack_retrieve.html +264 -274
  175. nautobot/dcim/templates/dcim/rackreservation_retrieve.html +0 -3
  176. nautobot/dcim/templates/dcim/rearport.html +78 -78
  177. nautobot/dcim/templates/dcim/virtualdevicecontext_retrieve.html +1 -5
  178. nautobot/dcim/tests/integration/test_device_bulk_operations.py +3 -2
  179. nautobot/dcim/tests/integration/test_location_bulk_operations.py +6 -2
  180. nautobot/dcim/tests/test_api.py +33 -1
  181. nautobot/dcim/tests/test_views.py +148 -4
  182. nautobot/dcim/ui.py +29 -0
  183. nautobot/dcim/urls.py +1 -109
  184. nautobot/dcim/utils.py +30 -0
  185. nautobot/dcim/views.py +1009 -531
  186. nautobot/extras/tables.py +20 -0
  187. nautobot/extras/templates/extras/computedfield_edit.html +4 -4
  188. nautobot/extras/templates/extras/configcontext_update.html +1 -1
  189. nautobot/extras/templates/extras/configcontextschema_retrieve.html +32 -32
  190. nautobot/extras/templates/extras/customfield_update.html +23 -23
  191. nautobot/extras/templates/extras/dynamicgroup_retrieve.html +38 -38
  192. nautobot/extras/templates/extras/dynamicgroup_update.html +62 -62
  193. nautobot/extras/templates/extras/gitrepository_list.html +10 -10
  194. nautobot/extras/templates/extras/gitrepository_retrieve.html +68 -68
  195. nautobot/extras/templates/extras/graphqlquery_retrieve.html +73 -73
  196. nautobot/extras/templates/extras/inc/configcontext_format.html +2 -2
  197. nautobot/extras/templates/extras/inc/job_table.html +10 -10
  198. nautobot/extras/templates/extras/inc/jobresult.html +21 -21
  199. nautobot/extras/templates/extras/inc/jobresult_js.html +6 -6
  200. nautobot/extras/templates/extras/inc/tags_panel.html +10 -10
  201. nautobot/extras/templates/extras/job.html +64 -64
  202. nautobot/extras/templates/extras/job_approval_request.html +9 -9
  203. nautobot/extras/templates/extras/job_bulk_edit.html +13 -13
  204. nautobot/extras/templates/extras/job_edit.html +45 -45
  205. nautobot/extras/templates/extras/job_list.html +4 -4
  206. nautobot/extras/templates/extras/jobresult_retrieve.html +0 -25
  207. nautobot/extras/templates/extras/marketplace.html +101 -101
  208. nautobot/extras/templates/extras/metadatatype_create.html +20 -20
  209. nautobot/extras/templates/extras/object_assign_contact_or_team.html +18 -18
  210. nautobot/extras/templates/extras/object_configcontext.html +1 -3
  211. nautobot/extras/templates/extras/objectchange.html +2 -165
  212. nautobot/extras/templates/extras/objectchange_retrieve.html +165 -0
  213. nautobot/extras/templates/extras/plugin_detail.html +41 -41
  214. nautobot/extras/templates/extras/plugins_list.html +9 -9
  215. nautobot/extras/templates/extras/plugins_tiles.html +26 -26
  216. nautobot/extras/templates/extras/relationship_edit.html +4 -4
  217. nautobot/extras/templates/extras/role_retrieve.html +13 -13
  218. nautobot/extras/templates/extras/scheduled_jobs_approval_queue_list.html +21 -21
  219. nautobot/extras/templates/extras/scheduledjob.html +128 -128
  220. nautobot/extras/templates/extras/secret_create.html +53 -53
  221. nautobot/extras/templates/extras/secretsgroup_update.html +13 -13
  222. nautobot/extras/templates/extras/templatetags/plugin_object_detail_tabs.html +3 -3
  223. nautobot/extras/templates/extras/webhook.html +79 -79
  224. nautobot/extras/tests/integration/test_relationships.py +6 -6
  225. nautobot/extras/tests/test_filters.py +1 -1
  226. nautobot/extras/tests/test_jobs.py +2 -0
  227. nautobot/extras/tests/test_views.py +3 -3
  228. nautobot/extras/urls.py +1 -3
  229. nautobot/extras/views.py +101 -27
  230. nautobot/ipam/filters.py +2 -2
  231. nautobot/ipam/migrations/0053_alter_vrfdeviceassignment_options_and_more.py +20 -0
  232. nautobot/ipam/models.py +34 -0
  233. nautobot/ipam/tables.py +3 -1
  234. nautobot/ipam/templates/ipam/inc/prefix_header_extra_content_table.html +4 -0
  235. nautobot/ipam/templates/ipam/inc/toggle_available.html +8 -8
  236. nautobot/ipam/templates/ipam/inc/vlangroup_header.html +4 -4
  237. nautobot/ipam/templates/ipam/ipaddress.html +119 -123
  238. nautobot/ipam/templates/ipam/ipaddress_assign.html +10 -10
  239. nautobot/ipam/templates/ipam/ipaddress_edit.html +1 -1
  240. nautobot/ipam/templates/ipam/ipaddress_merge.html +180 -180
  241. nautobot/ipam/templates/ipam/ipaddresstointerface_retrieve.html +48 -48
  242. nautobot/ipam/templates/ipam/prefix.html +2 -107
  243. nautobot/ipam/templates/ipam/prefix_create.html +34 -0
  244. nautobot/ipam/templates/ipam/prefix_edit.html +1 -34
  245. nautobot/ipam/templates/ipam/prefix_retrieve.html +3 -0
  246. nautobot/ipam/templates/ipam/service_retrieve.html +1 -6
  247. nautobot/ipam/templates/ipam/vlan_retrieve.html +1 -7
  248. nautobot/ipam/templates/ipam/vrf_edit.html +1 -1
  249. nautobot/ipam/tests/test_views.py +34 -0
  250. nautobot/ipam/ui.py +145 -0
  251. nautobot/ipam/urls.py +1 -46
  252. nautobot/ipam/utils/__init__.py +26 -0
  253. nautobot/ipam/views.py +219 -106
  254. nautobot/project-static/docs/404.html +11 -11
  255. nautobot/project-static/docs/apps/index.html +11 -11
  256. nautobot/project-static/docs/apps/nautobot-apps.html +11 -11
  257. nautobot/project-static/docs/assets/javascripts/{bundle.92b07e13.min.js → bundle.f55a23d4.min.js} +2 -2
  258. nautobot/project-static/docs/assets/javascripts/{bundle.92b07e13.min.js.map → bundle.f55a23d4.min.js.map} +2 -2
  259. nautobot/project-static/docs/assets/stylesheets/{main.7e37652d.min.css → main.e53b48f4.min.css} +1 -1
  260. nautobot/project-static/docs/assets/stylesheets/{main.7e37652d.min.css.map → main.e53b48f4.min.css.map} +1 -1
  261. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +11 -11
  262. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +11 -11
  263. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +11 -11
  264. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +11 -11
  265. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +11 -11
  266. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +11 -11
  267. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +11 -11
  268. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +11 -11
  269. nautobot/project-static/docs/code-reference/nautobot/apps/events.html +11 -11
  270. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +11 -11
  271. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +11 -11
  272. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +11 -11
  273. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +11 -11
  274. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +11 -11
  275. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +11 -11
  276. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +11 -11
  277. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +11 -11
  278. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +11 -11
  279. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +11 -11
  280. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +11 -11
  281. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +2174 -1226
  282. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +11 -11
  283. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +12 -12
  284. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +72 -27
  285. nautobot/project-static/docs/development/apps/api/configuration-view.html +11 -11
  286. nautobot/project-static/docs/development/apps/api/database-backend-config.html +11 -11
  287. nautobot/project-static/docs/development/apps/api/models/django-admin.html +11 -11
  288. nautobot/project-static/docs/development/apps/api/models/global-search.html +11 -11
  289. nautobot/project-static/docs/development/apps/api/models/graphql.html +11 -11
  290. nautobot/project-static/docs/development/apps/api/models/index.html +11 -11
  291. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +11 -11
  292. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +11 -11
  293. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +11 -11
  294. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +11 -11
  295. nautobot/project-static/docs/development/apps/api/platform-features/index.html +11 -11
  296. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +11 -11
  297. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +11 -11
  298. nautobot/project-static/docs/development/apps/api/platform-features/prepopulating-data.html +11 -11
  299. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +11 -11
  300. nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +11 -11
  301. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +11 -11
  302. nautobot/project-static/docs/development/apps/api/prometheus.html +11 -11
  303. nautobot/project-static/docs/development/apps/api/setup.html +11 -11
  304. nautobot/project-static/docs/development/apps/api/testing.html +11 -11
  305. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +11 -11
  306. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +11 -11
  307. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +11 -11
  308. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +11 -11
  309. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +11 -11
  310. nautobot/project-static/docs/development/apps/api/views/base-template.html +11 -11
  311. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +11 -11
  312. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +11 -11
  313. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +11 -11
  314. nautobot/project-static/docs/development/apps/api/views/index.html +11 -11
  315. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +11 -11
  316. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +11 -11
  317. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +11 -11
  318. nautobot/project-static/docs/development/apps/api/views/notes.html +11 -11
  319. nautobot/project-static/docs/development/apps/api/views/rest-api.html +11 -11
  320. nautobot/project-static/docs/development/apps/api/views/urls.html +11 -11
  321. nautobot/project-static/docs/development/apps/index.html +11 -11
  322. nautobot/project-static/docs/development/apps/migration/code-updates.html +11 -11
  323. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +11 -11
  324. nautobot/project-static/docs/development/apps/migration/from-v1.html +11 -11
  325. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +11 -11
  326. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +11 -11
  327. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +11 -11
  328. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +11 -11
  329. nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +11 -11
  330. nautobot/project-static/docs/development/apps/migration/ui-component-framework/breadcrumbs-titles.html +11 -11
  331. nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +11 -11
  332. nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +11 -11
  333. nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +11 -11
  334. nautobot/project-static/docs/development/apps/porting-from-netbox.html +11 -11
  335. nautobot/project-static/docs/development/core/application-registry.html +11 -11
  336. nautobot/project-static/docs/development/core/best-practices.html +11 -11
  337. nautobot/project-static/docs/development/core/bootstrap-ui.html +11 -11
  338. nautobot/project-static/docs/development/core/caching.html +11 -11
  339. nautobot/project-static/docs/development/core/controllers.html +11 -11
  340. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +11 -11
  341. nautobot/project-static/docs/development/core/generic-views.html +11 -11
  342. nautobot/project-static/docs/development/core/getting-started.html +50 -48
  343. nautobot/project-static/docs/development/core/homepage.html +11 -11
  344. nautobot/project-static/docs/development/core/index.html +11 -11
  345. nautobot/project-static/docs/development/core/minikube-dev-environment-for-k8s-jobs.html +11 -11
  346. nautobot/project-static/docs/development/core/model-checklist.html +11 -11
  347. nautobot/project-static/docs/development/core/model-features.html +11 -11
  348. nautobot/project-static/docs/development/core/natural-keys.html +11 -11
  349. nautobot/project-static/docs/development/core/navigation-menu.html +11 -11
  350. nautobot/project-static/docs/development/core/release-checklist.html +11 -11
  351. nautobot/project-static/docs/development/core/role-internals.html +11 -11
  352. nautobot/project-static/docs/development/core/settings.html +11 -11
  353. nautobot/project-static/docs/development/core/style-guide.html +15 -11
  354. nautobot/project-static/docs/development/core/templates.html +11 -11
  355. nautobot/project-static/docs/development/core/testing.html +11 -11
  356. nautobot/project-static/docs/development/core/ui-component-framework.html +11 -11
  357. nautobot/project-static/docs/development/core/user-preferences.html +11 -11
  358. nautobot/project-static/docs/development/index.html +11 -11
  359. nautobot/project-static/docs/development/jobs/getting-started.html +11 -11
  360. nautobot/project-static/docs/development/jobs/index.html +11 -11
  361. nautobot/project-static/docs/development/jobs/installation.html +11 -11
  362. nautobot/project-static/docs/development/jobs/job-extensions.html +11 -11
  363. nautobot/project-static/docs/development/jobs/job-logging.html +11 -11
  364. nautobot/project-static/docs/development/jobs/job-patterns.html +11 -11
  365. nautobot/project-static/docs/development/jobs/job-structure.html +11 -11
  366. nautobot/project-static/docs/development/jobs/migration/from-v1.html +11 -11
  367. nautobot/project-static/docs/development/jobs/testing.html +11 -11
  368. nautobot/project-static/docs/index.html +11 -11
  369. nautobot/project-static/docs/objects.inv +0 -0
  370. nautobot/project-static/docs/overview/application_stack.html +11 -11
  371. nautobot/project-static/docs/overview/design_philosophy.html +11 -11
  372. nautobot/project-static/docs/release-notes/index.html +11 -11
  373. nautobot/project-static/docs/release-notes/version-1.0.html +11 -11
  374. nautobot/project-static/docs/release-notes/version-1.1.html +11 -11
  375. nautobot/project-static/docs/release-notes/version-1.2.html +11 -11
  376. nautobot/project-static/docs/release-notes/version-1.3.html +11 -11
  377. nautobot/project-static/docs/release-notes/version-1.4.html +11 -11
  378. nautobot/project-static/docs/release-notes/version-1.5.html +11 -11
  379. nautobot/project-static/docs/release-notes/version-1.6.html +11 -11
  380. nautobot/project-static/docs/release-notes/version-2.0.html +11 -11
  381. nautobot/project-static/docs/release-notes/version-2.1.html +11 -11
  382. nautobot/project-static/docs/release-notes/version-2.2.html +11 -11
  383. nautobot/project-static/docs/release-notes/version-2.3.html +11 -11
  384. nautobot/project-static/docs/release-notes/version-2.4.html +196 -11
  385. nautobot/project-static/docs/search/search_index.json +1 -1
  386. nautobot/project-static/docs/sitemap.xml +300 -300
  387. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  388. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +11 -11
  389. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +11 -11
  390. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +11 -11
  391. nautobot/project-static/docs/user-guide/administration/configuration/index.html +11 -11
  392. nautobot/project-static/docs/user-guide/administration/configuration/redis.html +11 -11
  393. nautobot/project-static/docs/user-guide/administration/configuration/settings.html +11 -11
  394. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +11 -11
  395. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +89 -14
  396. nautobot/project-static/docs/user-guide/administration/guides/docker.html +11 -11
  397. nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +11 -11
  398. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +11 -11
  399. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +11 -11
  400. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +11 -11
  401. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +11 -11
  402. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +11 -11
  403. nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +11 -11
  404. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +11 -11
  405. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +11 -11
  406. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +11 -11
  407. nautobot/project-static/docs/user-guide/administration/installation/index.html +11 -11
  408. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +11 -11
  409. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +11 -11
  410. nautobot/project-static/docs/user-guide/administration/installation/services.html +11 -11
  411. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +11 -11
  412. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +11 -11
  413. nautobot/project-static/docs/user-guide/administration/security/index.html +11 -11
  414. nautobot/project-static/docs/user-guide/administration/security/notices.html +11 -11
  415. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +11 -11
  416. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +11 -11
  417. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +11 -11
  418. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +11 -11
  419. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +11 -11
  420. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +11 -11
  421. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +11 -11
  422. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +11 -11
  423. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +11 -11
  424. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +11 -11
  425. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +11 -11
  426. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +11 -11
  427. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +11 -11
  428. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +11 -11
  429. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +11 -11
  430. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +11 -11
  431. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +11 -11
  432. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +11 -11
  433. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +11 -11
  434. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +11 -11
  435. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +11 -11
  436. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +11 -11
  437. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +11 -11
  438. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +11 -11
  439. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +11 -11
  440. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +11 -11
  441. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +11 -11
  442. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +11 -11
  443. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +11 -11
  444. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +11 -11
  445. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +11 -11
  446. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +11 -11
  447. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +11 -11
  448. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +11 -11
  449. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +11 -11
  450. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +11 -11
  451. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +11 -11
  452. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +11 -11
  453. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +11 -11
  454. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +11 -11
  455. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +11 -11
  456. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +11 -11
  457. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +11 -11
  458. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +11 -11
  459. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +11 -11
  460. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +11 -11
  461. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +11 -11
  462. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +11 -11
  463. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulefamily.html +11 -11
  464. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +11 -11
  465. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +11 -11
  466. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +11 -11
  467. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +11 -11
  468. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +11 -11
  469. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +11 -11
  470. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +11 -11
  471. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +11 -11
  472. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +11 -11
  473. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +11 -11
  474. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +11 -11
  475. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +11 -11
  476. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +11 -11
  477. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +11 -11
  478. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +11 -11
  479. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +11 -11
  480. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +11 -11
  481. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +11 -11
  482. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +11 -11
  483. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +11 -11
  484. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +11 -11
  485. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +11 -11
  486. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +11 -11
  487. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +11 -11
  488. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +11 -11
  489. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +11 -11
  490. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +11 -11
  491. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +11 -11
  492. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +11 -11
  493. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +11 -11
  494. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +11 -11
  495. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +11 -11
  496. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +11 -11
  497. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +11 -11
  498. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +11 -11
  499. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +11 -11
  500. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +11 -11
  501. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +11 -11
  502. nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +11 -11
  503. nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +11 -11
  504. nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +11 -11
  505. nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +11 -11
  506. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +11 -11
  507. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +11 -11
  508. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +11 -11
  509. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +11 -11
  510. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +11 -11
  511. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +11 -11
  512. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +11 -11
  513. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +11 -11
  514. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +11 -11
  515. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +11 -11
  516. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +11 -11
  517. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +11 -11
  518. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +11 -11
  519. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +11 -11
  520. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +11 -11
  521. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +11 -11
  522. nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +11 -11
  523. nautobot/project-static/docs/user-guide/index.html +11 -11
  524. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +11 -11
  525. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +11 -11
  526. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +11 -11
  527. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +11 -11
  528. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +11 -11
  529. nautobot/project-static/docs/user-guide/platform-functionality/events.html +11 -11
  530. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +11 -11
  531. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +11 -11
  532. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +11 -11
  533. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +11 -11
  534. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +11 -11
  535. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +11 -11
  536. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +11 -11
  537. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +11 -11
  538. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +11 -11
  539. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +11 -11
  540. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +11 -11
  541. nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +11 -11
  542. nautobot/project-static/docs/user-guide/platform-functionality/jobs/managing-jobs.html +11 -11
  543. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +11 -11
  544. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +11 -11
  545. nautobot/project-static/docs/user-guide/platform-functionality/note.html +11 -11
  546. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +11 -11
  547. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +11 -11
  548. nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +11 -11
  549. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +11 -11
  550. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +11 -11
  551. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +11 -11
  552. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +11 -11
  553. nautobot/project-static/docs/user-guide/platform-functionality/role.html +11 -11
  554. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +11 -11
  555. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +11 -11
  556. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +11 -11
  557. nautobot/project-static/docs/user-guide/platform-functionality/status.html +11 -11
  558. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +11 -11
  559. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +11 -11
  560. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +11 -11
  561. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +11 -11
  562. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +11 -11
  563. nautobot/tenancy/templates/tenancy/tenant.html +1 -7
  564. nautobot/tenancy/views.py +13 -0
  565. nautobot/users/templates/users/api_tokens.html +4 -4
  566. nautobot/users/templates/users/base.html +28 -28
  567. nautobot/virtualization/templates/virtualization/cluster.html +64 -64
  568. nautobot/virtualization/templates/virtualization/inc/virtualmachine_vminterface_filter.html +8 -0
  569. nautobot/virtualization/templates/virtualization/virtualmachine_component_add.html +25 -25
  570. nautobot/virtualization/templates/virtualization/virtualmachine_retrieve.html +1 -251
  571. nautobot/virtualization/templates/virtualization/vminterface.html +70 -70
  572. nautobot/virtualization/urls.py +0 -12
  573. nautobot/virtualization/views.py +158 -54
  574. nautobot/wireless/templates/wireless/wirelessnetwork_create.html +13 -13
  575. nautobot/wireless/tests/integration/test_radio_profile.py +1 -1
  576. {nautobot-2.4.18.dist-info → nautobot-2.4.19.dist-info}/METADATA +1 -1
  577. {nautobot-2.4.18.dist-info → nautobot-2.4.19.dist-info}/RECORD +581 -570
  578. nautobot/ipam/templates/ipam/prefix_ipaddresses.html +0 -11
  579. nautobot/ipam/templates/ipam/prefix_prefixes.html +0 -11
  580. {nautobot-2.4.18.dist-info → nautobot-2.4.19.dist-info}/LICENSE.txt +0 -0
  581. {nautobot-2.4.18.dist-info → nautobot-2.4.19.dist-info}/NOTICE +0 -0
  582. {nautobot-2.4.18.dist-info → nautobot-2.4.19.dist-info}/WHEEL +0 -0
  583. {nautobot-2.4.18.dist-info → nautobot-2.4.19.dist-info}/entry_points.txt +0 -0
@@ -11,7 +11,7 @@ from django.contrib.auth.models import Group
11
11
  from django.contrib.contenttypes.models import ContentType
12
12
  from django.core.cache import cache
13
13
  from django.db.models import Count, Q
14
- from django.test import override_settings, TestCase
14
+ from django.test import override_settings
15
15
  from django.test.client import RequestFactory
16
16
  from django.urls import reverse
17
17
  import graphene.types
@@ -38,7 +38,7 @@ from nautobot.core.graphql.schema import (
38
38
  )
39
39
  from nautobot.core.graphql.types import DateType, OptimizedNautobotObjectType
40
40
  from nautobot.core.graphql.utils import str_to_var_name
41
- from nautobot.core.testing import create_test_user, NautobotTestClient
41
+ from nautobot.core.testing import create_test_user, NautobotTestClient, TestCase
42
42
  from nautobot.dcim.choices import ConsolePortTypeChoices, InterfaceModeChoices, InterfaceTypeChoices, PortTypeChoices
43
43
  from nautobot.dcim.filters import DeviceFilterSet, LocationFilterSet
44
44
  from nautobot.dcim.graphql.types import DeviceType as DeviceTypeGraphQL
@@ -1453,9 +1453,7 @@ query {
1453
1453
  # Assert GraphQL returned properties match those expected
1454
1454
  self.assertEqual(console_server_port_entry["connected_console_port"], connected_console_port)
1455
1455
 
1456
- @skip(
1457
- "Works in isolation, fails as part of the overall test suite due to issue #446, also something is broken with content types"
1458
- )
1456
+ @skip("Works in isolation, fails as part of the overall test suite due to issue #446")
1459
1457
  @override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
1460
1458
  def test_query_relationship_associations(self):
1461
1459
  """Test queries involving relationship associations."""
@@ -2442,6 +2440,23 @@ query {
2442
2440
  expected_interfaces_first = {"ip_addresses": [{"primary_ip4_for": [{"id": str(self.device1.id)}]}]}
2443
2441
  self.assertEqual(result.data["device"]["interfaces"][0], expected_interfaces_first)
2444
2442
 
2443
+ @override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
2444
+ def test_query_optimizer_reverse_lookup(self):
2445
+ """
2446
+ Test query optimization in the case of a query mixing reverse and forward nested lookups.
2447
+
2448
+ See https://github.com/nautobot/nautobot/issues/7651.
2449
+ """
2450
+ query = """query { tenant_groups { name tenants { name } } }"""
2451
+ # Prewarm caches of Relationships and such to reduce variation in the number of queries below
2452
+ result = self.execute_query(query)
2453
+ self.assertNotIn("error", str(result))
2454
+ # Run it again and assert that the optimized query is run.
2455
+ # Before the fix for #7651 this would result in N+1 queries where N is the number of tenant-groups!
2456
+ with self.assertNumQueries(2):
2457
+ result = self.execute_query(query)
2458
+ self.assertNotIn("error", str(result))
2459
+
2445
2460
 
2446
2461
  class GraphQLTypeTestCase(UnitTestTestCase):
2447
2462
  def test_date_type(self):
@@ -798,7 +798,8 @@ class BulkEditTestCase(TransactionTestCase):
798
798
  "BulkEditObjects",
799
799
  content_type=self.role_ct.id,
800
800
  edit_all=False,
801
- filter_query_params={"per_page": 2},
801
+ filter_query_params={"per_page": [2]},
802
+ pk_list=pk_list,
802
803
  form_data={"pk": pk_list, "color": "aa1409"},
803
804
  username=self.user.username,
804
805
  )
@@ -818,7 +819,8 @@ class BulkEditTestCase(TransactionTestCase):
818
819
  "BulkEditObjects",
819
820
  content_type=self.role_ct.id,
820
821
  edit_all=False,
821
- filter_query_params={"sort": "name"},
822
+ pk_list=pk_list,
823
+ filter_query_params={"sort": ["name"]},
822
824
  form_data={"pk": pk_list, "color": "aa1409"},
823
825
  username=self.user.username,
824
826
  )
@@ -872,6 +874,7 @@ class BulkEditTestCase(TransactionTestCase):
872
874
  content_type=self.namespace_ct.id,
873
875
  edit_all=False,
874
876
  filter_query_params={},
877
+ pk_list=pk_list,
875
878
  form_data={
876
879
  "pk": pk_list,
877
880
  "description": "Example description for bulk edit",
@@ -969,15 +972,16 @@ class BulkEditTestCase(TransactionTestCase):
969
972
  "nautobot.core.jobs.bulk_actions",
970
973
  "BulkEditObjects",
971
974
  content_type=self.status_ct.id,
972
- edit_all=False,
973
- filter_query_params={"name__isw": "A", "sort": "name"},
975
+ edit_all=True,
976
+ filter_query_params={"name__isw": ["A"], "sort": ["name"]},
977
+ pk_list=[str(statuses[0].pk)],
974
978
  form_data={
975
979
  "pk": [str(statuses[0].pk)],
976
980
  "color": "aa1409",
977
981
  },
978
982
  username=self.user.username,
979
983
  )
980
- self._common_no_error_test_assertion(Status, job_result, 1, name__istartswith="A", color="aa1409")
984
+ self._common_no_error_test_assertion(Status, job_result, len(statuses), name__istartswith="A", color="aa1409")
981
985
  self.assertNotEqual(status_to_ignore.color, "aa1409")
982
986
 
983
987
  def test_bulk_edit_objects_passing_in_both_pk_list_and_edit_all(self):
@@ -994,7 +998,7 @@ class BulkEditTestCase(TransactionTestCase):
994
998
  "BulkEditObjects",
995
999
  content_type=self.status_ct.id,
996
1000
  edit_all=True,
997
- filter_query_params={"name__isw": "A"},
1001
+ filter_query_params={"name__isw": ["A"]},
998
1002
  # pk ignored if edit_all is True
999
1003
  form_data={
1000
1004
  "pk": [str(statuses[0].pk)],
@@ -1110,9 +1114,12 @@ class BulkDeleteTestCase(TransactionTestCase):
1110
1114
  job_result = create_job_result_and_run_job(
1111
1115
  "nautobot.core.jobs.bulk_actions",
1112
1116
  "BulkDeleteObjects",
1117
+ username=self.user.username,
1113
1118
  content_type=self.status_ct.id,
1119
+ delete_all=False,
1120
+ filter_query_params={},
1114
1121
  pk_list=statuses_to_delete,
1115
- username=self.user.username,
1122
+ saved_view_id=None,
1116
1123
  )
1117
1124
  self.assertJobResultStatus(job_result, JobResultStatusChoices.STATUS_FAILURE)
1118
1125
  job_log = JobLogEntry.objects.get(job_result=job_result, log_level=LogLevelChoices.LOG_ERROR)
@@ -1129,19 +1136,19 @@ class BulkDeleteTestCase(TransactionTestCase):
1129
1136
  obj_perm.save()
1130
1137
  obj_perm.users.add(self.user)
1131
1138
  obj_perm.object_types.add(ContentType.objects.get_for_model(Status))
1132
-
1133
1139
  job_result = create_job_result_and_run_job(
1134
1140
  "nautobot.core.jobs.bulk_actions",
1135
1141
  "BulkDeleteObjects",
1142
+ username=self.user.username,
1136
1143
  content_type=self.status_ct.id,
1144
+ delete_all=False,
1145
+ filter_query_params={},
1137
1146
  pk_list=statuses_to_delete,
1138
- username=self.user.username,
1147
+ saved_view_id=None,
1139
1148
  )
1140
1149
  self.assertJobResultStatus(job_result, JobResultStatusChoices.STATUS_FAILURE)
1141
1150
  error_log = JobLogEntry.objects.get(job_result=job_result, log_level=LogLevelChoices.LOG_ERROR)
1142
- self.assertEqual(
1143
- error_log.message, "You do not have permissions to delete some of the objects provided in `pk_list`."
1144
- )
1151
+ self.assertIn("Cannot delete some instances of model", error_log.message)
1145
1152
  self.assertEqual(Status.objects.filter(pk__in=statuses_to_delete).count(), len(statuses_to_delete))
1146
1153
 
1147
1154
  def test_bulk_delete_objects_select_all(self):
@@ -1155,11 +1162,12 @@ class BulkDeleteTestCase(TransactionTestCase):
1155
1162
  job_result = create_job_result_and_run_job(
1156
1163
  "nautobot.core.jobs.bulk_actions",
1157
1164
  "BulkDeleteObjects",
1165
+ username=self.user.username,
1158
1166
  content_type=ContentType.objects.get_for_model(Circuit).id,
1159
1167
  delete_all=True,
1160
- filter_query_params={"per_page": 10},
1168
+ filter_query_params={"per_page": [10]},
1161
1169
  pk_list=[],
1162
- username=self.user.username,
1170
+ saved_view_id=None,
1163
1171
  )
1164
1172
  self._common_no_error_test_assertion(Circuit, job_result)
1165
1173
 
@@ -1174,11 +1182,12 @@ class BulkDeleteTestCase(TransactionTestCase):
1174
1182
  job_result = create_job_result_and_run_job(
1175
1183
  "nautobot.core.jobs.bulk_actions",
1176
1184
  "BulkDeleteObjects",
1185
+ username=self.user.username,
1177
1186
  content_type=self.role_ct.id,
1178
1187
  delete_all=False,
1179
1188
  filter_query_params={},
1180
1189
  pk_list=roles_pks,
1181
- username=self.user.username,
1190
+ saved_view_id=None,
1182
1191
  )
1183
1192
  self._common_no_error_test_assertion(Role, job_result, pk__in=roles_pks)
1184
1193
  self.assertTrue(Role.objects.filter(name=roles_to_ignore.name).exists())
@@ -1192,10 +1201,12 @@ class BulkDeleteTestCase(TransactionTestCase):
1192
1201
  job_result = create_job_result_and_run_job(
1193
1202
  "nautobot.core.jobs.bulk_actions",
1194
1203
  "BulkDeleteObjects",
1204
+ username=self.user.username,
1195
1205
  content_type=self.status_ct.id,
1196
1206
  delete_all=True,
1197
- filter_query_params={"name__isw": "Example Status", "sort": "name"},
1198
- username=self.user.username,
1207
+ filter_query_params={"name__isw": ["Example Status"], "sort": ["name"]},
1208
+ pk_list=[],
1209
+ saved_view_id=None,
1199
1210
  )
1200
1211
  self._common_no_error_test_assertion(Status, job_result, name__istartswith="Example Status")
1201
1212
  self.assertTrue(Status.objects.filter(name=status_to_ignore.name).exists())
@@ -1211,11 +1222,12 @@ class BulkDeleteTestCase(TransactionTestCase):
1211
1222
  job_result = create_job_result_and_run_job(
1212
1223
  "nautobot.core.jobs.bulk_actions",
1213
1224
  "BulkDeleteObjects",
1225
+ username=self.user.username,
1214
1226
  content_type=self.role_ct.id,
1215
1227
  delete_all=False,
1216
- filter_query_params={"name__isw": "Example Status"},
1228
+ filter_query_params={"name__isw": ["Example Status"]},
1217
1229
  pk_list=roles_pks,
1218
- username=self.user.username,
1230
+ saved_view_id=None,
1219
1231
  )
1220
1232
  self._common_no_error_test_assertion(Role, job_result, pk__in=roles_pks)
1221
1233
  self.assertTrue(Role.objects.filter(name=roles_to_ignore.name).exists())
@@ -1228,10 +1240,11 @@ class BulkDeleteTestCase(TransactionTestCase):
1228
1240
  job_result = create_job_result_and_run_job(
1229
1241
  "nautobot.core.jobs.bulk_actions",
1230
1242
  "BulkDeleteObjects",
1243
+ username=self.user.username,
1231
1244
  content_type=self.status_ct.pk,
1232
1245
  delete_all=True,
1233
- filter_query_params={"name__isw": "Example Status", "sort": "name"},
1246
+ filter_query_params={"name__isw": ["Example Status"]},
1234
1247
  pk_list=[str(Status.objects.first().pk)],
1235
- username=self.user.username,
1248
+ saved_view_id=None,
1236
1249
  )
1237
1250
  self._common_no_error_test_assertion(Role, job_result, name__istartswith="Example Status")
@@ -4,10 +4,25 @@ from unittest.mock import patch
4
4
 
5
5
  from django.template import Context
6
6
  from django.test import RequestFactory
7
+ from django.urls import reverse
7
8
 
9
+ from nautobot.cloud.models import CloudNetwork, CloudResourceType, CloudService
10
+ from nautobot.cloud.tables import CloudServiceTable
11
+ from nautobot.cloud.views import CloudResourceTypeUIViewSet
8
12
  from nautobot.core.templatetags.helpers import HTML_NONE
9
13
  from nautobot.core.testing import TestCase
10
- from nautobot.core.ui.object_detail import BaseTextPanel, DataTablePanel, ObjectFieldsPanel, ObjectsTablePanel, Panel
14
+ from nautobot.core.ui.object_detail import (
15
+ _ObjectDetailAdvancedTab,
16
+ _ObjectDetailMainTab,
17
+ BaseTextPanel,
18
+ DataTablePanel,
19
+ DistinctViewTab,
20
+ ObjectDetailContent,
21
+ ObjectFieldsPanel,
22
+ ObjectsTablePanel,
23
+ Panel,
24
+ SectionChoices,
25
+ )
11
26
  from nautobot.dcim.models import DeviceRedundancyGroup
12
27
  from nautobot.dcim.tables.devices import DeviceTable
13
28
 
@@ -213,3 +228,162 @@ class ObjectsTablePanelTest(TestCase):
213
228
  panel.get_extra_context(context_data)
214
229
 
215
230
  self.assertIn("non-existent column `non_existent_column`", str(context.exception))
231
+
232
+
233
+ class ObjectDetailContentExtraTabsTest(TestCase):
234
+ """
235
+ Test suite for verifying the behavior of ObjectDetailContent when rendering default and extra tabs.
236
+ """
237
+
238
+ user_permissions = ["cloud.view_cloudresourcetype", "cloud.view_cloudservice", "cloud.view_cloudnetwork"]
239
+
240
+ def setUp(self):
241
+ super().setUp()
242
+ self.factory = RequestFactory()
243
+ self.request = self.factory.get("/")
244
+ self.request.user = self.user
245
+ self.default_tabs_id = ["main", "advanced", "contacts", "dynamic_groups", "object_metadata"]
246
+
247
+ def test_default_extra_tabs_exist(self):
248
+ """
249
+ Test the default set of tabs (main, advanced, contacts, dynamic_groups, object_metadata) is present.
250
+ """
251
+ content = ObjectDetailContent(
252
+ panels=[],
253
+ )
254
+
255
+ self.assertEqual(len(content.tabs), len(self.default_tabs_id))
256
+ tab_ids = [t.tab_id for t in content.tabs]
257
+ self.assertListEqual(tab_ids, self.default_tabs_id)
258
+
259
+ def test_extra_tabs_exist(self):
260
+ """
261
+ Test that extra tabs (e.g. "services") can be injected via the `extra_tabs` argument.
262
+ Validating that tab IDs are correctly combined when extra tabs are provided.
263
+ """
264
+ content = ObjectDetailContent(
265
+ panels=[],
266
+ extra_tabs=[
267
+ DistinctViewTab(
268
+ weight=1000,
269
+ tab_id="services",
270
+ label="Cloud Services",
271
+ url_name="cloud:cloudresourcetype_services",
272
+ related_object_attribute="cloud_services",
273
+ panels=(
274
+ ObjectsTablePanel(
275
+ section=SectionChoices.FULL_WIDTH,
276
+ weight=100,
277
+ table_class=CloudServiceTable,
278
+ table_filter="cloud_resource_type",
279
+ tab_id="services",
280
+ ),
281
+ ),
282
+ ),
283
+ ],
284
+ )
285
+
286
+ self.assertEqual(len(content.tabs), len(self.default_tabs_id) + 1)
287
+ tab_ids = [t.tab_id for t in content.tabs]
288
+ self.default_tabs_id.append("services")
289
+ self.assertListEqual(tab_ids, self.default_tabs_id)
290
+
291
+ def test_extra_tab_panel_context(self):
292
+ """
293
+ Confirming that extra tab panels produce the correct context,
294
+ including `url` and `body_content_table` populated with the expected related objects.
295
+ """
296
+ cloud_resource_type = CloudResourceType.objects.get_for_model(CloudNetwork)[0]
297
+ cloud_services = CloudService.objects.filter(cloud_resource_type=cloud_resource_type)
298
+
299
+ tab = DistinctViewTab(
300
+ weight=1000,
301
+ tab_id="services",
302
+ label="Cloud Services",
303
+ url_name="cloud:cloudresourcetype_services",
304
+ related_object_attribute="cloud_services",
305
+ panels=(
306
+ ObjectsTablePanel(
307
+ section=SectionChoices.FULL_WIDTH,
308
+ weight=100,
309
+ table_class=CloudServiceTable,
310
+ table_filter="cloud_resource_type",
311
+ tab_id="services",
312
+ ),
313
+ ),
314
+ )
315
+ context = {"request": self.request, "object": cloud_resource_type}
316
+ extra_context = tab.get_extra_context(context)
317
+ self.assertIn("url", extra_context)
318
+ self.assertTrue(extra_context["url"].endswith("/services/"))
319
+
320
+ panel = tab.panels[0]
321
+ panel_context = panel.get_extra_context(context)
322
+
323
+ self.assertIn("body_content_table", panel_context)
324
+ table = panel_context["body_content_table"]
325
+ self.assertQuerySetEqual(cloud_services, table.data)
326
+
327
+ def test_tab_conditional_rendering(self):
328
+ """
329
+ Assert default tabs render on the main detail view but not sub-views, while distinct-view-tabs do the reverse.
330
+ """
331
+ cloud_resource_type = CloudResourceType.objects.get_for_model(CloudNetwork)[0]
332
+ content = CloudResourceTypeUIViewSet.object_detail_content
333
+
334
+ # Main detail view renders all base tabs and no DistinctViewTabs
335
+ request = self.factory.get(cloud_resource_type.get_absolute_url())
336
+ request.user = self.user
337
+ context_data = {
338
+ "request": request,
339
+ "object": cloud_resource_type,
340
+ "settings": {},
341
+ "csrf_token": "",
342
+ "perms": [],
343
+ "created_by": self.request.user,
344
+ "last_updated_by": self.request.user,
345
+ "view_action": "retrieve",
346
+ "detail": True,
347
+ }
348
+ context = Context(context_data)
349
+ for tab in content.tabs:
350
+ if isinstance(tab, DistinctViewTab):
351
+ with patch.object(tab.panels[0], "render", wraps=tab.panels[0].render) as panel_render:
352
+ self.assertEqual(tab.render(context), "")
353
+ panel_render.assert_not_called()
354
+ elif isinstance(tab, (_ObjectDetailMainTab, _ObjectDetailAdvancedTab)): # other base tabs might not render
355
+ with patch.object(tab.panels[0], "render", wraps=tab.panels[0].render) as panel_render:
356
+ self.assertNotEqual(tab.render(context), "")
357
+ panel_render.assert_called()
358
+
359
+ # Distinct tab view renders its tab *only*
360
+ request = self.factory.get(reverse("cloud:cloudresourcetype_networks", kwargs={"pk": cloud_resource_type.pk}))
361
+ request.user = self.user
362
+ context_data["request"] = request
363
+ context_data["view_action"] = "networks"
364
+ context = Context(context_data)
365
+ for tab in content.tabs:
366
+ if isinstance(tab, DistinctViewTab) and tab.url_name == "cloud:cloudresourcetype_networks": # pylint: disable=no-member
367
+ with patch.object(tab.panels[0], "render", wraps=tab.panels[0].render) as panel_render:
368
+ self.assertNotEqual(tab.render(context), "")
369
+ panel_render.assert_called()
370
+ else:
371
+ with patch.object(tab.panels[0], "render", wraps=tab.panels[0].render) as panel_render:
372
+ self.assertEqual(tab.render(context), "")
373
+ panel_render.assert_not_called()
374
+
375
+ # Same, but for a different distinct view tab
376
+ request = self.factory.get(reverse("cloud:cloudresourcetype_services", kwargs={"pk": cloud_resource_type.pk}))
377
+ request.user = self.user
378
+ context_data["request"] = request
379
+ context_data["view_action"] = "services"
380
+ context = Context(context_data)
381
+ for tab in content.tabs:
382
+ if isinstance(tab, DistinctViewTab) and tab.url_name == "cloud:cloudresourcetype_services": # pylint: disable=no-member
383
+ with patch.object(tab.panels[0], "render", wraps=tab.panels[0].render) as panel_render:
384
+ self.assertNotEqual(tab.render(context), "")
385
+ panel_render.assert_called()
386
+ else:
387
+ with patch.object(tab.panels[0], "render", wraps=tab.panels[0].render) as panel_render:
388
+ self.assertEqual(tab.render(context), "")
389
+ panel_render.assert_not_called()
@@ -81,6 +81,41 @@ class NormalizeQueryDictTest(TestCase):
81
81
  {"name": ["Sample Status"], "content_types": ["dcim.device"]},
82
82
  )
83
83
 
84
+ self.assertDictEqual(
85
+ requests.normalize_querydict({"name": ["Sample Status"], "content_types": ["1"]}, form_class=StatusForm),
86
+ {"name": "Sample Status", "content_types": ["1"]},
87
+ )
88
+
89
+ self.assertDictEqual(
90
+ requests.normalize_querydict(
91
+ requests.convert_querydict_to_dict(QueryDict("name=Sample Status&content_types=1")),
92
+ form_class=StatusForm,
93
+ ),
94
+ {"name": "Sample Status", "content_types": ["1"]},
95
+ )
96
+
97
+
98
+ class ConvertQueryDictToDictTest(TestCase):
99
+ """
100
+ Validate convert_querydict_to_dict() utility function.
101
+ """
102
+
103
+ def test_convert_querydict_to_dict(self):
104
+ self.assertDictEqual(
105
+ requests.convert_querydict_to_dict(QueryDict("foo=1&bar=2&bar=3&baz=")),
106
+ {"foo": ["1"], "bar": ["2", "3"], "baz": [""]},
107
+ )
108
+
109
+ self.assertDictEqual(
110
+ requests.convert_querydict_to_dict(QueryDict("name=Sample Status&content_types=1")),
111
+ {"name": ["Sample Status"], "content_types": ["1"]},
112
+ )
113
+
114
+ self.assertDictEqual(
115
+ requests.convert_querydict_to_dict(QueryDict("name=Sample Status&content_types=dcim.device")),
116
+ {"name": ["Sample Status"], "content_types": ["dcim.device"]},
117
+ )
118
+
84
119
 
85
120
  class DeepMergeTest(TestCase):
86
121
  """
@@ -0,0 +1,43 @@
1
+ from itertools import combinations
2
+
3
+ from nautobot.core.testing import TestCase
4
+ from nautobot.core.views import generic
5
+ from nautobot.dcim.models import Location
6
+
7
+
8
+ class TestViewsGeneric(TestCase):
9
+ def test_mro_resolve_for_generic_views(self):
10
+ """
11
+ Test if all the generic views can be used extend view class.
12
+
13
+ Tries to detect if there is no MRO issues according to the #7829.
14
+ """
15
+ generic_views = [
16
+ generic.GenericView,
17
+ generic.ObjectListView,
18
+ generic.ObjectView,
19
+ generic.ObjectEditView,
20
+ generic.ObjectDeleteView,
21
+ generic.BulkCreateView,
22
+ generic.ObjectImportView,
23
+ generic.BulkImportView,
24
+ generic.BulkEditView,
25
+ generic.BulkRenameView,
26
+ generic.BulkDeleteView,
27
+ generic.ComponentCreateView,
28
+ generic.BulkComponentCreateView,
29
+ ]
30
+ generic_views_pairs = combinations(generic_views, 2)
31
+
32
+ for base_view, extension_view in generic_views_pairs:
33
+ with self.subTest("Test different class inheritance."):
34
+
35
+ class MyMixin(base_view):
36
+ pass
37
+
38
+ # Defining this class will fail if there is MRO issue
39
+ # pylint: disable=unused-variable
40
+ class MyView(MyMixin, extension_view):
41
+ queryset = Location.objects.all()
42
+
43
+ # pylint: enable=unused-variable