nautobot 2.1.7__py3-none-any.whl → 2.1.9__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 (338) hide show
  1. nautobot/apps/api.py +1 -2
  2. nautobot/apps/utils.py +4 -0
  3. nautobot/apps/views.py +2 -0
  4. nautobot/circuits/api/urls.py +1 -2
  5. nautobot/circuits/api/views.py +0 -12
  6. nautobot/circuits/tests/integration/test_relationships.py +0 -4
  7. nautobot/core/api/routers.py +25 -3
  8. nautobot/core/api/utils.py +4 -0
  9. nautobot/core/api/views.py +21 -15
  10. nautobot/core/celery/schedulers.py +13 -0
  11. nautobot/core/choices.py +0 -21
  12. nautobot/core/models/__init__.py +1 -1
  13. nautobot/core/models/tree_queries.py +29 -7
  14. nautobot/core/releases.py +1 -1
  15. nautobot/core/settings.py +9 -0
  16. nautobot/core/settings_funcs.py +0 -18
  17. nautobot/core/signals.py +5 -5
  18. nautobot/core/tasks.py +7 -3
  19. nautobot/core/templates/admin/base.html +23 -94
  20. nautobot/core/templates/generic/object_list.html +2 -0
  21. nautobot/core/templates/graphene/graphiql.html +18 -47
  22. nautobot/core/templates/inc/footer.html +5 -5
  23. nautobot/core/templates/inc/nav_menu.html +0 -7
  24. nautobot/core/templates/nautobot_config.py.j2 +6 -0
  25. nautobot/core/templates/rest_framework/api.html +12 -5
  26. nautobot/core/testing/mixins.py +13 -5
  27. nautobot/core/tests/integration/test_plugin_navbar.py +7 -21
  28. nautobot/core/tests/integration/test_view_authentication.py +67 -0
  29. nautobot/core/tests/runner.py +25 -2
  30. nautobot/core/tests/test_graphql.py +2 -14
  31. nautobot/core/tests/test_models.py +3 -3
  32. nautobot/core/tests/test_navigations.py +67 -10
  33. nautobot/core/tests/test_releases.py +9 -3
  34. nautobot/core/tests/test_views.py +23 -16
  35. nautobot/core/utils/lookup.py +124 -0
  36. nautobot/core/views/__init__.py +3 -7
  37. nautobot/core/views/generic.py +9 -0
  38. nautobot/dcim/api/urls.py +1 -2
  39. nautobot/dcim/api/views.py +1 -12
  40. nautobot/dcim/choices.py +56 -0
  41. nautobot/dcim/models/racks.py +1 -3
  42. nautobot/dcim/navigation.py +1 -1
  43. nautobot/dcim/templates/dcim/device/lldp_neighbors.html +67 -43
  44. nautobot/dcim/tests/test_api.py +3 -0
  45. nautobot/dcim/tests/test_filters.py +0 -28
  46. nautobot/dcim/views.py +5 -2
  47. nautobot/extras/api/urls.py +1 -2
  48. nautobot/extras/api/views.py +0 -10
  49. nautobot/extras/choices.py +14 -0
  50. nautobot/extras/models/customfields.py +93 -34
  51. nautobot/extras/models/groups.py +1 -1
  52. nautobot/extras/models/relationships.py +32 -19
  53. nautobot/extras/navigation.py +3 -2
  54. nautobot/extras/plugins/__init__.py +8 -0
  55. nautobot/extras/plugins/views.py +6 -9
  56. nautobot/extras/querysets.py +1 -1
  57. nautobot/extras/signals.py +12 -6
  58. nautobot/extras/templates/extras/customfield.html +22 -14
  59. nautobot/extras/templatetags/job_buttons.py +7 -0
  60. nautobot/extras/templatetags/plugins.py +5 -1
  61. nautobot/extras/tests/test_customfields.py +323 -287
  62. nautobot/extras/tests/test_dynamicgroups.py +1 -1
  63. nautobot/extras/tests/test_jobs.py +2 -2
  64. nautobot/extras/tests/test_plugins.py +41 -0
  65. nautobot/extras/tests/test_relationships.py +31 -14
  66. nautobot/extras/tests/test_views.py +124 -1
  67. nautobot/extras/utils.py +7 -3
  68. nautobot/extras/views.py +10 -10
  69. nautobot/ipam/api/urls.py +1 -2
  70. nautobot/ipam/api/views.py +6 -13
  71. nautobot/ipam/tables.py +0 -1
  72. nautobot/ipam/tests/test_graphql.py +2 -3
  73. nautobot/ipam/views.py +12 -10
  74. nautobot/project-static/css/base.css +1 -0
  75. nautobot/project-static/docs/404.html +30 -2
  76. nautobot/project-static/docs/apps/index.html +30 -2
  77. nautobot/project-static/docs/apps/nautobot-apps.html +30 -2
  78. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +30 -2
  79. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +30 -2
  80. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +410 -410
  81. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +30 -2
  82. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +386 -358
  83. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +30 -2
  84. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +30 -2
  85. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +30 -2
  86. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +30 -2
  87. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +45 -17
  88. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +30 -2
  89. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +30 -2
  90. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +30 -2
  91. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +759 -602
  92. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +30 -2
  93. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +30 -2
  94. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +30 -2
  95. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +528 -467
  96. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +205 -109
  97. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +30 -2
  98. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +1265 -785
  99. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +1827 -1746
  100. nautobot/project-static/docs/development/apps/api/configuration-view.html +30 -2
  101. nautobot/project-static/docs/development/apps/api/database-backend-config.html +30 -2
  102. nautobot/project-static/docs/development/apps/api/models/django-admin.html +30 -2
  103. nautobot/project-static/docs/development/apps/api/models/global-search.html +30 -2
  104. nautobot/project-static/docs/development/apps/api/models/graphql.html +30 -2
  105. nautobot/project-static/docs/development/apps/api/models/index.html +30 -2
  106. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +31 -3
  107. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +30 -2
  108. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +30 -2
  109. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +30 -2
  110. nautobot/project-static/docs/development/apps/api/platform-features/index.html +30 -2
  111. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +30 -2
  112. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +30 -2
  113. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +30 -2
  114. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +30 -2
  115. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +30 -2
  116. nautobot/project-static/docs/development/apps/api/prometheus.html +30 -2
  117. nautobot/project-static/docs/development/apps/api/setup.html +30 -2
  118. nautobot/project-static/docs/development/apps/api/testing.html +33 -5
  119. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +30 -2
  120. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +30 -2
  121. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +30 -2
  122. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +33 -5
  123. nautobot/project-static/docs/development/apps/api/ui-extensions/object-detail-views.html +13 -5559
  124. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +5594 -0
  125. nautobot/project-static/docs/development/apps/api/ui-extensions/tabs.html +3 -3
  126. nautobot/project-static/docs/development/apps/api/views/base-template.html +30 -2
  127. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +44 -11
  128. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +47 -14
  129. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +30 -2
  130. nautobot/project-static/docs/development/apps/api/views/index.html +30 -2
  131. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +30 -2
  132. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +30 -2
  133. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +30 -2
  134. nautobot/project-static/docs/development/apps/api/views/notes.html +30 -2
  135. nautobot/project-static/docs/development/apps/api/views/rest-api.html +30 -2
  136. nautobot/project-static/docs/development/apps/api/views/urls.html +30 -2
  137. nautobot/project-static/docs/development/apps/index.html +30 -2
  138. nautobot/project-static/docs/development/apps/migration/code-updates.html +30 -2
  139. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +30 -2
  140. nautobot/project-static/docs/development/apps/migration/from-v1.html +30 -2
  141. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +30 -2
  142. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +30 -2
  143. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +30 -2
  144. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +30 -2
  145. nautobot/project-static/docs/development/apps/porting-from-netbox.html +30 -2
  146. nautobot/project-static/docs/development/core/application-registry.html +30 -2
  147. nautobot/project-static/docs/development/core/best-practices.html +33 -5
  148. nautobot/project-static/docs/development/core/bootstrap-ui.html +30 -2
  149. nautobot/project-static/docs/development/core/caching.html +5481 -0
  150. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +30 -2
  151. nautobot/project-static/docs/development/core/extending-models.html +33 -5
  152. nautobot/project-static/docs/development/core/generic-views.html +30 -2
  153. nautobot/project-static/docs/development/core/getting-started.html +49 -12
  154. nautobot/project-static/docs/development/core/homepage.html +30 -2
  155. nautobot/project-static/docs/development/core/index.html +30 -2
  156. nautobot/project-static/docs/development/core/model-features.html +30 -2
  157. nautobot/project-static/docs/development/core/natural-keys.html +30 -2
  158. nautobot/project-static/docs/development/core/navigation-menu.html +30 -2
  159. nautobot/project-static/docs/development/core/release-checklist.html +30 -2
  160. nautobot/project-static/docs/development/core/role-internals.html +30 -2
  161. nautobot/project-static/docs/development/core/style-guide.html +30 -2
  162. nautobot/project-static/docs/development/core/templates.html +30 -2
  163. nautobot/project-static/docs/development/core/testing.html +30 -2
  164. nautobot/project-static/docs/development/core/user-preferences.html +30 -2
  165. nautobot/project-static/docs/development/index.html +30 -2
  166. nautobot/project-static/docs/development/jobs/index.html +30 -2
  167. nautobot/project-static/docs/development/jobs/migration/from-v1.html +30 -2
  168. nautobot/project-static/docs/index.html +30 -2
  169. nautobot/project-static/docs/objects.inv +0 -0
  170. nautobot/project-static/docs/release-notes/index.html +30 -2
  171. nautobot/project-static/docs/release-notes/version-1.0.html +30 -2
  172. nautobot/project-static/docs/release-notes/version-1.1.html +30 -2
  173. nautobot/project-static/docs/release-notes/version-1.2.html +30 -2
  174. nautobot/project-static/docs/release-notes/version-1.3.html +30 -2
  175. nautobot/project-static/docs/release-notes/version-1.4.html +31 -3
  176. nautobot/project-static/docs/release-notes/version-1.5.html +30 -2
  177. nautobot/project-static/docs/release-notes/version-1.6.html +573 -134
  178. nautobot/project-static/docs/release-notes/version-2.0.html +30 -2
  179. nautobot/project-static/docs/release-notes/version-2.1.html +539 -170
  180. nautobot/project-static/docs/search/search_index.json +1 -1
  181. nautobot/project-static/docs/sitemap.xml +250 -240
  182. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  183. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +30 -2
  184. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +30 -2
  185. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +30 -2
  186. nautobot/project-static/docs/user-guide/administration/configuration/index.html +30 -2
  187. nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +49 -2
  188. nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +30 -2
  189. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +30 -2
  190. nautobot/project-static/docs/user-guide/administration/guides/caching.html +30 -2
  191. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +30 -2
  192. nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +30 -2
  193. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +30 -2
  194. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +30 -2
  195. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +30 -2
  196. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +30 -2
  197. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +30 -2
  198. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +30 -2
  199. nautobot/project-static/docs/user-guide/administration/installation/docker.html +37 -5
  200. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +30 -2
  201. nautobot/project-static/docs/user-guide/administration/installation/health-checks.html +6019 -0
  202. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +30 -2
  203. nautobot/project-static/docs/user-guide/administration/installation/index.html +30 -2
  204. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +30 -2
  205. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +30 -2
  206. nautobot/project-static/docs/user-guide/administration/installation/selinux-troubleshooting.html +33 -5
  207. nautobot/project-static/docs/user-guide/administration/installation/services.html +30 -2
  208. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +30 -2
  209. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +30 -2
  210. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +30 -2
  211. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +30 -2
  212. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +30 -2
  213. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +30 -2
  214. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +30 -2
  215. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +30 -2
  216. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +30 -2
  217. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +30 -2
  218. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +30 -2
  219. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +30 -2
  220. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +30 -2
  221. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +30 -2
  222. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +30 -2
  223. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +30 -2
  224. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +30 -2
  225. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +30 -2
  226. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +30 -2
  227. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +30 -2
  228. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +30 -2
  229. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +30 -2
  230. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +30 -2
  231. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +30 -2
  232. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +30 -2
  233. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +30 -2
  234. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +30 -2
  235. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +30 -2
  236. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +30 -2
  237. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +30 -2
  238. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +30 -2
  239. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +30 -2
  240. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +30 -2
  241. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +30 -2
  242. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +30 -2
  243. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +30 -2
  244. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +30 -2
  245. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +30 -2
  246. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +30 -2
  247. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +30 -2
  248. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +30 -2
  249. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +30 -2
  250. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +30 -2
  251. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +30 -2
  252. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +30 -2
  253. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +30 -2
  254. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +30 -2
  255. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +30 -2
  256. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +30 -2
  257. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +30 -2
  258. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +30 -2
  259. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +30 -2
  260. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +30 -2
  261. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +30 -2
  262. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +30 -2
  263. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +30 -2
  264. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +30 -2
  265. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +30 -2
  266. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +30 -2
  267. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +30 -2
  268. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +30 -2
  269. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +30 -2
  270. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +30 -2
  271. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +30 -2
  272. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +30 -2
  273. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +30 -2
  274. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +30 -2
  275. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +30 -2
  276. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +30 -2
  277. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +33 -5
  278. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +30 -2
  279. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +30 -2
  280. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +30 -2
  281. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +30 -2
  282. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +30 -2
  283. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +30 -2
  284. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +30 -2
  285. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +30 -2
  286. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +30 -2
  287. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +30 -2
  288. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +30 -2
  289. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +30 -2
  290. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +30 -2
  291. nautobot/project-static/docs/user-guide/index.html +30 -2
  292. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +30 -2
  293. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +30 -2
  294. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +111 -15
  295. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +30 -2
  296. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +30 -2
  297. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +30 -2
  298. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +30 -2
  299. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +30 -2
  300. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +30 -2
  301. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +30 -2
  302. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +30 -2
  303. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +30 -2
  304. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +30 -2
  305. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +30 -2
  306. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +30 -2
  307. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +30 -2
  308. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +30 -2
  309. nautobot/project-static/docs/user-guide/platform-functionality/note.html +30 -2
  310. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +30 -2
  311. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +30 -2
  312. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +30 -2
  313. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +30 -2
  314. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +30 -2
  315. nautobot/project-static/docs/user-guide/platform-functionality/role.html +30 -2
  316. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +30 -2
  317. nautobot/project-static/docs/user-guide/platform-functionality/status.html +30 -2
  318. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +30 -2
  319. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +30 -2
  320. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +30 -2
  321. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +30 -2
  322. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +30 -2
  323. nautobot/tenancy/api/urls.py +1 -2
  324. nautobot/tenancy/api/views.py +0 -12
  325. nautobot/tenancy/navigation.py +1 -1
  326. nautobot/tenancy/tests/test_filters.py +0 -168
  327. nautobot/users/api/urls.py +1 -2
  328. nautobot/users/api/views.py +2 -65
  329. nautobot/users/views.py +8 -8
  330. nautobot/virtualization/api/urls.py +1 -2
  331. nautobot/virtualization/api/views.py +0 -12
  332. nautobot/virtualization/tests/test_filters.py +0 -28
  333. {nautobot-2.1.7.dist-info → nautobot-2.1.9.dist-info}/METADATA +2 -2
  334. {nautobot-2.1.7.dist-info → nautobot-2.1.9.dist-info}/RECORD +338 -334
  335. {nautobot-2.1.7.dist-info → nautobot-2.1.9.dist-info}/LICENSE.txt +0 -0
  336. {nautobot-2.1.7.dist-info → nautobot-2.1.9.dist-info}/NOTICE +0 -0
  337. {nautobot-2.1.7.dist-info → nautobot-2.1.9.dist-info}/WHEEL +0 -0
  338. {nautobot-2.1.7.dist-info → nautobot-2.1.9.dist-info}/entry_points.txt +0 -0
@@ -52,19 +52,6 @@ class TenantGroupTestCase(FilterTestCases.NameOnlyFilterTestCase):
52
52
  TenantGroup.objects.filter(children__in=[child_groups[0], child_groups[1]]).distinct(),
53
53
  )
54
54
 
55
- def test_has_children(self):
56
- """Test the `has_children` filter."""
57
- params = {"has_children": True}
58
- self.assertQuerysetEqualAndNotEmpty(
59
- self.filterset(params, self.queryset).qs,
60
- TenantGroup.objects.filter(children__isnull=False).distinct(),
61
- )
62
- params = {"has_children": False}
63
- self.assertQuerysetEqualAndNotEmpty(
64
- self.filterset(params, self.queryset).qs,
65
- TenantGroup.objects.filter(children__isnull=True).distinct(),
66
- )
67
-
68
55
  def test_tenants(self):
69
56
  """Test the `tenants` filter."""
70
57
  tenants = Tenant.objects.filter(tenant_group__isnull=False)
@@ -74,19 +61,6 @@ class TenantGroupTestCase(FilterTestCases.NameOnlyFilterTestCase):
74
61
  TenantGroup.objects.filter(tenants__in=[tenants[0], tenants[1]]).distinct(),
75
62
  )
76
63
 
77
- def test_has_tenants(self):
78
- """Test the `has_tenants` filter."""
79
- params = {"has_tenants": True}
80
- self.assertQuerysetEqualAndNotEmpty(
81
- self.filterset(params, self.queryset).qs,
82
- TenantGroup.objects.filter(tenants__isnull=False).distinct(),
83
- )
84
- params = {"has_tenants": False}
85
- self.assertQuerysetEqualAndNotEmpty(
86
- self.filterset(params, self.queryset).qs,
87
- TenantGroup.objects.filter(tenants__isnull=True).distinct(),
88
- )
89
-
90
64
 
91
65
  class TenantTestCase(FilterTestCases.NameOnlyFilterTestCase):
92
66
  queryset = Tenant.objects.all()
@@ -160,19 +134,6 @@ class TenantTestCase(FilterTestCases.NameOnlyFilterTestCase):
160
134
  self.queryset.filter(circuits__in=circuits).distinct(),
161
135
  )
162
136
 
163
- def test_has_circuits(self):
164
- """Test the `has_circuits` filter."""
165
- params = {"has_circuits": True}
166
- self.assertQuerysetEqualAndNotEmpty(
167
- self.filterset(params, self.queryset).qs,
168
- self.queryset.filter(circuits__isnull=False).distinct(),
169
- )
170
- params = {"has_circuits": False}
171
- self.assertQuerysetEqualAndNotEmpty(
172
- self.filterset(params, self.queryset).qs,
173
- self.queryset.filter(circuits__isnull=True).distinct(),
174
- )
175
-
176
137
  def test_clusters(self):
177
138
  """Test the `clusters` filter."""
178
139
  clusters = list(Cluster.objects.filter(tenant__isnull=False))[:2]
@@ -182,19 +143,6 @@ class TenantTestCase(FilterTestCases.NameOnlyFilterTestCase):
182
143
  self.queryset.filter(clusters__in=clusters).distinct(),
183
144
  )
184
145
 
185
- def test_has_clusters(self):
186
- """Test the `has_clusters` filter."""
187
- params = {"has_clusters": True}
188
- self.assertQuerysetEqualAndNotEmpty(
189
- self.filterset(params, self.queryset).qs,
190
- self.queryset.filter(clusters__isnull=False).distinct(),
191
- )
192
- params = {"has_clusters": False}
193
- self.assertQuerysetEqualAndNotEmpty(
194
- self.filterset(params, self.queryset).qs,
195
- self.queryset.filter(clusters__isnull=True).distinct(),
196
- )
197
-
198
146
  def test_devices(self):
199
147
  """Test the `devices` filter."""
200
148
  params = {"devices": [self.devices[0].pk, self.devices[1].name]}
@@ -203,19 +151,6 @@ class TenantTestCase(FilterTestCases.NameOnlyFilterTestCase):
203
151
  self.queryset.filter(devices__in=self.devices).distinct(),
204
152
  )
205
153
 
206
- def test_has_devices(self):
207
- """Test the `has_devices` filter."""
208
- params = {"has_devices": True}
209
- self.assertQuerysetEqualAndNotEmpty(
210
- self.filterset(params, self.queryset).qs,
211
- self.queryset.filter(devices__isnull=False).distinct(),
212
- )
213
- params = {"has_devices": False}
214
- self.assertQuerysetEqualAndNotEmpty(
215
- self.filterset(params, self.queryset).qs,
216
- self.queryset.filter(devices__isnull=True).distinct(),
217
- )
218
-
219
154
  def test_tenant_group(self):
220
155
  groups = list(TenantGroup.objects.filter(tenants__isnull=False))[:2]
221
156
  groups_including_children = []
@@ -241,19 +176,6 @@ class TenantTestCase(FilterTestCases.NameOnlyFilterTestCase):
241
176
  self.queryset.filter(ip_addresses__in=ip_addresses).distinct(),
242
177
  )
243
178
 
244
- def test_has_ip_addresses(self):
245
- """Test the `has_ip_addresses` filter."""
246
- params = {"has_ip_addresses": True}
247
- self.assertQuerysetEqualAndNotEmpty(
248
- self.filterset(params, self.queryset).qs,
249
- self.queryset.filter(ip_addresses__isnull=False).distinct(),
250
- )
251
- params = {"has_ip_addresses": False}
252
- self.assertQuerysetEqualAndNotEmpty(
253
- self.filterset(params, self.queryset).qs,
254
- self.queryset.filter(ip_addresses__isnull=True).distinct(),
255
- )
256
-
257
179
  def test_locations(self):
258
180
  params = {"locations": [self.locations[0].pk, self.locations[1].name]}
259
181
  self.assertQuerysetEqualAndNotEmpty(
@@ -261,18 +183,6 @@ class TenantTestCase(FilterTestCases.NameOnlyFilterTestCase):
261
183
  self.queryset.filter(locations__in=[self.locations[0], self.locations[1]]).distinct(),
262
184
  )
263
185
 
264
- def test_has_locations(self):
265
- params = {"has_locations": True}
266
- self.assertQuerysetEqualAndNotEmpty(
267
- self.filterset(params, self.queryset).qs,
268
- self.queryset.filter(locations__isnull=False).distinct(),
269
- )
270
- params = {"has_locations": False}
271
- self.assertQuerysetEqualAndNotEmpty(
272
- self.filterset(params, self.queryset).qs,
273
- self.queryset.filter(locations__isnull=True).distinct(),
274
- )
275
-
276
186
  def test_prefixes(self):
277
187
  """Test the `prefixes` filter."""
278
188
  prefixes = list(Prefix.objects.filter(tenant__isnull=False))[:2]
@@ -282,19 +192,6 @@ class TenantTestCase(FilterTestCases.NameOnlyFilterTestCase):
282
192
  self.queryset.filter(prefixes__in=prefixes).distinct(),
283
193
  )
284
194
 
285
- def test_has_prefixes(self):
286
- """Test the `has_prefixes` filter."""
287
- params = {"has_prefixes": True}
288
- self.assertQuerysetEqualAndNotEmpty(
289
- self.filterset(params, self.queryset).qs,
290
- self.queryset.filter(prefixes__isnull=False).distinct(),
291
- )
292
- params = {"has_prefixes": False}
293
- self.assertQuerysetEqualAndNotEmpty(
294
- self.filterset(params, self.queryset).qs,
295
- self.queryset.filter(prefixes__isnull=True).distinct(),
296
- )
297
-
298
195
  def test_rack_reservations(self):
299
196
  """Test the `rack_reservations` filter."""
300
197
  rack_reservations = list(RackReservation.objects.filter(tenant__isnull=False))[:2]
@@ -304,19 +201,6 @@ class TenantTestCase(FilterTestCases.NameOnlyFilterTestCase):
304
201
  self.queryset.filter(rack_reservations__in=rack_reservations).distinct(),
305
202
  )
306
203
 
307
- def test_has_rack_reservations(self):
308
- """Test the `has_rack_reservations` filter."""
309
- params = {"has_rack_reservations": True}
310
- self.assertQuerysetEqualAndNotEmpty(
311
- self.filterset(params, self.queryset).qs,
312
- self.queryset.filter(rack_reservations__isnull=False).distinct(),
313
- )
314
- params = {"has_rack_reservations": False}
315
- self.assertQuerysetEqualAndNotEmpty(
316
- self.filterset(params, self.queryset).qs,
317
- self.queryset.filter(rack_reservations__isnull=True).distinct(),
318
- )
319
-
320
204
  def test_racks(self):
321
205
  """Test the `racks` filter."""
322
206
  racks = list(Rack.objects.filter(tenant__isnull=False))[:2]
@@ -326,19 +210,6 @@ class TenantTestCase(FilterTestCases.NameOnlyFilterTestCase):
326
210
  self.queryset.filter(racks__in=racks).distinct(),
327
211
  )
328
212
 
329
- def test_has_racks(self):
330
- """Test the `has_racks` filter."""
331
- params = {"has_racks": True}
332
- self.assertQuerysetEqualAndNotEmpty(
333
- self.filterset(params, self.queryset).qs,
334
- self.queryset.filter(racks__isnull=False).distinct(),
335
- )
336
- params = {"has_racks": False}
337
- self.assertQuerysetEqualAndNotEmpty(
338
- self.filterset(params, self.queryset).qs,
339
- self.queryset.filter(racks__isnull=True).distinct(),
340
- )
341
-
342
213
  def test_route_targets(self):
343
214
  """Test the `route_targets` filter."""
344
215
  route_targets = list(RouteTarget.objects.filter(tenant__isnull=False))[:2]
@@ -348,19 +219,6 @@ class TenantTestCase(FilterTestCases.NameOnlyFilterTestCase):
348
219
  self.queryset.filter(route_targets__in=route_targets).distinct(),
349
220
  )
350
221
 
351
- def test_has_route_targets(self):
352
- """Test the `has_route_targets` filter."""
353
- params = {"has_route_targets": True}
354
- self.assertQuerysetEqualAndNotEmpty(
355
- self.filterset(params, self.queryset).qs,
356
- self.queryset.filter(route_targets__isnull=False).distinct(),
357
- )
358
- params = {"has_route_targets": False}
359
- self.assertQuerysetEqualAndNotEmpty(
360
- self.filterset(params, self.queryset).qs,
361
- self.queryset.filter(route_targets__isnull=True).distinct(),
362
- )
363
-
364
222
  def test_virtual_machines(self):
365
223
  """Test the `virtual_machines` filter."""
366
224
  virtual_machines = list(VirtualMachine.objects.filter(tenant__isnull=False))[:2]
@@ -370,19 +228,6 @@ class TenantTestCase(FilterTestCases.NameOnlyFilterTestCase):
370
228
  self.queryset.filter(virtual_machines__in=virtual_machines).distinct(),
371
229
  )
372
230
 
373
- def test_has_virtual_machines(self):
374
- """Test the `has_virtual_machines` filter."""
375
- params = {"has_virtual_machines": True}
376
- self.assertQuerysetEqualAndNotEmpty(
377
- self.filterset(params, self.queryset).qs,
378
- self.queryset.filter(virtual_machines__isnull=False).distinct(),
379
- )
380
- params = {"has_virtual_machines": False}
381
- self.assertQuerysetEqualAndNotEmpty(
382
- self.filterset(params, self.queryset).qs,
383
- self.queryset.filter(virtual_machines__isnull=True).distinct(),
384
- )
385
-
386
231
  def test_vlans(self):
387
232
  """Test the `vlans` filter."""
388
233
  vlans = list(VLAN.objects.filter(tenant__isnull=False))[:2]
@@ -392,19 +237,6 @@ class TenantTestCase(FilterTestCases.NameOnlyFilterTestCase):
392
237
  self.queryset.filter(vlans__in=vlans).distinct(),
393
238
  )
394
239
 
395
- def test_has_vlans(self):
396
- """Test the `has_vlans` filter."""
397
- params = {"has_vlans": True}
398
- self.assertQuerysetEqualAndNotEmpty(
399
- self.filterset(params, self.queryset).qs,
400
- self.queryset.filter(vlans__isnull=False).distinct(),
401
- )
402
- params = {"has_vlans": False}
403
- self.assertQuerysetEqualAndNotEmpty(
404
- self.filterset(params, self.queryset).qs,
405
- self.queryset.filter(vlans__isnull=True).distinct(),
406
- )
407
-
408
240
  def test_vrfs(self):
409
241
  """Test the `vrfs` filter."""
410
242
  vrfs = list(VRF.objects.filter(tenant__isnull=False))[:2]
@@ -2,8 +2,7 @@ from nautobot.core.api.routers import OrderedDefaultRouter
2
2
 
3
3
  from . import views
4
4
 
5
- router = OrderedDefaultRouter()
6
- router.APIRootView = views.UsersRootView
5
+ router = OrderedDefaultRouter(view_name="Users")
7
6
 
8
7
  # Users and groups
9
8
  router.register("users", views.UserViewSet)
@@ -1,14 +1,10 @@
1
- from django.contrib.auth import get_user_model, login, logout
1
+ from django.contrib.auth import get_user_model
2
2
  from django.contrib.auth.models import Group
3
3
  from django.db.models import Count
4
- from django.utils.decorators import method_decorator
5
- from django.views.decorators.csrf import ensure_csrf_cookie
6
4
  from drf_spectacular.utils import extend_schema, extend_schema_view, OpenApiTypes
7
5
  from rest_framework.authentication import BasicAuthentication
8
- from rest_framework.decorators import action
9
- from rest_framework.permissions import AllowAny, IsAuthenticated
6
+ from rest_framework.permissions import IsAuthenticated
10
7
  from rest_framework.response import Response
11
- from rest_framework.routers import APIRootView
12
8
  from rest_framework.viewsets import ViewSet
13
9
 
14
10
  from nautobot.core.api.serializers import BulkOperationIntegerIDSerializer
@@ -20,16 +16,6 @@ from nautobot.users.models import ObjectPermission, Token
20
16
 
21
17
  from . import serializers
22
18
 
23
-
24
- class UsersRootView(APIRootView):
25
- """
26
- Users API root view
27
- """
28
-
29
- def get_view_name(self):
30
- return "Users"
31
-
32
-
33
19
  #
34
20
  # Users and groups
35
21
  #
@@ -40,40 +26,6 @@ class UserViewSet(ModelViewSet):
40
26
  serializer_class = serializers.UserSerializer
41
27
  filterset_class = filters.UserFilterSet
42
28
 
43
- @action(methods=["GET"], detail=False, url_path="my-profile")
44
- def my_profile(self, request):
45
- serializer = self.serializer_class(instance=request.user, context={"request": request})
46
- return Response(serializer.data)
47
-
48
- @method_decorator(ensure_csrf_cookie)
49
- @action(methods=["GET"], detail=False, permission_classes=[AllowAny])
50
- def session(self, request):
51
- from django.conf import settings as django_settings
52
- from django.urls import reverse
53
- from social_django.context_processors import backends
54
-
55
- from nautobot.core.settings_funcs import sso_auth_enabled
56
-
57
- serializer = self.serializer_class(instance=request.user, context={"request": request})
58
-
59
- _backends = []
60
- sso_enabled = sso_auth_enabled(django_settings.AUTHENTICATION_BACKENDS)
61
-
62
- social_auth_backends = backends(request)["backends"]
63
- if sso_enabled:
64
- for backend in social_auth_backends["backends"]:
65
- _backends.append(reverse("social:begin", kwargs={"backend": backend}))
66
-
67
- resp = {
68
- "user": serializer.data,
69
- "logged_in": request.user.is_authenticated,
70
- "sso_enabled": sso_enabled,
71
- "sso_user": (len(social_auth_backends["associated"]) > 0),
72
- "backends": _backends,
73
- }
74
-
75
- return Response(resp)
76
-
77
29
 
78
30
  @extend_schema_view(
79
31
  bulk_destroy=extend_schema(request=BulkOperationIntegerIDSerializer(many=True)),
@@ -101,21 +53,6 @@ class TokenViewSet(ModelViewSet):
101
53
  classes = super().authentication_classes
102
54
  return [*classes, BasicAuthentication]
103
55
 
104
- # TODO(timizuo): Move authenticate and logout to its own view;
105
- # as it is not proper to be on this.
106
- @action(methods=["POST"], detail=False, permission_classes=[AllowAny])
107
- def authenticate(self, request):
108
- serializer = serializers.UserLoginSerializer(data=request.data, context=self.get_serializer_context())
109
- serializer.is_valid(raise_exception=True)
110
- user = serializer.validated_data["user"]
111
- login(request, user=user)
112
- return Response(status=200)
113
-
114
- @action(methods=["GET"], detail=False)
115
- def logout(self, request):
116
- logout(request)
117
- return Response(status=200)
118
-
119
56
  def get_queryset(self):
120
57
  """
121
58
  Limit users to their own Tokens.
nautobot/users/views.py CHANGED
@@ -7,7 +7,6 @@ from django.contrib.auth import (
7
7
  logout as auth_logout,
8
8
  update_session_auth_hash,
9
9
  )
10
- from django.contrib.auth.mixins import LoginRequiredMixin
11
10
  from django.http import HttpResponseForbidden, HttpResponseRedirect
12
11
  from django.shortcuts import get_object_or_404, redirect, render
13
12
  from django.urls import reverse
@@ -18,6 +17,7 @@ from django.views.decorators.debug import sensitive_post_parameters
18
17
  from django.views.generic import View
19
18
 
20
19
  from nautobot.core.forms import ConfirmationForm
20
+ from nautobot.core.views.generic import GenericView
21
21
 
22
22
  from .forms import AdvancedProfileSettingsForm, LoginForm, PasswordChangeForm, TokenForm
23
23
  from .models import Token
@@ -118,7 +118,7 @@ def is_django_auth_user(request):
118
118
  return request.session.get(BACKEND_SESSION_KEY, None) == "nautobot.core.authentication.ObjectPermissionBackend"
119
119
 
120
120
 
121
- class ProfileView(LoginRequiredMixin, View):
121
+ class ProfileView(GenericView):
122
122
  template_name = "users/profile.html"
123
123
 
124
124
  def get(self, request):
@@ -132,7 +132,7 @@ class ProfileView(LoginRequiredMixin, View):
132
132
  )
133
133
 
134
134
 
135
- class UserConfigView(LoginRequiredMixin, View):
135
+ class UserConfigView(GenericView):
136
136
  template_name = "users/preferences.html"
137
137
 
138
138
  def get(self, request):
@@ -160,7 +160,7 @@ class UserConfigView(LoginRequiredMixin, View):
160
160
  return redirect("user:preferences")
161
161
 
162
162
 
163
- class ChangePasswordView(LoginRequiredMixin, View):
163
+ class ChangePasswordView(GenericView):
164
164
  template_name = "users/change_password.html"
165
165
 
166
166
  RESTRICTED_NOTICE = "Remotely authenticated user credentials cannot be changed within Nautobot."
@@ -218,7 +218,7 @@ class ChangePasswordView(LoginRequiredMixin, View):
218
218
  #
219
219
 
220
220
 
221
- class TokenListView(LoginRequiredMixin, View):
221
+ class TokenListView(GenericView):
222
222
  def get(self, request):
223
223
  tokens = Token.objects.filter(user=request.user)
224
224
 
@@ -233,7 +233,7 @@ class TokenListView(LoginRequiredMixin, View):
233
233
  )
234
234
 
235
235
 
236
- class TokenEditView(LoginRequiredMixin, View):
236
+ class TokenEditView(GenericView):
237
237
  def get(self, request, pk=None):
238
238
  if pk is not None:
239
239
  if not request.user.has_perm("users.change_token"):
@@ -292,7 +292,7 @@ class TokenEditView(LoginRequiredMixin, View):
292
292
  )
293
293
 
294
294
 
295
- class TokenDeleteView(LoginRequiredMixin, View):
295
+ class TokenDeleteView(GenericView):
296
296
  def get(self, request, pk):
297
297
  token = get_object_or_404(Token.objects.filter(user=request.user), pk=pk)
298
298
  initial_data = {
@@ -336,7 +336,7 @@ class TokenDeleteView(LoginRequiredMixin, View):
336
336
  #
337
337
 
338
338
 
339
- class AdvancedProfileSettingsEditView(LoginRequiredMixin, View):
339
+ class AdvancedProfileSettingsEditView(GenericView):
340
340
  template_name = "users/advanced_settings_edit.html"
341
341
 
342
342
  def get(self, request):
@@ -2,8 +2,7 @@ from nautobot.core.api.routers import OrderedDefaultRouter
2
2
 
3
3
  from . import views
4
4
 
5
- router = OrderedDefaultRouter()
6
- router.APIRootView = views.VirtualizationRootView
5
+ router = OrderedDefaultRouter(view_name="Virtualization")
7
6
 
8
7
  # Clusters
9
8
  router.register("cluster-types", views.ClusterTypeViewSet)
@@ -1,5 +1,3 @@
1
- from rest_framework.routers import APIRootView
2
-
3
1
  from nautobot.core.models.querysets import count_related
4
2
  from nautobot.dcim.models import Device
5
3
  from nautobot.extras.api.views import (
@@ -19,16 +17,6 @@ from nautobot.virtualization.models import (
19
17
 
20
18
  from . import serializers
21
19
 
22
-
23
- class VirtualizationRootView(APIRootView):
24
- """
25
- Virtualization API root view
26
- """
27
-
28
- def get_view_name(self):
29
- return "Virtualization"
30
-
31
-
32
20
  #
33
21
  # Clusters
34
22
  #
@@ -49,13 +49,6 @@ class ClusterTypeTestCase(FilterTestCases.NameOnlyFilterTestCase):
49
49
  params = {"clusters": [self.clusters[0].pk, self.clusters[1].name]}
50
50
  self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
51
51
 
52
- with self.subTest("Has Clusters"):
53
- params = {"has_clusters": True}
54
- self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
55
-
56
- params = {"has_clusters": False}
57
- self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
58
-
59
52
 
60
53
  class ClusterGroupTestCase(FilterTestCases.NameOnlyFilterTestCase):
61
54
  queryset = ClusterGroup.objects.all()
@@ -89,13 +82,6 @@ class ClusterGroupTestCase(FilterTestCases.NameOnlyFilterTestCase):
89
82
  params = {"clusters": [self.clusters[0].pk, self.clusters[1].name]}
90
83
  self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
91
84
 
92
- with self.subTest("Has Clusters"):
93
- params = {"has_clusters": True}
94
- self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
95
-
96
- params = {"has_clusters": False}
97
- self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
98
-
99
85
 
100
86
  class ClusterTestCase(FilterTestCases.FilterTestCase, FilterTestCases.TenancyFilterTestCaseMixin):
101
87
  queryset = Cluster.objects.all()
@@ -192,25 +178,11 @@ class ClusterTestCase(FilterTestCases.FilterTestCase, FilterTestCases.TenancyFil
192
178
  params = {"devices": [self.device.pk, self.device.name]}
193
179
  self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
194
180
 
195
- with self.subTest("Has Devices"):
196
- params = {"has_devices": True}
197
- self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
198
-
199
- params = {"has_devices": False}
200
- self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
201
-
202
181
  def test_virtual_machines(self):
203
182
  with self.subTest("Virtual Machines"):
204
183
  params = {"virtual_machines": [self.virtualmachine.pk, self.virtualmachine.name]}
205
184
  self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
206
185
 
207
- with self.subTest("Has Virtual Machines"):
208
- params = {"has_virtual_machines": True}
209
- self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
210
-
211
- params = {"has_virtual_machines": False}
212
- self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
213
-
214
186
  def test_location(self):
215
187
  params = {"location": [self.locations[0].pk, self.locations[1].pk]}
216
188
  self.assertQuerysetEqual(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: nautobot
3
- Version: 2.1.7
3
+ Version: 2.1.9
4
4
  Summary: Source of truth and network automation platform.
5
5
  Home-page: https://nautobot.com
6
6
  License: Apache-2.0
@@ -22,7 +22,7 @@ Provides-Extra: mysql
22
22
  Provides-Extra: napalm
23
23
  Provides-Extra: remote-storage
24
24
  Provides-Extra: sso
25
- Requires-Dist: Django (>=3.2.24,<3.3.0)
25
+ Requires-Dist: Django (>=3.2.25,<3.3.0)
26
26
  Requires-Dist: GitPython (>=3.1.41,<3.2.0)
27
27
  Requires-Dist: Jinja2 (>=3.1.3,<3.2.0)
28
28
  Requires-Dist: Markdown (>=3.3.7,<3.4.0)