nautobot 2.0.4__py3-none-any.whl → 2.1.0b1__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (812) hide show
  1. nautobot/circuits/navigation.py +0 -25
  2. nautobot/circuits/templates/circuits/circuit_retrieve.html +0 -9
  3. nautobot/circuits/templates/circuits/providernetwork_retrieve.html +0 -2
  4. nautobot/circuits/tests/test_api.py +79 -2
  5. nautobot/circuits/tests/test_filters.py +1 -0
  6. nautobot/core/api/serializers.py +15 -5
  7. nautobot/core/api/views.py +18 -19
  8. nautobot/core/choices.py +1 -1
  9. nautobot/core/filters.py +12 -4
  10. nautobot/core/jobs/__init__.py +125 -3
  11. nautobot/core/management/commands/generate_test_data.py +6 -1
  12. nautobot/core/middleware.py +12 -4
  13. nautobot/core/models/fields.py +12 -2
  14. nautobot/core/settings.py +9 -8
  15. nautobot/core/tables.py +26 -31
  16. nautobot/core/templates/base_django.html +2 -2
  17. nautobot/core/templates/buttons/export.html +57 -30
  18. nautobot/core/templates/generic/object_list.html +2 -2
  19. nautobot/core/templates/generic/object_retrieve.html +8 -1
  20. nautobot/core/templates/home.html +5 -5
  21. nautobot/core/templates/inc/created_updated.html +2 -2
  22. nautobot/core/templates/inc/footer.html +2 -2
  23. nautobot/core/templates/inc/javascript.html +0 -10
  24. nautobot/core/templates/inc/media.html +2 -0
  25. nautobot/core/templates/inc/nav_menu.html +66 -68
  26. nautobot/core/templates/inc/object_details_advanced_panel.html +19 -0
  27. nautobot/core/templates/nautobot_config.py.j2 +10 -4
  28. nautobot/core/templates/panel_table.html +1 -1
  29. nautobot/core/templates/template.css +89 -0
  30. nautobot/core/templates/utilities/templatetags/table_config_form.html +1 -0
  31. nautobot/core/templatetags/buttons.py +7 -2
  32. nautobot/core/templatetags/helpers.py +9 -9
  33. nautobot/core/testing/views.py +34 -4
  34. nautobot/core/tests/integration/test_home.py +1 -43
  35. nautobot/core/tests/integration/test_navbar.py +10 -64
  36. nautobot/core/tests/integration/test_plugin_home.py +4 -5
  37. nautobot/core/tests/integration/test_plugin_navbar.py +20 -16
  38. nautobot/core/tests/integration/test_theme.py +4 -0
  39. nautobot/core/tests/test_api.py +14 -66
  40. nautobot/core/tests/test_filters.py +127 -0
  41. nautobot/core/tests/test_forms.py +4 -4
  42. nautobot/core/tests/test_graphql.py +165 -2
  43. nautobot/core/tests/test_jobs.py +112 -0
  44. nautobot/core/tests/test_openapi.py +6 -0
  45. nautobot/core/tests/test_utils.py +23 -20
  46. nautobot/core/tests/test_views.py +11 -85
  47. nautobot/core/urls.py +6 -1
  48. nautobot/core/utils/data.py +5 -1
  49. nautobot/core/utils/filtering.py +6 -4
  50. nautobot/core/utils/lookup.py +28 -0
  51. nautobot/core/utils/requests.py +2 -3
  52. nautobot/core/views/__init__.py +3 -4
  53. nautobot/core/views/generic.py +15 -11
  54. nautobot/core/views/mixins.py +9 -8
  55. nautobot/core/views/renderers.py +5 -0
  56. nautobot/core/views/utils.py +23 -24
  57. nautobot/dcim/api/serializers.py +8 -4
  58. nautobot/dcim/models/device_components.py +1 -0
  59. nautobot/dcim/models/devices.py +7 -6
  60. nautobot/dcim/navigation.py +10 -165
  61. nautobot/dcim/templates/dcim/location.html +1 -1
  62. nautobot/dcim/tests/features/locations.feature +143 -0
  63. nautobot/dcim/tests/test_api.py +8 -1
  64. nautobot/dcim/tests/test_filters.py +11 -3
  65. nautobot/dcim/views.py +5 -6
  66. nautobot/extras/admin.py +1 -1
  67. nautobot/extras/api/serializers.py +33 -0
  68. nautobot/extras/api/urls.py +6 -0
  69. nautobot/extras/api/views.py +45 -6
  70. nautobot/extras/context_managers.py +34 -8
  71. nautobot/extras/factory.py +28 -2
  72. nautobot/extras/filters/__init__.py +52 -0
  73. nautobot/extras/filters/mixins.py +4 -29
  74. nautobot/extras/forms/forms.py +43 -0
  75. nautobot/extras/jobs.py +39 -17
  76. nautobot/extras/migrations/0100_fileproxy_job_result.py +32 -0
  77. nautobot/extras/migrations/0101_externalintegration.py +61 -0
  78. nautobot/extras/migrations/0102_set_null_objectchange_contenttype.py +32 -0
  79. nautobot/extras/models/__init__.py +2 -0
  80. nautobot/extras/models/change_logging.py +2 -2
  81. nautobot/extras/models/customfields.py +2 -2
  82. nautobot/extras/models/models.py +101 -18
  83. nautobot/extras/models/relationships.py +13 -8
  84. nautobot/extras/navigation.py +17 -29
  85. nautobot/extras/signals.py +80 -59
  86. nautobot/extras/tables.py +28 -2
  87. nautobot/extras/templates/extras/externalintegration_retrieve.html +37 -0
  88. nautobot/extras/templates/extras/inc/jobresult.html +24 -0
  89. nautobot/extras/templates/extras/jobresult.html +24 -0
  90. nautobot/extras/templatetags/computed_fields.py +6 -13
  91. nautobot/extras/templatetags/custom_links.py +19 -12
  92. nautobot/extras/templatetags/job_buttons.py +34 -19
  93. nautobot/extras/templatetags/plugins.py +1 -1
  94. nautobot/extras/test_jobs/file_output.py +16 -0
  95. nautobot/extras/tests/test_api.py +92 -0
  96. nautobot/extras/tests/test_context_managers.py +94 -4
  97. nautobot/extras/tests/test_customfields.py +1 -1
  98. nautobot/extras/tests/test_filters.py +64 -2
  99. nautobot/extras/tests/test_jobs.py +75 -22
  100. nautobot/extras/tests/test_models.py +34 -0
  101. nautobot/extras/tests/test_relationships.py +2 -2
  102. nautobot/extras/tests/test_views.py +204 -4
  103. nautobot/extras/tests/test_webhooks.py +61 -25
  104. nautobot/extras/urls.py +1 -0
  105. nautobot/extras/views.py +27 -13
  106. nautobot/extras/webhooks.py +16 -25
  107. nautobot/ipam/fields.py +5 -0
  108. nautobot/ipam/forms.py +16 -0
  109. nautobot/ipam/models.py +13 -2
  110. nautobot/ipam/navigation.py +2 -59
  111. nautobot/ipam/tables.py +1 -1
  112. nautobot/ipam/templates/ipam/ipaddress.html +0 -9
  113. nautobot/ipam/templates/ipam/prefix.html +0 -9
  114. nautobot/ipam/tests/features/prefixes.feature +134 -0
  115. nautobot/ipam/tests/test_filters.py +5 -10
  116. nautobot/ipam/tests/test_models.py +7 -0
  117. nautobot/ipam/tests/test_views.py +8 -1
  118. nautobot/ipam/views.py +99 -58
  119. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css +191 -191
  120. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css.map +1 -1
  121. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css +1 -1
  122. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css.map +1 -1
  123. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css +874 -881
  124. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css.map +1 -1
  125. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css +1 -1
  126. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css.map +1 -1
  127. nautobot/project-static/css/base.css +138 -99
  128. nautobot/project-static/css/dark.css +65 -6
  129. nautobot/project-static/docs/404.html +45 -17
  130. nautobot/project-static/docs/apps/index.html +45 -17
  131. nautobot/project-static/docs/apps/nautobot-apps.html +45 -17
  132. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +45 -17
  133. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +45 -17
  134. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +1598 -1458
  135. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +229 -152
  136. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +46 -18
  137. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +45 -17
  138. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +45 -17
  139. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +45 -17
  140. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +45 -17
  141. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +354 -433
  142. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +67 -39
  143. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +45 -17
  144. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +2083 -2234
  145. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +1389 -1247
  146. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +45 -17
  147. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +45 -17
  148. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +129 -111
  149. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +3601 -3457
  150. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +45 -17
  151. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +45 -17
  152. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +320 -284
  153. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +3863 -3801
  154. nautobot/project-static/docs/development/apps/api/configuration-view.html +45 -17
  155. nautobot/project-static/docs/development/apps/api/database-backend-config.html +45 -17
  156. nautobot/project-static/docs/development/apps/api/models/django-admin.html +45 -17
  157. nautobot/project-static/docs/development/apps/api/models/global-search.html +45 -17
  158. nautobot/project-static/docs/development/apps/api/models/graphql.html +45 -17
  159. nautobot/project-static/docs/development/apps/api/models/index.html +45 -17
  160. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +45 -17
  161. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +45 -17
  162. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +45 -17
  163. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +45 -17
  164. nautobot/project-static/docs/development/apps/api/platform-features/index.html +45 -17
  165. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +45 -17
  166. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +45 -17
  167. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +45 -17
  168. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +45 -17
  169. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +45 -17
  170. nautobot/project-static/docs/development/apps/api/prometheus.html +45 -17
  171. nautobot/project-static/docs/development/apps/api/setup.html +45 -17
  172. nautobot/project-static/docs/development/apps/api/testing.html +45 -17
  173. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +45 -17
  174. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +45 -17
  175. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +45 -17
  176. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +45 -17
  177. nautobot/project-static/docs/development/apps/api/ui-extensions/object-detail-views.html +45 -17
  178. nautobot/project-static/docs/development/apps/api/ui-extensions/tabs.html +45 -17
  179. nautobot/project-static/docs/development/apps/api/views/base-template.html +45 -17
  180. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +45 -17
  181. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +45 -17
  182. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +45 -17
  183. nautobot/project-static/docs/development/apps/api/views/index.html +45 -17
  184. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +45 -17
  185. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +45 -17
  186. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +45 -17
  187. nautobot/project-static/docs/development/apps/api/views/notes.html +45 -17
  188. nautobot/project-static/docs/development/apps/api/views/rest-api.html +45 -17
  189. nautobot/project-static/docs/development/apps/api/views/urls.html +45 -17
  190. nautobot/project-static/docs/development/apps/api/views/view-overrides.html +45 -17
  191. nautobot/project-static/docs/development/apps/index.html +45 -17
  192. nautobot/project-static/docs/development/apps/migration/code-updates.html +45 -17
  193. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +45 -17
  194. nautobot/project-static/docs/development/apps/migration/from-v1.html +45 -17
  195. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +45 -17
  196. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +45 -17
  197. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +45 -17
  198. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +45 -17
  199. nautobot/project-static/docs/development/apps/porting-from-netbox.html +45 -17
  200. nautobot/project-static/docs/development/core/application-registry.html +45 -17
  201. nautobot/project-static/docs/development/core/best-practices.html +45 -17
  202. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +45 -17
  203. nautobot/project-static/docs/development/core/extending-models.html +45 -17
  204. nautobot/project-static/docs/development/core/generic-views.html +45 -17
  205. nautobot/project-static/docs/development/core/getting-started.html +45 -17
  206. nautobot/project-static/docs/development/core/homepage.html +45 -17
  207. nautobot/project-static/docs/development/core/index.html +45 -17
  208. nautobot/project-static/docs/development/core/model-features.html +45 -17
  209. nautobot/project-static/docs/development/core/natural-keys.html +45 -17
  210. nautobot/project-static/docs/development/core/navigation-menu.html +45 -22
  211. nautobot/project-static/docs/development/core/react-ui.html +45 -17
  212. nautobot/project-static/docs/development/core/release-checklist.html +46 -18
  213. nautobot/project-static/docs/development/core/role-internals.html +45 -17
  214. nautobot/project-static/docs/development/core/style-guide.html +45 -17
  215. nautobot/project-static/docs/development/core/templates.html +45 -17
  216. nautobot/project-static/docs/development/core/testing.html +45 -17
  217. nautobot/project-static/docs/development/core/user-preferences.html +45 -17
  218. nautobot/project-static/docs/development/index.html +45 -17
  219. nautobot/project-static/docs/development/jobs/index.html +281 -235
  220. nautobot/project-static/docs/development/jobs/migration/from-v1.html +45 -17
  221. nautobot/project-static/docs/index.html +45 -17
  222. nautobot/project-static/docs/media/nautobot_application_stack_low_level.png +0 -0
  223. nautobot/project-static/docs/media/nautobot_application_stack_low_level.txt +1 -0
  224. nautobot/project-static/docs/objects.inv +0 -0
  225. nautobot/project-static/docs/release-notes/index.html +48 -20
  226. nautobot/project-static/docs/release-notes/version-1.0.html +45 -17
  227. nautobot/project-static/docs/release-notes/version-1.1.html +45 -17
  228. nautobot/project-static/docs/release-notes/version-1.2.html +45 -17
  229. nautobot/project-static/docs/release-notes/version-1.3.html +45 -17
  230. nautobot/project-static/docs/release-notes/version-1.4.html +45 -17
  231. nautobot/project-static/docs/release-notes/version-1.5.html +45 -17
  232. nautobot/project-static/docs/release-notes/version-1.6.html +46 -18
  233. nautobot/project-static/docs/release-notes/version-2.0.html +372 -199
  234. nautobot/project-static/docs/release-notes/version-2.1.html +5724 -0
  235. nautobot/project-static/docs/requirements.txt +1 -1
  236. nautobot/project-static/docs/search/search_index.json +1 -1
  237. nautobot/project-static/docs/sitemap.xml +247 -237
  238. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  239. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +45 -17
  240. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +45 -17
  241. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +45 -17
  242. nautobot/project-static/docs/user-guide/administration/configuration/index.html +45 -17
  243. nautobot/project-static/docs/user-guide/administration/configuration/node-configuration.html +45 -17
  244. nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +110 -44
  245. nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +45 -17
  246. nautobot/project-static/docs/user-guide/administration/guides/caching.html +48 -20
  247. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +45 -17
  248. nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +45 -17
  249. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +45 -17
  250. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +45 -17
  251. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +45 -17
  252. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +49 -20
  253. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +45 -17
  254. nautobot/project-static/docs/user-guide/administration/installation/docker.html +45 -17
  255. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +45 -17
  256. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +45 -17
  257. nautobot/project-static/docs/user-guide/administration/installation/index.html +45 -17
  258. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +45 -17
  259. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +45 -17
  260. nautobot/project-static/docs/user-guide/administration/installation/selinux-troubleshooting.html +45 -17
  261. nautobot/project-static/docs/user-guide/administration/installation/services.html +45 -17
  262. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +45 -17
  263. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +45 -17
  264. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +45 -17
  265. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +45 -17
  266. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +45 -17
  267. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +45 -17
  268. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +45 -17
  269. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +45 -17
  270. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +45 -17
  271. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +45 -17
  272. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +45 -17
  273. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +45 -17
  274. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +45 -17
  275. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +45 -17
  276. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +45 -17
  277. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +45 -17
  278. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +45 -17
  279. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +45 -17
  280. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +45 -17
  281. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +45 -17
  282. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +45 -17
  283. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +45 -17
  284. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +45 -17
  285. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +45 -17
  286. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +45 -17
  287. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +45 -17
  288. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +45 -17
  289. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +45 -17
  290. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +45 -17
  291. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +45 -17
  292. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +45 -17
  293. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +45 -17
  294. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +45 -17
  295. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +45 -17
  296. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +45 -17
  297. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +45 -17
  298. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +45 -17
  299. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +45 -17
  300. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +45 -17
  301. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +45 -17
  302. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +45 -17
  303. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +45 -17
  304. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +45 -17
  305. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +45 -17
  306. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +45 -17
  307. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +45 -17
  308. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +45 -17
  309. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +45 -17
  310. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +45 -17
  311. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +45 -17
  312. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +45 -17
  313. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +45 -17
  314. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +45 -17
  315. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +45 -17
  316. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +45 -17
  317. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +45 -17
  318. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +45 -17
  319. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +45 -17
  320. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +45 -17
  321. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +45 -17
  322. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +45 -17
  323. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +45 -17
  324. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +45 -17
  325. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +45 -17
  326. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +45 -17
  327. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +45 -17
  328. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +45 -17
  329. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +45 -17
  330. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +45 -17
  331. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +45 -17
  332. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +45 -17
  333. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +45 -17
  334. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +45 -17
  335. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +45 -17
  336. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +45 -17
  337. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +45 -17
  338. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +45 -17
  339. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +45 -17
  340. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +45 -17
  341. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +45 -17
  342. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +45 -17
  343. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +45 -17
  344. nautobot/project-static/docs/user-guide/index.html +45 -17
  345. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +111 -17
  346. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +45 -17
  347. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +45 -17
  348. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +45 -17
  349. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +45 -17
  350. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +48 -20
  351. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +5359 -0
  352. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +48 -20
  353. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +45 -17
  354. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +45 -17
  355. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +45 -17
  356. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +45 -17
  357. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +45 -17
  358. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +45 -17
  359. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +45 -17
  360. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +45 -17
  361. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +45 -17
  362. nautobot/project-static/docs/user-guide/platform-functionality/note.html +45 -17
  363. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +45 -17
  364. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +45 -17
  365. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +114 -45
  366. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +45 -17
  367. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +45 -17
  368. nautobot/project-static/docs/user-guide/platform-functionality/role.html +45 -17
  369. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +45 -17
  370. nautobot/project-static/docs/user-guide/platform-functionality/status.html +45 -17
  371. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +45 -17
  372. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +45 -17
  373. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +45 -17
  374. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +45 -17
  375. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +45 -17
  376. nautobot/project-static/fonts/UFL.txt +96 -0
  377. nautobot/project-static/fonts/Ubuntu-Bold.woff2 +0 -0
  378. nautobot/project-static/fonts/Ubuntu-BoldItalic.woff2 +0 -0
  379. nautobot/project-static/fonts/Ubuntu-Italic.woff2 +0 -0
  380. nautobot/project-static/fonts/Ubuntu-Medium.woff2 +0 -0
  381. nautobot/project-static/fonts/Ubuntu-MediumItalic.woff2 +0 -0
  382. nautobot/project-static/fonts/Ubuntu-Regular.woff2 +0 -0
  383. nautobot/project-static/fonts/UbuntuMono-Bold.woff2 +0 -0
  384. nautobot/project-static/fonts/UbuntuMono-BoldItalic.woff2 +0 -0
  385. nautobot/project-static/fonts/UbuntuMono-Italic.woff2 +0 -0
  386. nautobot/project-static/fonts/UbuntuMono-Regular.woff2 +0 -0
  387. nautobot/project-static/img/dark-theme.png +0 -0
  388. nautobot/project-static/img/light-theme.png +0 -0
  389. nautobot/project-static/img/nautobot_chevron.svg +5 -0
  390. nautobot/project-static/img/nautobot_chevron_header.svg +5 -0
  391. nautobot/project-static/img/system-theme.png +0 -0
  392. nautobot/tenancy/navigation.py +0 -13
  393. nautobot/ui/package-lock.json +2 -2
  394. nautobot/ui/package.json +1 -1
  395. nautobot/users/admin.py +44 -0
  396. nautobot/users/migrations/0007_alter_objectpermission_object_types.py +33 -0
  397. nautobot/users/models.py +3 -2
  398. nautobot/virtualization/navigation.py +1 -33
  399. nautobot/virtualization/tests/test_api.py +1 -1
  400. nautobot/virtualization/tests/test_filters.py +1 -1
  401. {nautobot-2.0.4.dist-info → nautobot-2.1.0b1.dist-info}/METADATA +2 -2
  402. {nautobot-2.0.4.dist-info → nautobot-2.1.0b1.dist-info}/RECORD +405 -786
  403. CHANGELOG.md +0 -3
  404. CONTRIBUTING.md +0 -3
  405. NOTICE +0 -8
  406. nautobot/docs/apps/index.md +0 -22
  407. nautobot/docs/apps/nautobot-apps.md +0 -10
  408. nautobot/docs/assets/app-icons/icon-ChatOps.png +0 -0
  409. nautobot/docs/assets/app-icons/icon-DataValidationEngine.png +0 -0
  410. nautobot/docs/assets/app-icons/icon-DeviceLifecycle.png +0 -0
  411. nautobot/docs/assets/app-icons/icon-DeviceOnboarding.png +0 -0
  412. nautobot/docs/assets/app-icons/icon-FirewallModels.png +0 -0
  413. nautobot/docs/assets/app-icons/icon-GoldenConfiguration.png +0 -0
  414. nautobot/docs/assets/app-icons/icon-NautobotPluginNornir.png +0 -0
  415. nautobot/docs/assets/app-icons/icon-SSoT.png +0 -0
  416. nautobot/docs/assets/extra.css +0 -139
  417. nautobot/docs/assets/favicon.ico +0 -0
  418. nautobot/docs/assets/nautobot_logo.png +0 -0
  419. nautobot/docs/assets/nautobot_logo.svg +0 -131
  420. nautobot/docs/assets/networktocode_bw.png +0 -0
  421. nautobot/docs/assets/overrides/partials/copyright.html +0 -20
  422. nautobot/docs/development/apps/api/configuration-view.md +0 -35
  423. nautobot/docs/development/apps/api/database-backend-config.md +0 -26
  424. nautobot/docs/development/apps/api/models/django-admin.md +0 -20
  425. nautobot/docs/development/apps/api/models/global-search.md +0 -11
  426. nautobot/docs/development/apps/api/models/graphql.md +0 -97
  427. nautobot/docs/development/apps/api/models/index.md +0 -81
  428. nautobot/docs/development/apps/api/nautobot-app-config.md +0 -84
  429. nautobot/docs/development/apps/api/platform-features/custom-validators.md +0 -30
  430. nautobot/docs/development/apps/api/platform-features/filter-extensions.md +0 -49
  431. nautobot/docs/development/apps/api/platform-features/git-repository-content.md +0 -62
  432. nautobot/docs/development/apps/api/platform-features/index.md +0 -1
  433. nautobot/docs/development/apps/api/platform-features/jinja2-filters.md +0 -28
  434. nautobot/docs/development/apps/api/platform-features/jobs.md +0 -29
  435. nautobot/docs/development/apps/api/platform-features/populating-extensibility-features.md +0 -58
  436. nautobot/docs/development/apps/api/platform-features/secrets-providers.md +0 -64
  437. nautobot/docs/development/apps/api/platform-features/uniquely-identify-objects.md +0 -63
  438. nautobot/docs/development/apps/api/prometheus.md +0 -25
  439. nautobot/docs/development/apps/api/setup.md +0 -132
  440. nautobot/docs/development/apps/api/testing.md +0 -55
  441. nautobot/docs/development/apps/api/ui-extensions/banners.md +0 -26
  442. nautobot/docs/development/apps/api/ui-extensions/home-page.md +0 -9
  443. nautobot/docs/development/apps/api/ui-extensions/index.md +0 -1
  444. nautobot/docs/development/apps/api/ui-extensions/navigation.md +0 -15
  445. nautobot/docs/development/apps/api/ui-extensions/object-detail-views.md +0 -74
  446. nautobot/docs/development/apps/api/ui-extensions/tabs.md +0 -52
  447. nautobot/docs/development/apps/api/views/base-template.md +0 -38
  448. nautobot/docs/development/apps/api/views/core-view-overrides.md +0 -26
  449. nautobot/docs/development/apps/api/views/django-generic-views.md +0 -23
  450. nautobot/docs/development/apps/api/views/help-documentation.md +0 -16
  451. nautobot/docs/development/apps/api/views/index.md +0 -3
  452. nautobot/docs/development/apps/api/views/nautobot-generic-views.md +0 -35
  453. nautobot/docs/development/apps/api/views/nautobotuiviewset.md +0 -147
  454. nautobot/docs/development/apps/api/views/nautobotuiviewsetrouter.md +0 -41
  455. nautobot/docs/development/apps/api/views/notes.md +0 -25
  456. nautobot/docs/development/apps/api/views/rest-api.md +0 -64
  457. nautobot/docs/development/apps/api/views/urls.md +0 -26
  458. nautobot/docs/development/apps/api/views/view-overrides.md +0 -50
  459. nautobot/docs/development/apps/index.md +0 -75
  460. nautobot/docs/development/apps/migration/code-updates.md +0 -160
  461. nautobot/docs/development/apps/migration/dependency-updates.md +0 -13
  462. nautobot/docs/development/apps/migration/from-v1.md +0 -56
  463. nautobot/docs/development/apps/migration/model-updates/dcim.md +0 -285
  464. nautobot/docs/development/apps/migration/model-updates/extras.md +0 -30
  465. nautobot/docs/development/apps/migration/model-updates/global.md +0 -5
  466. nautobot/docs/development/apps/migration/model-updates/ipam.md +0 -22
  467. nautobot/docs/development/apps/porting-from-netbox.md +0 -23
  468. nautobot/docs/development/core/application-registry.md +0 -216
  469. nautobot/docs/development/core/best-practices.md +0 -469
  470. nautobot/docs/development/core/docker-compose-advanced-use-cases.md +0 -228
  471. nautobot/docs/development/core/extending-models.md +0 -93
  472. nautobot/docs/development/core/generic-views.md +0 -65
  473. nautobot/docs/development/core/getting-started.md +0 -859
  474. nautobot/docs/development/core/homepage.md +0 -63
  475. nautobot/docs/development/core/index.md +0 -334
  476. nautobot/docs/development/core/model-features.md +0 -44
  477. nautobot/docs/development/core/natural-keys.md +0 -121
  478. nautobot/docs/development/core/navigation-menu.md +0 -142
  479. nautobot/docs/development/core/react-ui.md +0 -137
  480. nautobot/docs/development/core/release-checklist.md +0 -312
  481. nautobot/docs/development/core/role-internals.md +0 -28
  482. nautobot/docs/development/core/style-guide.md +0 -200
  483. nautobot/docs/development/core/templates.md +0 -101
  484. nautobot/docs/development/core/testing.md +0 -238
  485. nautobot/docs/development/core/user-preferences.md +0 -11
  486. nautobot/docs/development/index.md +0 -1
  487. nautobot/docs/development/jobs/index.md +0 -835
  488. nautobot/docs/development/jobs/migration/from-v1.md +0 -160
  489. nautobot/docs/generate_code_reference_pages.py +0 -20
  490. nautobot/docs/img/edge_dev_circuit_relationship.png +0 -0
  491. nautobot/docs/img/leaf_dev_no_circuit_relationship.png +0 -0
  492. nautobot/docs/img/relationship_w_json_filter.png +0 -0
  493. nautobot/docs/index.md +0 -105
  494. nautobot/docs/media/admin_ui_run_permission.png +0 -0
  495. nautobot/docs/media/development/homepage_changelog_panel.png +0 -0
  496. nautobot/docs/media/development/homepage_dcim_panel.png +0 -0
  497. nautobot/docs/media/development/index_bug_wf.jpg +0 -0
  498. nautobot/docs/media/development/index_feature_request_wf.jpg +0 -0
  499. nautobot/docs/media/development/index_release_cadence.drawio +0 -90
  500. nautobot/docs/media/development/index_release_cadence.jpg +0 -0
  501. nautobot/docs/media/installation/nautobot_ui_admin.png +0 -0
  502. nautobot/docs/media/installation/nautobot_ui_guest.png +0 -0
  503. nautobot/docs/media/models/dcim_cable_trace.png +0 -0
  504. nautobot/docs/media/models/dcim_cable_trace_circuit.png +0 -0
  505. nautobot/docs/media/models/dynamicgroup_filtering_01.png +0 -0
  506. nautobot/docs/media/models/dynamicgroup_workflow_advanced_1_01.png +0 -0
  507. nautobot/docs/media/models/dynamicgroup_workflow_advanced_1_02.png +0 -0
  508. nautobot/docs/media/models/dynamicgroup_workflow_advanced_1_03.png +0 -0
  509. nautobot/docs/media/models/dynamicgroup_workflow_advanced_1_04.png +0 -0
  510. nautobot/docs/media/models/dynamicgroup_workflow_advanced_1_05.png +0 -0
  511. nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_01.png +0 -0
  512. nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_02.png +0 -0
  513. nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_03.png +0 -0
  514. nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_04.png +0 -0
  515. nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_05.png +0 -0
  516. nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_06.png +0 -0
  517. nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_07.png +0 -0
  518. nautobot/docs/media/models/dynamicgroup_workflow_basic_01.png +0 -0
  519. nautobot/docs/media/models/dynamicgroup_workflow_basic_02.png +0 -0
  520. nautobot/docs/media/models/dynamicgroup_workflow_basic_03.png +0 -0
  521. nautobot/docs/media/models/jobbutton_form.png +0 -0
  522. nautobot/docs/media/models/site_jobbuttons.png +0 -0
  523. nautobot/docs/media/nautobot_application_stack_high_level.drawio +0 -1
  524. nautobot/docs/media/nautobot_application_stack_high_level.png +0 -0
  525. nautobot/docs/media/nautobot_application_stack_low_level.drawio +0 -1
  526. nautobot/docs/media/nautobot_application_stack_low_level.png +0 -0
  527. nautobot/docs/media/nautobot_chatops.gif +0 -0
  528. nautobot/docs/media/nautobot_config_context.gif +0 -0
  529. nautobot/docs/media/nautobot_golden_config.gif +0 -0
  530. nautobot/docs/media/nautobot_graphql.gif +0 -0
  531. nautobot/docs/media/nautobot_mainpage.gif +0 -0
  532. nautobot/docs/media/nautobot_prefix_hierarchy.gif +0 -0
  533. nautobot/docs/media/plugins/plugin_admin_config.png +0 -0
  534. nautobot/docs/media/plugins/plugin_admin_ui.png +0 -0
  535. nautobot/docs/media/plugins/plugin_rest_api_endpoint.png +0 -0
  536. nautobot/docs/media/power_distribution.png +0 -0
  537. nautobot/docs/media/ss_config_contexts.png +0 -0
  538. nautobot/docs/media/ss_graphiql.png +0 -0
  539. nautobot/docs/media/ss_main_page.png +0 -0
  540. nautobot/docs/media/ss_plugin_chatops.png +0 -0
  541. nautobot/docs/media/ss_plugin_golden_config.png +0 -0
  542. nautobot/docs/media/ss_prefix_hierarchy.png +0 -0
  543. nautobot/docs/media/user-guide/administration/guides/s3-django-storage/user-guide-s3-1.png +0 -0
  544. nautobot/docs/media/user-guide/administration/guides/s3-django-storage/user-guide-s3-2.png +0 -0
  545. nautobot/docs/media/user-guide/administration/upgrading/from-v1/ipam/tenant-affinity.png +0 -0
  546. nautobot/docs/nautobot_logo.png +0 -0
  547. nautobot/docs/nautobot_logo.svg +0 -131
  548. nautobot/docs/release-notes/index.md +0 -3
  549. nautobot/docs/release-notes/version-1.0.md +0 -530
  550. nautobot/docs/release-notes/version-1.1.md +0 -337
  551. nautobot/docs/release-notes/version-1.2.md +0 -509
  552. nautobot/docs/release-notes/version-1.3.md +0 -554
  553. nautobot/docs/release-notes/version-1.4.md +0 -677
  554. nautobot/docs/release-notes/version-1.5.md +0 -840
  555. nautobot/docs/release-notes/version-1.6.md +0 -290
  556. nautobot/docs/release-notes/version-2.0.md +0 -1359
  557. nautobot/docs/requirements.txt +0 -12
  558. nautobot/docs/user-guide/administration/configuration/authentication/ldap.md +0 -286
  559. nautobot/docs/user-guide/administration/configuration/authentication/remote.md +0 -46
  560. nautobot/docs/user-guide/administration/configuration/authentication/sso.md +0 -528
  561. nautobot/docs/user-guide/administration/configuration/index.md +0 -190
  562. nautobot/docs/user-guide/administration/configuration/node-configuration.md +0 -31
  563. nautobot/docs/user-guide/administration/configuration/optional-settings.md +0 -1302
  564. nautobot/docs/user-guide/administration/configuration/required-settings.md +0 -244
  565. nautobot/docs/user-guide/administration/guides/caching.md +0 -108
  566. nautobot/docs/user-guide/administration/guides/celery-queues.md +0 -42
  567. nautobot/docs/user-guide/administration/guides/healthcheck.md +0 -11
  568. nautobot/docs/user-guide/administration/guides/permissions.md +0 -98
  569. nautobot/docs/user-guide/administration/guides/prometheus-metrics.md +0 -55
  570. nautobot/docs/user-guide/administration/guides/replicating-nautobot.md +0 -70
  571. nautobot/docs/user-guide/administration/guides/s3-django-storage.md +0 -145
  572. nautobot/docs/user-guide/administration/installation/app-install.md +0 -94
  573. nautobot/docs/user-guide/administration/installation/docker.md +0 -286
  574. nautobot/docs/user-guide/administration/installation/external-authentication.md +0 -9
  575. nautobot/docs/user-guide/administration/installation/http-server.md +0 -279
  576. nautobot/docs/user-guide/administration/installation/index.md +0 -101
  577. nautobot/docs/user-guide/administration/installation/install_system.md +0 -493
  578. nautobot/docs/user-guide/administration/installation/nautobot.md +0 -367
  579. nautobot/docs/user-guide/administration/installation/selinux-troubleshooting.md +0 -194
  580. nautobot/docs/user-guide/administration/installation/services.md +0 -340
  581. nautobot/docs/user-guide/administration/migration/migrating-from-netbox.md +0 -336
  582. nautobot/docs/user-guide/administration/migration/migrating-from-postgresql.md +0 -122
  583. nautobot/docs/user-guide/administration/tools/nautobot-server.md +0 -858
  584. nautobot/docs/user-guide/administration/tools/nautobot-shell.md +0 -263
  585. nautobot/docs/user-guide/administration/upgrading/database-backup.md +0 -11
  586. nautobot/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.md +0 -55
  587. nautobot/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.md +0 -73
  588. nautobot/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.md +0 -211
  589. nautobot/docs/user-guide/administration/upgrading/from-v1/ipam/index.md +0 -16
  590. nautobot/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.md +0 -157
  591. nautobot/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.md +0 -153
  592. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-api-behavior-changes.yaml +0 -82
  593. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-api-removed-fields.yaml +0 -175
  594. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-api-renamed-fields.yaml +0 -124
  595. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-code-location-changes.yaml +0 -241
  596. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-code-removals.yaml +0 -57
  597. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-code-renames.yaml +0 -5
  598. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-database-behavior-changes.yaml +0 -76
  599. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-database-removed-fields.yaml +0 -202
  600. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-database-renamed-fields.yaml +0 -343
  601. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-filters-corrected-fields.yaml +0 -31
  602. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-filters-enhanced-fields.yaml +0 -244
  603. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-filters-removed-fields.yaml +0 -595
  604. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-filters-renamed-fields.yaml +0 -253
  605. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-logging-renamed-loggers.yaml +0 -23
  606. nautobot/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.md +0 -574
  607. nautobot/docs/user-guide/administration/upgrading/upgrading.md +0 -127
  608. nautobot/docs/user-guide/core-data-model/circuits/circuit.md +0 -19
  609. nautobot/docs/user-guide/core-data-model/circuits/circuittermination.md +0 -10
  610. nautobot/docs/user-guide/core-data-model/circuits/circuittype.md +0 -8
  611. nautobot/docs/user-guide/core-data-model/circuits/provider.md +0 -5
  612. nautobot/docs/user-guide/core-data-model/circuits/providernetwork.md +0 -7
  613. nautobot/docs/user-guide/core-data-model/dcim/cable.md +0 -43
  614. nautobot/docs/user-guide/core-data-model/dcim/consoleport.md +0 -8
  615. nautobot/docs/user-guide/core-data-model/dcim/consoleporttemplate.md +0 -6
  616. nautobot/docs/user-guide/core-data-model/dcim/consoleserverport.md +0 -8
  617. nautobot/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.md +0 -6
  618. nautobot/docs/user-guide/core-data-model/dcim/device.md +0 -29
  619. nautobot/docs/user-guide/core-data-model/dcim/devicebay.md +0 -11
  620. nautobot/docs/user-guide/core-data-model/dcim/devicebaytemplate.md +0 -6
  621. nautobot/docs/user-guide/core-data-model/dcim/deviceredundancygroup.md +0 -279
  622. nautobot/docs/user-guide/core-data-model/dcim/devicetype.md +0 -44
  623. nautobot/docs/user-guide/core-data-model/dcim/frontport.md +0 -6
  624. nautobot/docs/user-guide/core-data-model/dcim/frontporttemplate.md +0 -6
  625. nautobot/docs/user-guide/core-data-model/dcim/interface.md +0 -34
  626. nautobot/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.md +0 -24
  627. nautobot/docs/user-guide/core-data-model/dcim/interfacetemplate.md +0 -6
  628. nautobot/docs/user-guide/core-data-model/dcim/inventoryitem.md +0 -10
  629. nautobot/docs/user-guide/core-data-model/dcim/location.md +0 -15
  630. nautobot/docs/user-guide/core-data-model/dcim/locationtype.md +0 -43
  631. nautobot/docs/user-guide/core-data-model/dcim/manufacturer.md +0 -3
  632. nautobot/docs/user-guide/core-data-model/dcim/platform.md +0 -19
  633. nautobot/docs/user-guide/core-data-model/dcim/powerfeed.md +0 -25
  634. nautobot/docs/user-guide/core-data-model/dcim/poweroutlet.md +0 -14
  635. nautobot/docs/user-guide/core-data-model/dcim/poweroutlettemplate.md +0 -6
  636. nautobot/docs/user-guide/core-data-model/dcim/powerpanel.md +0 -12
  637. nautobot/docs/user-guide/core-data-model/dcim/powerport.md +0 -15
  638. nautobot/docs/user-guide/core-data-model/dcim/powerporttemplate.md +0 -6
  639. nautobot/docs/user-guide/core-data-model/dcim/rack.md +0 -41
  640. nautobot/docs/user-guide/core-data-model/dcim/rackgroup.md +0 -7
  641. nautobot/docs/user-guide/core-data-model/dcim/rackreservation.md +0 -3
  642. nautobot/docs/user-guide/core-data-model/dcim/rearport.md +0 -9
  643. nautobot/docs/user-guide/core-data-model/dcim/rearporttemplate.md +0 -6
  644. nautobot/docs/user-guide/core-data-model/dcim/virtualchassis.md +0 -8
  645. nautobot/docs/user-guide/core-data-model/extras/configcontext.md +0 -78
  646. nautobot/docs/user-guide/core-data-model/extras/configcontextschema.md +0 -73
  647. nautobot/docs/user-guide/core-data-model/ipam/ipaddress.md +0 -69
  648. nautobot/docs/user-guide/core-data-model/ipam/media/ipam_namespace_documentation.drawio +0 -1
  649. nautobot/docs/user-guide/core-data-model/ipam/media/ipam_namespace_documentation.drawio.svg +0 -4
  650. nautobot/docs/user-guide/core-data-model/ipam/namespace.md +0 -18
  651. nautobot/docs/user-guide/core-data-model/ipam/prefix.md +0 -65
  652. nautobot/docs/user-guide/core-data-model/ipam/rir.md +0 -10
  653. nautobot/docs/user-guide/core-data-model/ipam/routetarget.md +0 -5
  654. nautobot/docs/user-guide/core-data-model/ipam/service.md +0 -8
  655. nautobot/docs/user-guide/core-data-model/ipam/vlan.md +0 -17
  656. nautobot/docs/user-guide/core-data-model/ipam/vlangroup.md +0 -5
  657. nautobot/docs/user-guide/core-data-model/ipam/vrf.md +0 -15
  658. nautobot/docs/user-guide/core-data-model/tenancy/tenant.md +0 -20
  659. nautobot/docs/user-guide/core-data-model/tenancy/tenantgroup.md +0 -5
  660. nautobot/docs/user-guide/core-data-model/virtualization/cluster.md +0 -5
  661. nautobot/docs/user-guide/core-data-model/virtualization/clustergroup.md +0 -3
  662. nautobot/docs/user-guide/core-data-model/virtualization/clustertype.md +0 -3
  663. nautobot/docs/user-guide/core-data-model/virtualization/virtualmachine.md +0 -17
  664. nautobot/docs/user-guide/core-data-model/virtualization/vminterface.md +0 -19
  665. nautobot/docs/user-guide/feature-guides/custom-fields.md +0 -350
  666. nautobot/docs/user-guide/feature-guides/getting-started/creating-devices.md +0 -130
  667. nautobot/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.md +0 -113
  668. nautobot/docs/user-guide/feature-guides/getting-started/index.md +0 -29
  669. nautobot/docs/user-guide/feature-guides/getting-started/interfaces.md +0 -100
  670. nautobot/docs/user-guide/feature-guides/getting-started/ipam.md +0 -104
  671. nautobot/docs/user-guide/feature-guides/getting-started/platforms.md +0 -78
  672. nautobot/docs/user-guide/feature-guides/getting-started/search-bar.md +0 -40
  673. nautobot/docs/user-guide/feature-guides/getting-started/tenants.md +0 -40
  674. nautobot/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.md +0 -87
  675. nautobot/docs/user-guide/feature-guides/git-data-source.md +0 -307
  676. nautobot/docs/user-guide/feature-guides/graphql.md +0 -342
  677. nautobot/docs/user-guide/feature-guides/images/custom-fields/custom_field_choices.png +0 -0
  678. nautobot/docs/user-guide/feature-guides/images/custom-fields/custom_field_detail_grouped.png +0 -0
  679. nautobot/docs/user-guide/feature-guides/images/custom-fields/custom_field_detail_label.png +0 -0
  680. nautobot/docs/user-guide/feature-guides/images/custom-fields/custom_field_edit.png +0 -0
  681. nautobot/docs/user-guide/feature-guides/images/custom-fields/custom_field_select.png +0 -0
  682. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/1-create-location-type.png +0 -0
  683. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/10-add-platform.png +0 -0
  684. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/11-platforms-page.png +0 -0
  685. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/12-add-tenant.png +0 -0
  686. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/13-assign-tenant-to-device.png +0 -0
  687. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/14-assign-tenant-to-device-2.png +0 -0
  688. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/15-create-device-type.png +0 -0
  689. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/16-interface-templates.png +0 -0
  690. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/17-templated-interfaces.png +0 -0
  691. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/18-assign-device-type.png +0 -0
  692. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/19-edit-ints-for-lag.png +0 -0
  693. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/2-create-manufacturer.png +0 -0
  694. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/20-ints-int-lag.png +0 -0
  695. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/21-device-type.png +0 -0
  696. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/22-create-vlans.png +0 -0
  697. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/23-create-vlans-2.png +0 -0
  698. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/24-vlan-main-page.png +0 -0
  699. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/25-add-vlan-to-interface.png +0 -0
  700. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/26-add-vlan-to-interface-2.png +0 -0
  701. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/27-add-rir.png +0 -0
  702. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/3-create-role.png +0 -0
  703. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/30-add-prefix.png +0 -0
  704. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/32-add-ip-addr.png +0 -0
  705. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/33-assign-address.png +0 -0
  706. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/34-assign-address-2.png +0 -0
  707. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/35-assign-address-3.png +0 -0
  708. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/36-verify-address.png +0 -0
  709. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/37-verify-prefix.png +0 -0
  710. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/38-verify-prefix2.png +0 -0
  711. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/39-address-search.png +0 -0
  712. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/4-create-device-type.png +0 -0
  713. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/40-addr-main-page.png +0 -0
  714. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/41-device-search-results.png +0 -0
  715. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/42-address-search-v2.png +0 -0
  716. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/43-get-to-device-main-page.png +0 -0
  717. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/44-add-platform.png +0 -0
  718. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/5-create-device.png +0 -0
  719. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/6-create-location.png +0 -0
  720. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/7-location-type-page.png +0 -0
  721. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/8-location-page.png +0 -0
  722. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/01-git-data-source.png +0 -0
  723. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/02-git-data-source.png +0 -0
  724. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/03-git-data-source.png +0 -0
  725. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/04-git-data-source.png +0 -0
  726. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/05-git-data-source.png +0 -0
  727. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/06-git-data-source.png +0 -0
  728. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/07-git-data-source.png +0 -0
  729. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/08-git-data-source.png +0 -0
  730. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/09-git-data-source.png +0 -0
  731. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/10-git-data-source.png +0 -0
  732. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/11-git-data-source.png +0 -0
  733. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/12-git-data-source.png +0 -0
  734. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/13-git-data-source.png +0 -0
  735. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/14-git-data-source.png +0 -0
  736. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/15-git-data-source.png +0 -0
  737. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/16-git-data-source.png +0 -0
  738. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/17-git-data-source.png +0 -0
  739. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/18-git-data-source.png +0 -0
  740. nautobot/docs/user-guide/feature-guides/images/graphql/00-graphiql.png +0 -0
  741. nautobot/docs/user-guide/feature-guides/images/graphql/01-graphiql-explorer.png +0 -0
  742. nautobot/docs/user-guide/feature-guides/images/graphql/02-graphiql-explorer-device-query.png +0 -0
  743. nautobot/docs/user-guide/feature-guides/images/graphql/03-graphiql-explorer-device-attributes.png +0 -0
  744. nautobot/docs/user-guide/feature-guides/images/graphql/04-graphql-query-01.png +0 -0
  745. nautobot/docs/user-guide/feature-guides/images/graphql/05-graphiql-autocomplete.png +0 -0
  746. nautobot/docs/user-guide/feature-guides/images/graphql/06-graphql-query-02.png +0 -0
  747. nautobot/docs/user-guide/feature-guides/images/graphql/07-graphql-query-03.png +0 -0
  748. nautobot/docs/user-guide/feature-guides/images/graphql/08-graphql-query-04.png +0 -0
  749. nautobot/docs/user-guide/feature-guides/images/graphql/09-graphql-query-05.png +0 -0
  750. nautobot/docs/user-guide/feature-guides/images/graphql/10-graphql-swagger.png +0 -0
  751. nautobot/docs/user-guide/feature-guides/images/graphql/11-graphql-query-06.png +0 -0
  752. nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/ip_merge_button.png +0 -0
  753. nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/merge_button.png +0 -0
  754. nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/merge_view.png +0 -0
  755. nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/no_more_dup_ips.png +0 -0
  756. nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/skip_button.png +0 -0
  757. nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/unselect_ips.png +0 -0
  758. nautobot/docs/user-guide/feature-guides/images/relationships/01-relationships.png +0 -0
  759. nautobot/docs/user-guide/feature-guides/images/relationships/02-relationships.png +0 -0
  760. nautobot/docs/user-guide/feature-guides/images/relationships/03-relationships.png +0 -0
  761. nautobot/docs/user-guide/feature-guides/images/relationships/04-relationships.png +0 -0
  762. nautobot/docs/user-guide/feature-guides/images/relationships/05-relationships.png +0 -0
  763. nautobot/docs/user-guide/feature-guides/images/relationships/06-relationships.png +0 -0
  764. nautobot/docs/user-guide/feature-guides/images/relationships/07-relationships.png +0 -0
  765. nautobot/docs/user-guide/feature-guides/images/relationships/08-relationships.png +0 -0
  766. nautobot/docs/user-guide/feature-guides/images/relationships/09-relationships.png +0 -0
  767. nautobot/docs/user-guide/feature-guides/images/relationships/10-relationships.png +0 -0
  768. nautobot/docs/user-guide/feature-guides/images/relationships/11-relationships.png +0 -0
  769. nautobot/docs/user-guide/feature-guides/ip-address-merge-tool.md +0 -63
  770. nautobot/docs/user-guide/feature-guides/relationships.md +0 -125
  771. nautobot/docs/user-guide/index.md +0 -1
  772. nautobot/docs/user-guide/platform-functionality/change-logging.md +0 -21
  773. nautobot/docs/user-guide/platform-functionality/computedfield.md +0 -89
  774. nautobot/docs/user-guide/platform-functionality/customfield.md +0 -123
  775. nautobot/docs/user-guide/platform-functionality/customlink.md +0 -59
  776. nautobot/docs/user-guide/platform-functionality/dynamicgroup.md +0 -660
  777. nautobot/docs/user-guide/platform-functionality/exporttemplate.md +0 -55
  778. nautobot/docs/user-guide/platform-functionality/gitrepository.md +0 -353
  779. nautobot/docs/user-guide/platform-functionality/graphql.md +0 -259
  780. nautobot/docs/user-guide/platform-functionality/graphqlquery.md +0 -28
  781. nautobot/docs/user-guide/platform-functionality/imageattachment.md +0 -10
  782. nautobot/docs/user-guide/platform-functionality/jobs/index.md +0 -193
  783. nautobot/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.md +0 -78
  784. nautobot/docs/user-guide/platform-functionality/jobs/jobbutton.md +0 -79
  785. nautobot/docs/user-guide/platform-functionality/jobs/jobhook.md +0 -15
  786. nautobot/docs/user-guide/platform-functionality/jobs/models.md +0 -65
  787. nautobot/docs/user-guide/platform-functionality/napalm.md +0 -85
  788. nautobot/docs/user-guide/platform-functionality/note.md +0 -7
  789. nautobot/docs/user-guide/platform-functionality/relationship.md +0 -158
  790. nautobot/docs/user-guide/platform-functionality/rest-api/authentication.md +0 -67
  791. nautobot/docs/user-guide/platform-functionality/rest-api/filtering.md +0 -142
  792. nautobot/docs/user-guide/platform-functionality/rest-api/overview.md +0 -1045
  793. nautobot/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.md +0 -9
  794. nautobot/docs/user-guide/platform-functionality/role.md +0 -17
  795. nautobot/docs/user-guide/platform-functionality/secret.md +0 -136
  796. nautobot/docs/user-guide/platform-functionality/status.md +0 -92
  797. nautobot/docs/user-guide/platform-functionality/tag.md +0 -62
  798. nautobot/docs/user-guide/platform-functionality/template-filters.md +0 -306
  799. nautobot/docs/user-guide/platform-functionality/users/objectpermission.md +0 -56
  800. nautobot/docs/user-guide/platform-functionality/users/token.md +0 -21
  801. nautobot/docs/user-guide/platform-functionality/webhook.md +0 -137
  802. nautobot/project-static/docs/media/nautobot_application_stack_low_level.drawio +0 -1
  803. nautobot/project-static/docs/media/nautobot_chatops.gif +0 -0
  804. nautobot/project-static/docs/media/nautobot_config_context.gif +0 -0
  805. nautobot/project-static/docs/media/nautobot_golden_config.gif +0 -0
  806. nautobot/project-static/docs/media/nautobot_graphql.gif +0 -0
  807. nautobot/project-static/docs/media/nautobot_mainpage.gif +0 -0
  808. nautobot/project-static/docs/media/nautobot_prefix_hierarchy.gif +0 -0
  809. nautobot-2.0.4.dist-info/LICENSE.txt +0 -177
  810. /LICENSE.txt → /nautobot-2.1.0b1.dist-info/LICENSE.txt +0 -0
  811. {nautobot-2.0.4.dist-info → nautobot-2.1.0b1.dist-info}/WHEEL +0 -0
  812. {nautobot-2.0.4.dist-info → nautobot-2.1.0b1.dist-info}/entry_points.txt +0 -0
@@ -17,7 +17,7 @@
17
17
  <link rel="next" href="views.html">
18
18
 
19
19
  <link rel="icon" href="../../../assets/favicon.ico">
20
- <meta name="generator" content="mkdocs-1.4.3, mkdocs-material-9.1.20">
20
+ <meta name="generator" content="mkdocs-1.5.3, mkdocs-material-9.1.21">
21
21
 
22
22
 
23
23
 
@@ -2659,6 +2659,20 @@
2659
2659
 
2660
2660
 
2661
2661
 
2662
+ <li class="md-nav__item">
2663
+ <a href="../../../user-guide/platform-functionality/externalintegration.html" class="md-nav__link">
2664
+ External Integrations
2665
+ </a>
2666
+ </li>
2667
+
2668
+
2669
+
2670
+
2671
+
2672
+
2673
+
2674
+
2675
+
2662
2676
  <li class="md-nav__item">
2663
2677
  <a href="../../../user-guide/platform-functionality/gitrepository.html" class="md-nav__link">
2664
2678
  Git Repositories
@@ -2679,7 +2693,7 @@
2679
2693
 
2680
2694
 
2681
2695
 
2682
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_8" >
2696
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_9" >
2683
2697
 
2684
2698
 
2685
2699
 
@@ -2688,14 +2702,14 @@
2688
2702
  <div class="md-nav__link md-nav__link--index ">
2689
2703
  <a href="../../../user-guide/platform-functionality/graphql.html">GraphQL</a>
2690
2704
 
2691
- <label for="__nav_2_4_8">
2705
+ <label for="__nav_2_4_9">
2692
2706
  <span class="md-nav__icon md-icon"></span>
2693
2707
  </label>
2694
2708
 
2695
2709
  </div>
2696
2710
 
2697
- <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_8_label" aria-expanded="false">
2698
- <label class="md-nav__title" for="__nav_2_4_8">
2711
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_9_label" aria-expanded="false">
2712
+ <label class="md-nav__title" for="__nav_2_4_9">
2699
2713
  <span class="md-nav__icon md-icon"></span>
2700
2714
  GraphQL
2701
2715
  </label>
@@ -2747,7 +2761,7 @@
2747
2761
 
2748
2762
 
2749
2763
 
2750
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_10" >
2764
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_11" >
2751
2765
 
2752
2766
 
2753
2767
 
@@ -2756,14 +2770,14 @@
2756
2770
  <div class="md-nav__link md-nav__link--index ">
2757
2771
  <a href="../../../user-guide/platform-functionality/jobs/index.html">Jobs</a>
2758
2772
 
2759
- <label for="__nav_2_4_10">
2773
+ <label for="__nav_2_4_11">
2760
2774
  <span class="md-nav__icon md-icon"></span>
2761
2775
  </label>
2762
2776
 
2763
2777
  </div>
2764
2778
 
2765
- <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_10_label" aria-expanded="false">
2766
- <label class="md-nav__title" for="__nav_2_4_10">
2779
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_11_label" aria-expanded="false">
2780
+ <label class="md-nav__title" for="__nav_2_4_11">
2767
2781
  <span class="md-nav__icon md-icon"></span>
2768
2782
  Jobs
2769
2783
  </label>
@@ -2885,7 +2899,7 @@
2885
2899
 
2886
2900
 
2887
2901
 
2888
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_14" >
2902
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_15" >
2889
2903
 
2890
2904
 
2891
2905
 
@@ -2894,14 +2908,14 @@
2894
2908
  <div class="md-nav__link md-nav__link--index ">
2895
2909
  <a href="../../../user-guide/platform-functionality/rest-api/overview.html">REST API</a>
2896
2910
 
2897
- <label for="__nav_2_4_14">
2911
+ <label for="__nav_2_4_15">
2898
2912
  <span class="md-nav__icon md-icon"></span>
2899
2913
  </label>
2900
2914
 
2901
2915
  </div>
2902
2916
 
2903
- <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_14_label" aria-expanded="false">
2904
- <label class="md-nav__title" for="__nav_2_4_14">
2917
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_15_label" aria-expanded="false">
2918
+ <label class="md-nav__title" for="__nav_2_4_15">
2905
2919
  <span class="md-nav__icon md-icon"></span>
2906
2920
  REST API
2907
2921
  </label>
@@ -3037,17 +3051,17 @@
3037
3051
 
3038
3052
 
3039
3053
 
3040
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_20" >
3054
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_21" >
3041
3055
 
3042
3056
 
3043
3057
 
3044
- <label class="md-nav__link" for="__nav_2_4_20" id="__nav_2_4_20_label" tabindex="0">
3058
+ <label class="md-nav__link" for="__nav_2_4_21" id="__nav_2_4_21_label" tabindex="0">
3045
3059
  Users
3046
3060
  <span class="md-nav__icon md-icon"></span>
3047
3061
  </label>
3048
3062
 
3049
- <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_20_label" aria-expanded="false">
3050
- <label class="md-nav__title" for="__nav_2_4_20">
3063
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_21_label" aria-expanded="false">
3064
+ <label class="md-nav__title" for="__nav_2_4_21">
3051
3065
  <span class="md-nav__icon md-icon"></span>
3052
3066
  Users
3053
3067
  </label>
@@ -5353,6 +5367,20 @@
5353
5367
 
5354
5368
 
5355
5369
 
5370
+ <li class="md-nav__item">
5371
+ <a href="../../../release-notes/version-2.1.html" class="md-nav__link">
5372
+ Version 2.1
5373
+ </a>
5374
+ </li>
5375
+
5376
+
5377
+
5378
+
5379
+
5380
+
5381
+
5382
+
5383
+
5356
5384
  <li class="md-nav__item">
5357
5385
  <a href="../../../release-notes/version-2.0.html" class="md-nav__link">
5358
5386
  Version 2.0
@@ -7705,8 +7733,7 @@ suitable for use as <code>choices</code> on a choice field:</p>
7705
7733
 
7706
7734
  <details class="quote">
7707
7735
  <summary>Source code in <code>nautobot/core/utils/filtering.py</code></summary>
7708
- <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-21">21</a></span>
7709
- <span class="normal"><a href="#__codelineno-0-22">22</a></span>
7736
+ <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-22">22</a></span>
7710
7737
  <span class="normal"><a href="#__codelineno-0-23">23</a></span>
7711
7738
  <span class="normal"><a href="#__codelineno-0-24">24</a></span>
7712
7739
  <span class="normal"><a href="#__codelineno-0-25">25</a></span>
@@ -7725,27 +7752,28 @@ suitable for use as <code>choices</code> on a choice field:</p>
7725
7752
  <span class="normal"><a href="#__codelineno-0-38">38</a></span>
7726
7753
  <span class="normal"><a href="#__codelineno-0-39">39</a></span>
7727
7754
  <span class="normal"><a href="#__codelineno-0-40">40</a></span>
7728
- <span class="normal"><a href="#__codelineno-0-41">41</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-21" name="__codelineno-0-21"></a><span class="k">def</span> <span class="nf">build_lookup_label</span><span class="p">(</span><span class="n">field_name</span><span class="p">,</span> <span class="n">_verbose_name</span><span class="p">):</span>
7729
- <a id="__codelineno-0-22" name="__codelineno-0-22"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
7730
- <a id="__codelineno-0-23" name="__codelineno-0-23"></a><span class="sd"> Return lookup expr with its verbose name</span>
7731
- <a id="__codelineno-0-24" name="__codelineno-0-24"></a>
7732
- <a id="__codelineno-0-25" name="__codelineno-0-25"></a><span class="sd"> Args:</span>
7733
- <a id="__codelineno-0-26" name="__codelineno-0-26"></a><span class="sd"> field_name (str): Field name e.g name__iew</span>
7734
- <a id="__codelineno-0-27" name="__codelineno-0-27"></a><span class="sd"> _verbose_name (str): The verbose name for the lookup expr which is suffixed to the field name e.g iew -&gt; iendswith</span>
7735
- <a id="__codelineno-0-28" name="__codelineno-0-28"></a>
7736
- <a id="__codelineno-0-29" name="__codelineno-0-29"></a><span class="sd"> Examples:</span>
7737
- <a id="__codelineno-0-30" name="__codelineno-0-30"></a><span class="sd"> &gt;&gt;&gt; build_lookup_label(&quot;name__iew&quot;, &quot;iendswith&quot;)</span>
7738
- <a id="__codelineno-0-31" name="__codelineno-0-31"></a><span class="sd"> &gt;&gt;&gt; &quot;ends-with (iew)&quot;</span>
7739
- <a id="__codelineno-0-32" name="__codelineno-0-32"></a><span class="sd"> &quot;&quot;&quot;</span>
7740
- <a id="__codelineno-0-33" name="__codelineno-0-33"></a> <span class="n">verbose_name</span> <span class="o">=</span> <span class="n">verbose_lookup_expr</span><span class="p">(</span><span class="n">_verbose_name</span><span class="p">)</span> <span class="ow">or</span> <span class="s2">&quot;exact&quot;</span>
7741
- <a id="__codelineno-0-34" name="__codelineno-0-34"></a> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
7742
- <a id="__codelineno-0-35" name="__codelineno-0-35"></a> <span class="n">search</span> <span class="o">=</span> <span class="n">CONTAINS_LOOKUP_EXPR_RE</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">field_name</span><span class="p">)</span>
7743
- <a id="__codelineno-0-36" name="__codelineno-0-36"></a> <span class="k">if</span> <span class="n">search</span><span class="p">:</span>
7744
- <a id="__codelineno-0-37" name="__codelineno-0-37"></a> <span class="n">label</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot; (</span><span class="si">{</span><span class="n">search</span><span class="o">.</span><span class="n">group</span><span class="p">()</span><span class="si">}</span><span class="s2">)&quot;</span>
7745
- <a id="__codelineno-0-38" name="__codelineno-0-38"></a>
7746
- <a id="__codelineno-0-39" name="__codelineno-0-39"></a> <span class="n">verbose_name</span> <span class="o">=</span> <span class="s2">&quot;not &quot;</span> <span class="o">+</span> <span class="n">verbose_name</span> <span class="k">if</span> <span class="n">label</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot; (n&quot;</span><span class="p">)</span> <span class="k">else</span> <span class="n">verbose_name</span>
7747
- <a id="__codelineno-0-40" name="__codelineno-0-40"></a>
7748
- <a id="__codelineno-0-41" name="__codelineno-0-41"></a> <span class="k">return</span> <span class="n">verbose_name</span> <span class="o">+</span> <span class="n">label</span>
7755
+ <span class="normal"><a href="#__codelineno-0-41">41</a></span>
7756
+ <span class="normal"><a href="#__codelineno-0-42">42</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-22" name="__codelineno-0-22"></a><span class="k">def</span> <span class="nf">build_lookup_label</span><span class="p">(</span><span class="n">field_name</span><span class="p">,</span> <span class="n">_verbose_name</span><span class="p">):</span>
7757
+ <a id="__codelineno-0-23" name="__codelineno-0-23"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
7758
+ <a id="__codelineno-0-24" name="__codelineno-0-24"></a><span class="sd"> Return lookup expr with its verbose name</span>
7759
+ <a id="__codelineno-0-25" name="__codelineno-0-25"></a>
7760
+ <a id="__codelineno-0-26" name="__codelineno-0-26"></a><span class="sd"> Args:</span>
7761
+ <a id="__codelineno-0-27" name="__codelineno-0-27"></a><span class="sd"> field_name (str): Field name e.g name__iew</span>
7762
+ <a id="__codelineno-0-28" name="__codelineno-0-28"></a><span class="sd"> _verbose_name (str): The verbose name for the lookup expr which is suffixed to the field name e.g iew -&gt; iendswith</span>
7763
+ <a id="__codelineno-0-29" name="__codelineno-0-29"></a>
7764
+ <a id="__codelineno-0-30" name="__codelineno-0-30"></a><span class="sd"> Examples:</span>
7765
+ <a id="__codelineno-0-31" name="__codelineno-0-31"></a><span class="sd"> &gt;&gt;&gt; build_lookup_label(&quot;name__iew&quot;, &quot;iendswith&quot;)</span>
7766
+ <a id="__codelineno-0-32" name="__codelineno-0-32"></a><span class="sd"> &gt;&gt;&gt; &quot;ends-with (iew)&quot;</span>
7767
+ <a id="__codelineno-0-33" name="__codelineno-0-33"></a><span class="sd"> &quot;&quot;&quot;</span>
7768
+ <a id="__codelineno-0-34" name="__codelineno-0-34"></a> <span class="n">verbose_name</span> <span class="o">=</span> <span class="n">verbose_lookup_expr</span><span class="p">(</span><span class="n">_verbose_name</span><span class="p">)</span> <span class="ow">or</span> <span class="s2">&quot;exact&quot;</span>
7769
+ <a id="__codelineno-0-35" name="__codelineno-0-35"></a> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
7770
+ <a id="__codelineno-0-36" name="__codelineno-0-36"></a> <span class="n">search</span> <span class="o">=</span> <span class="n">CONTAINS_LOOKUP_EXPR_RE</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">field_name</span><span class="p">)</span>
7771
+ <a id="__codelineno-0-37" name="__codelineno-0-37"></a> <span class="k">if</span> <span class="n">search</span><span class="p">:</span>
7772
+ <a id="__codelineno-0-38" name="__codelineno-0-38"></a> <span class="n">label</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot; (</span><span class="si">{</span><span class="n">search</span><span class="o">.</span><span class="n">group</span><span class="p">()</span><span class="si">}</span><span class="s2">)&quot;</span>
7773
+ <a id="__codelineno-0-39" name="__codelineno-0-39"></a>
7774
+ <a id="__codelineno-0-40" name="__codelineno-0-40"></a> <span class="n">verbose_name</span> <span class="o">=</span> <span class="s2">&quot;not &quot;</span> <span class="o">+</span> <span class="n">verbose_name</span> <span class="k">if</span> <span class="n">label</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot; (n&quot;</span><span class="p">)</span> <span class="k">else</span> <span class="n">verbose_name</span>
7775
+ <a id="__codelineno-0-41" name="__codelineno-0-41"></a>
7776
+ <a id="__codelineno-0-42" name="__codelineno-0-42"></a> <span class="k">return</span> <span class="n">verbose_name</span> <span class="o">+</span> <span class="n">label</span>
7749
7777
  </code></pre></div></td></tr></table></div>
7750
7778
  </details>
7751
7779
  </div>
@@ -8603,8 +8631,7 @@ while discarding <code>querydict</code> params which are not part of <code>filte
8603
8631
 
8604
8632
  <details class="quote">
8605
8633
  <summary>Source code in <code>nautobot/core/utils/filtering.py</code></summary>
8606
- <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-44">44</a></span>
8607
- <span class="normal"><a href="#__codelineno-0-45">45</a></span>
8634
+ <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-45">45</a></span>
8608
8635
  <span class="normal"><a href="#__codelineno-0-46">46</a></span>
8609
8636
  <span class="normal"><a href="#__codelineno-0-47">47</a></span>
8610
8637
  <span class="normal"><a href="#__codelineno-0-48">48</a></span>
@@ -8634,38 +8661,39 @@ while discarding <code>querydict</code> params which are not part of <code>filte
8634
8661
  <span class="normal"><a href="#__codelineno-0-72">72</a></span>
8635
8662
  <span class="normal"><a href="#__codelineno-0-73">73</a></span>
8636
8663
  <span class="normal"><a href="#__codelineno-0-74">74</a></span>
8637
- <span class="normal"><a href="#__codelineno-0-75">75</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-44" name="__codelineno-0-44"></a><span class="k">def</span> <span class="nf">get_all_lookup_expr_for_field</span><span class="p">(</span><span class="n">model</span><span class="p">,</span> <span class="n">field_name</span><span class="p">):</span>
8638
- <a id="__codelineno-0-45" name="__codelineno-0-45"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
8639
- <a id="__codelineno-0-46" name="__codelineno-0-46"></a><span class="sd"> Return all lookup expressions for `field_name` in `model` filterset</span>
8640
- <a id="__codelineno-0-47" name="__codelineno-0-47"></a><span class="sd"> &quot;&quot;&quot;</span>
8641
- <a id="__codelineno-0-48" name="__codelineno-0-48"></a> <span class="n">filterset</span> <span class="o">=</span> <span class="n">get_filterset_for_model</span><span class="p">(</span><span class="n">model</span><span class="p">)()</span><span class="o">.</span><span class="n">filters</span>
8642
- <a id="__codelineno-0-49" name="__codelineno-0-49"></a>
8643
- <a id="__codelineno-0-50" name="__codelineno-0-50"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">filterset</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">field_name</span><span class="p">):</span>
8644
- <a id="__codelineno-0-51" name="__codelineno-0-51"></a> <span class="k">raise</span> <span class="n">exceptions</span><span class="o">.</span><span class="n">FilterSetFieldNotFound</span><span class="p">(</span><span class="s2">&quot;field_name not found&quot;</span><span class="p">)</span>
8645
- <a id="__codelineno-0-52" name="__codelineno-0-52"></a>
8646
- <a id="__codelineno-0-53" name="__codelineno-0-53"></a> <span class="k">if</span> <span class="n">field_name</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;has_&quot;</span><span class="p">):</span>
8647
- <a id="__codelineno-0-54" name="__codelineno-0-54"></a> <span class="k">return</span> <span class="p">[{</span><span class="s2">&quot;id&quot;</span><span class="p">:</span> <span class="n">field_name</span><span class="p">,</span> <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;exact&quot;</span><span class="p">}]</span>
8648
- <a id="__codelineno-0-55" name="__codelineno-0-55"></a>
8649
- <a id="__codelineno-0-56" name="__codelineno-0-56"></a> <span class="n">lookup_expr_choices</span> <span class="o">=</span> <span class="p">[]</span>
8650
- <a id="__codelineno-0-57" name="__codelineno-0-57"></a>
8651
- <a id="__codelineno-0-58" name="__codelineno-0-58"></a> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">field</span> <span class="ow">in</span> <span class="n">filterset</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
8652
- <a id="__codelineno-0-59" name="__codelineno-0-59"></a> <span class="c1"># remove the lookup_expr from field_name e.g name__iew -&gt; name</span>
8653
- <a id="__codelineno-0-60" name="__codelineno-0-60"></a> <span class="k">if</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;__\w+&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="o">==</span> <span class="n">field_name</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">name</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;has_&quot;</span><span class="p">):</span>
8654
- <a id="__codelineno-0-61" name="__codelineno-0-61"></a> <span class="n">lookup_expr_choices</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
8655
- <a id="__codelineno-0-62" name="__codelineno-0-62"></a> <span class="p">{</span>
8656
- <a id="__codelineno-0-63" name="__codelineno-0-63"></a> <span class="s2">&quot;id&quot;</span><span class="p">:</span> <span class="n">name</span><span class="p">,</span>
8657
- <a id="__codelineno-0-64" name="__codelineno-0-64"></a> <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="n">build_lookup_label</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">field</span><span class="o">.</span><span class="n">lookup_expr</span><span class="p">),</span>
8658
- <a id="__codelineno-0-65" name="__codelineno-0-65"></a> <span class="p">}</span>
8659
- <a id="__codelineno-0-66" name="__codelineno-0-66"></a> <span class="p">)</span>
8660
- <a id="__codelineno-0-67" name="__codelineno-0-67"></a> <span class="k">elif</span> <span class="n">name</span> <span class="o">==</span> <span class="n">field_name</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">name</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;has_&quot;</span><span class="p">):</span>
8661
- <a id="__codelineno-0-68" name="__codelineno-0-68"></a> <span class="n">lookup_expr_choices</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
8662
- <a id="__codelineno-0-69" name="__codelineno-0-69"></a> <span class="p">{</span>
8663
- <a id="__codelineno-0-70" name="__codelineno-0-70"></a> <span class="s2">&quot;id&quot;</span><span class="p">:</span> <span class="n">name</span><span class="p">,</span>
8664
- <a id="__codelineno-0-71" name="__codelineno-0-71"></a> <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;exact&quot;</span><span class="p">,</span>
8665
- <a id="__codelineno-0-72" name="__codelineno-0-72"></a> <span class="p">}</span>
8666
- <a id="__codelineno-0-73" name="__codelineno-0-73"></a> <span class="p">)</span>
8667
- <a id="__codelineno-0-74" name="__codelineno-0-74"></a>
8668
- <a id="__codelineno-0-75" name="__codelineno-0-75"></a> <span class="k">return</span> <span class="n">lookup_expr_choices</span>
8664
+ <span class="normal"><a href="#__codelineno-0-75">75</a></span>
8665
+ <span class="normal"><a href="#__codelineno-0-76">76</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-45" name="__codelineno-0-45"></a><span class="k">def</span> <span class="nf">get_all_lookup_expr_for_field</span><span class="p">(</span><span class="n">model</span><span class="p">,</span> <span class="n">field_name</span><span class="p">):</span>
8666
+ <a id="__codelineno-0-46" name="__codelineno-0-46"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
8667
+ <a id="__codelineno-0-47" name="__codelineno-0-47"></a><span class="sd"> Return all lookup expressions for `field_name` in `model` filterset</span>
8668
+ <a id="__codelineno-0-48" name="__codelineno-0-48"></a><span class="sd"> &quot;&quot;&quot;</span>
8669
+ <a id="__codelineno-0-49" name="__codelineno-0-49"></a> <span class="n">filterset</span> <span class="o">=</span> <span class="n">get_filterset_for_model</span><span class="p">(</span><span class="n">model</span><span class="p">)()</span><span class="o">.</span><span class="n">filters</span>
8670
+ <a id="__codelineno-0-50" name="__codelineno-0-50"></a>
8671
+ <a id="__codelineno-0-51" name="__codelineno-0-51"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">filterset</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">field_name</span><span class="p">):</span>
8672
+ <a id="__codelineno-0-52" name="__codelineno-0-52"></a> <span class="k">raise</span> <span class="n">exceptions</span><span class="o">.</span><span class="n">FilterSetFieldNotFound</span><span class="p">(</span><span class="s2">&quot;field_name not found&quot;</span><span class="p">)</span>
8673
+ <a id="__codelineno-0-53" name="__codelineno-0-53"></a>
8674
+ <a id="__codelineno-0-54" name="__codelineno-0-54"></a> <span class="k">if</span> <span class="n">field_name</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;has_&quot;</span><span class="p">):</span>
8675
+ <a id="__codelineno-0-55" name="__codelineno-0-55"></a> <span class="k">return</span> <span class="p">[{</span><span class="s2">&quot;id&quot;</span><span class="p">:</span> <span class="n">field_name</span><span class="p">,</span> <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;exact&quot;</span><span class="p">}]</span>
8676
+ <a id="__codelineno-0-56" name="__codelineno-0-56"></a>
8677
+ <a id="__codelineno-0-57" name="__codelineno-0-57"></a> <span class="n">lookup_expr_choices</span> <span class="o">=</span> <span class="p">[]</span>
8678
+ <a id="__codelineno-0-58" name="__codelineno-0-58"></a>
8679
+ <a id="__codelineno-0-59" name="__codelineno-0-59"></a> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">field</span> <span class="ow">in</span> <span class="n">filterset</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
8680
+ <a id="__codelineno-0-60" name="__codelineno-0-60"></a> <span class="c1"># remove the lookup_expr from field_name e.g name__iew -&gt; name</span>
8681
+ <a id="__codelineno-0-61" name="__codelineno-0-61"></a> <span class="k">if</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;__\w+&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="o">==</span> <span class="n">field_name</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">name</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;has_&quot;</span><span class="p">):</span>
8682
+ <a id="__codelineno-0-62" name="__codelineno-0-62"></a> <span class="n">lookup_expr_choices</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
8683
+ <a id="__codelineno-0-63" name="__codelineno-0-63"></a> <span class="p">{</span>
8684
+ <a id="__codelineno-0-64" name="__codelineno-0-64"></a> <span class="s2">&quot;id&quot;</span><span class="p">:</span> <span class="n">name</span><span class="p">,</span>
8685
+ <a id="__codelineno-0-65" name="__codelineno-0-65"></a> <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="n">build_lookup_label</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">field</span><span class="o">.</span><span class="n">lookup_expr</span><span class="p">),</span>
8686
+ <a id="__codelineno-0-66" name="__codelineno-0-66"></a> <span class="p">}</span>
8687
+ <a id="__codelineno-0-67" name="__codelineno-0-67"></a> <span class="p">)</span>
8688
+ <a id="__codelineno-0-68" name="__codelineno-0-68"></a> <span class="k">elif</span> <span class="n">name</span> <span class="o">==</span> <span class="n">field_name</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">name</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;has_&quot;</span><span class="p">):</span>
8689
+ <a id="__codelineno-0-69" name="__codelineno-0-69"></a> <span class="n">lookup_expr_choices</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
8690
+ <a id="__codelineno-0-70" name="__codelineno-0-70"></a> <span class="p">{</span>
8691
+ <a id="__codelineno-0-71" name="__codelineno-0-71"></a> <span class="s2">&quot;id&quot;</span><span class="p">:</span> <span class="n">name</span><span class="p">,</span>
8692
+ <a id="__codelineno-0-72" name="__codelineno-0-72"></a> <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;exact&quot;</span><span class="p">,</span>
8693
+ <a id="__codelineno-0-73" name="__codelineno-0-73"></a> <span class="p">}</span>
8694
+ <a id="__codelineno-0-74" name="__codelineno-0-74"></a> <span class="p">)</span>
8695
+ <a id="__codelineno-0-75" name="__codelineno-0-75"></a>
8696
+ <a id="__codelineno-0-76" name="__codelineno-0-76"></a> <span class="k">return</span> <span class="n">lookup_expr_choices</span>
8669
8697
  </code></pre></div></td></tr></table></div>
8670
8698
  </details>
8671
8699
  </div>
@@ -8922,9 +8950,7 @@ by the model class. If an instance is provided, the queryset will also be filter
8922
8950
 
8923
8951
  <details class="quote">
8924
8952
  <summary>Source code in <code>nautobot/core/utils/filtering.py</code></summary>
8925
- <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-168">168</a></span>
8926
- <span class="normal"><a href="#__codelineno-0-169">169</a></span>
8927
- <span class="normal"><a href="#__codelineno-0-170">170</a></span>
8953
+ <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-170">170</a></span>
8928
8954
  <span class="normal"><a href="#__codelineno-0-171">171</a></span>
8929
8955
  <span class="normal"><a href="#__codelineno-0-172">172</a></span>
8930
8956
  <span class="normal"><a href="#__codelineno-0-173">173</a></span>
@@ -8940,25 +8966,27 @@ by the model class. If an instance is provided, the queryset will also be filter
8940
8966
  <span class="normal"><a href="#__codelineno-0-183">183</a></span>
8941
8967
  <span class="normal"><a href="#__codelineno-0-184">184</a></span>
8942
8968
  <span class="normal"><a href="#__codelineno-0-185">185</a></span>
8943
- <span class="normal"><a href="#__codelineno-0-186">186</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-168" name="__codelineno-0-168"></a><span class="k">def</span> <span class="nf">get_filter_field_label</span><span class="p">(</span><span class="n">filter_field</span><span class="p">):</span>
8944
- <a id="__codelineno-0-169" name="__codelineno-0-169"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
8945
- <a id="__codelineno-0-170" name="__codelineno-0-170"></a><span class="sd"> Return a label for a given field name and value.</span>
8946
- <a id="__codelineno-0-171" name="__codelineno-0-171"></a>
8947
- <a id="__codelineno-0-172" name="__codelineno-0-172"></a><span class="sd"> Args:</span>
8948
- <a id="__codelineno-0-173" name="__codelineno-0-173"></a><span class="sd"> filter_field (Filter): The filter to get a label for</span>
8949
- <a id="__codelineno-0-174" name="__codelineno-0-174"></a>
8950
- <a id="__codelineno-0-175" name="__codelineno-0-175"></a><span class="sd"> Returns:</span>
8951
- <a id="__codelineno-0-176" name="__codelineno-0-176"></a><span class="sd"> (str): The label for the given field</span>
8952
- <a id="__codelineno-0-177" name="__codelineno-0-177"></a><span class="sd"> &quot;&quot;&quot;</span>
8953
- <a id="__codelineno-0-178" name="__codelineno-0-178"></a>
8954
- <a id="__codelineno-0-179" name="__codelineno-0-179"></a> <span class="k">if</span> <span class="n">filter_field</span><span class="o">.</span><span class="n">label</span><span class="p">:</span>
8955
- <a id="__codelineno-0-180" name="__codelineno-0-180"></a> <span class="k">return</span> <span class="n">filter_field</span><span class="o">.</span><span class="n">label</span>
8956
- <a id="__codelineno-0-181" name="__codelineno-0-181"></a> <span class="k">elif</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">filter_field</span><span class="p">,</span> <span class="s2">&quot;relationship&quot;</span><span class="p">):</span>
8957
- <a id="__codelineno-0-182" name="__codelineno-0-182"></a> <span class="k">return</span> <span class="n">filter_field</span><span class="o">.</span><span class="n">relationship</span><span class="o">.</span><span class="n">get_label</span><span class="p">(</span><span class="n">side</span><span class="o">=</span><span class="n">filter_field</span><span class="o">.</span><span class="n">side</span><span class="p">)</span>
8958
- <a id="__codelineno-0-183" name="__codelineno-0-183"></a> <span class="k">elif</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">filter_field</span><span class="p">,</span> <span class="s2">&quot;custom_field&quot;</span><span class="p">):</span>
8959
- <a id="__codelineno-0-184" name="__codelineno-0-184"></a> <span class="k">return</span> <span class="n">filter_field</span><span class="o">.</span><span class="n">custom_field</span><span class="o">.</span><span class="n">label</span>
8960
- <a id="__codelineno-0-185" name="__codelineno-0-185"></a> <span class="k">else</span><span class="p">:</span>
8961
- <a id="__codelineno-0-186" name="__codelineno-0-186"></a> <span class="k">return</span> <span class="n">_field_name_to_display</span><span class="p">(</span><span class="n">filter_field</span><span class="o">.</span><span class="n">field_name</span><span class="p">)</span>
8969
+ <span class="normal"><a href="#__codelineno-0-186">186</a></span>
8970
+ <span class="normal"><a href="#__codelineno-0-187">187</a></span>
8971
+ <span class="normal"><a href="#__codelineno-0-188">188</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-170" name="__codelineno-0-170"></a><span class="k">def</span> <span class="nf">get_filter_field_label</span><span class="p">(</span><span class="n">filter_field</span><span class="p">):</span>
8972
+ <a id="__codelineno-0-171" name="__codelineno-0-171"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
8973
+ <a id="__codelineno-0-172" name="__codelineno-0-172"></a><span class="sd"> Return a label for a given field name and value.</span>
8974
+ <a id="__codelineno-0-173" name="__codelineno-0-173"></a>
8975
+ <a id="__codelineno-0-174" name="__codelineno-0-174"></a><span class="sd"> Args:</span>
8976
+ <a id="__codelineno-0-175" name="__codelineno-0-175"></a><span class="sd"> filter_field (Filter): The filter to get a label for</span>
8977
+ <a id="__codelineno-0-176" name="__codelineno-0-176"></a>
8978
+ <a id="__codelineno-0-177" name="__codelineno-0-177"></a><span class="sd"> Returns:</span>
8979
+ <a id="__codelineno-0-178" name="__codelineno-0-178"></a><span class="sd"> (str): The label for the given field</span>
8980
+ <a id="__codelineno-0-179" name="__codelineno-0-179"></a><span class="sd"> &quot;&quot;&quot;</span>
8981
+ <a id="__codelineno-0-180" name="__codelineno-0-180"></a>
8982
+ <a id="__codelineno-0-181" name="__codelineno-0-181"></a> <span class="k">if</span> <span class="n">filter_field</span><span class="o">.</span><span class="n">label</span><span class="p">:</span>
8983
+ <a id="__codelineno-0-182" name="__codelineno-0-182"></a> <span class="k">return</span> <span class="n">filter_field</span><span class="o">.</span><span class="n">label</span>
8984
+ <a id="__codelineno-0-183" name="__codelineno-0-183"></a> <span class="k">elif</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">filter_field</span><span class="p">,</span> <span class="s2">&quot;relationship&quot;</span><span class="p">):</span>
8985
+ <a id="__codelineno-0-184" name="__codelineno-0-184"></a> <span class="k">return</span> <span class="n">filter_field</span><span class="o">.</span><span class="n">relationship</span><span class="o">.</span><span class="n">get_label</span><span class="p">(</span><span class="n">side</span><span class="o">=</span><span class="n">filter_field</span><span class="o">.</span><span class="n">side</span><span class="p">)</span>
8986
+ <a id="__codelineno-0-185" name="__codelineno-0-185"></a> <span class="k">elif</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">filter_field</span><span class="p">,</span> <span class="s2">&quot;custom_field&quot;</span><span class="p">):</span>
8987
+ <a id="__codelineno-0-186" name="__codelineno-0-186"></a> <span class="k">return</span> <span class="n">filter_field</span><span class="o">.</span><span class="n">custom_field</span><span class="o">.</span><span class="n">label</span>
8988
+ <a id="__codelineno-0-187" name="__codelineno-0-187"></a> <span class="k">else</span><span class="p">:</span>
8989
+ <a id="__codelineno-0-188" name="__codelineno-0-188"></a> <span class="k">return</span> <span class="n">_field_name_to_display</span><span class="p">(</span><span class="n">filter_field</span><span class="o">.</span><span class="n">field_name</span><span class="p">)</span>
8962
8990
  </code></pre></div></td></tr></table></div>
8963
8991
  </details>
8964
8992
  </div>
@@ -9097,8 +9125,7 @@ to return only queryset filterable parameters.</p>
9097
9125
  <span class="normal"><a href="#__codelineno-0-133">133</a></span>
9098
9126
  <span class="normal"><a href="#__codelineno-0-134">134</a></span>
9099
9127
  <span class="normal"><a href="#__codelineno-0-135">135</a></span>
9100
- <span class="normal"><a href="#__codelineno-0-136">136</a></span>
9101
- <span class="normal"><a href="#__codelineno-0-137">137</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-104" name="__codelineno-0-104"></a><span class="k">def</span> <span class="nf">get_filterable_params_from_filter_params</span><span class="p">(</span><span class="n">filter_params</span><span class="p">,</span> <span class="n">non_filter_params</span><span class="p">,</span> <span class="n">filterset</span><span class="p">):</span>
9128
+ <span class="normal"><a href="#__codelineno-0-136">136</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-104" name="__codelineno-0-104"></a><span class="k">def</span> <span class="nf">get_filterable_params_from_filter_params</span><span class="p">(</span><span class="n">filter_params</span><span class="p">,</span> <span class="n">non_filter_params</span><span class="p">,</span> <span class="n">filterset</span><span class="p">):</span>
9102
9129
  <a id="__codelineno-0-105" name="__codelineno-0-105"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
9103
9130
  <a id="__codelineno-0-106" name="__codelineno-0-106"></a><span class="sd"> Remove any `non_filter_params` and fields that are not a part of the filterset from `filter_params`</span>
9104
9131
  <a id="__codelineno-0-107" name="__codelineno-0-107"></a><span class="sd"> to return only queryset filterable parameters.</span>
@@ -9111,27 +9138,26 @@ to return only queryset filterable parameters.</p>
9111
9138
  <a id="__codelineno-0-114" name="__codelineno-0-114"></a><span class="sd"> Returns:</span>
9112
9139
  <a id="__codelineno-0-115" name="__codelineno-0-115"></a><span class="sd"> (QueryDict): Filter param querydict with only queryset filterable params</span>
9113
9140
  <a id="__codelineno-0-116" name="__codelineno-0-116"></a><span class="sd"> &quot;&quot;&quot;</span>
9114
- <a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="k">for</span> <span class="n">non_filter_param</span> <span class="ow">in</span> <span class="n">non_filter_params</span><span class="p">:</span>
9115
- <a id="__codelineno-0-118" name="__codelineno-0-118"></a> <span class="n">filter_params</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">non_filter_param</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
9116
- <a id="__codelineno-0-119" name="__codelineno-0-119"></a>
9117
- <a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="c1"># Some FilterSet field only accept single choice not multiple choices</span>
9118
- <a id="__codelineno-0-121" name="__codelineno-0-121"></a> <span class="c1"># e.g datetime field, bool fields etc.</span>
9119
- <a id="__codelineno-0-122" name="__codelineno-0-122"></a> <span class="n">final_filter_params</span> <span class="o">=</span> <span class="p">{}</span>
9120
- <a id="__codelineno-0-123" name="__codelineno-0-123"></a> <span class="k">for</span> <span class="n">field</span> <span class="ow">in</span> <span class="n">filter_params</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
9121
- <a id="__codelineno-0-124" name="__codelineno-0-124"></a> <span class="k">if</span> <span class="n">filter_params</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">field</span><span class="p">):</span>
9122
- <a id="__codelineno-0-125" name="__codelineno-0-125"></a> <span class="c1"># `is_single_choice_field` implements `get_filterset_field`, which throws an exception if a field is not found.</span>
9123
- <a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="c1"># If an exception is thrown, instead of throwing an exception, set `_is_single_choice_field` to &#39;False&#39;</span>
9124
- <a id="__codelineno-0-127" name="__codelineno-0-127"></a> <span class="c1"># because the fields that were not discovered are still necessary.</span>
9125
- <a id="__codelineno-0-128" name="__codelineno-0-128"></a> <span class="k">try</span><span class="p">:</span>
9126
- <a id="__codelineno-0-129" name="__codelineno-0-129"></a> <span class="n">_is_single_choice_field</span> <span class="o">=</span> <span class="n">is_single_choice_field</span><span class="p">(</span><span class="n">filterset</span><span class="p">,</span> <span class="n">field</span><span class="p">)</span>
9127
- <a id="__codelineno-0-130" name="__codelineno-0-130"></a> <span class="k">except</span> <span class="n">exceptions</span><span class="o">.</span><span class="n">FilterSetFieldNotFound</span><span class="p">:</span>
9128
- <a id="__codelineno-0-131" name="__codelineno-0-131"></a> <span class="n">_is_single_choice_field</span> <span class="o">=</span> <span class="kc">False</span>
9129
- <a id="__codelineno-0-132" name="__codelineno-0-132"></a>
9130
- <a id="__codelineno-0-133" name="__codelineno-0-133"></a> <span class="n">final_filter_params</span><span class="p">[</span><span class="n">field</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span>
9131
- <a id="__codelineno-0-134" name="__codelineno-0-134"></a> <span class="n">filter_params</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">field</span><span class="p">)</span> <span class="k">if</span> <span class="n">_is_single_choice_field</span> <span class="k">else</span> <span class="n">filter_params</span><span class="o">.</span><span class="n">getlist</span><span class="p">(</span><span class="n">field</span><span class="p">)</span>
9132
- <a id="__codelineno-0-135" name="__codelineno-0-135"></a> <span class="p">)</span>
9133
- <a id="__codelineno-0-136" name="__codelineno-0-136"></a>
9134
- <a id="__codelineno-0-137" name="__codelineno-0-137"></a> <span class="k">return</span> <span class="n">final_filter_params</span>
9141
+ <a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="c1"># Some FilterSet field only accept single choice not multiple choices</span>
9142
+ <a id="__codelineno-0-118" name="__codelineno-0-118"></a> <span class="c1"># e.g datetime field, bool fields etc.</span>
9143
+ <a id="__codelineno-0-119" name="__codelineno-0-119"></a> <span class="n">final_filter_params</span> <span class="o">=</span> <span class="p">{}</span>
9144
+ <a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="k">for</span> <span class="n">field</span> <span class="ow">in</span> <span class="n">filter_params</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
9145
+ <a id="__codelineno-0-121" name="__codelineno-0-121"></a> <span class="k">if</span> <span class="n">field</span> <span class="ow">in</span> <span class="n">non_filter_params</span><span class="p">:</span>
9146
+ <a id="__codelineno-0-122" name="__codelineno-0-122"></a> <span class="k">continue</span>
9147
+ <a id="__codelineno-0-123" name="__codelineno-0-123"></a> <span class="k">if</span> <span class="n">filter_params</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">field</span><span class="p">):</span>
9148
+ <a id="__codelineno-0-124" name="__codelineno-0-124"></a> <span class="c1"># `is_single_choice_field` implements `get_filterset_field`, which throws an exception if a field is not found.</span>
9149
+ <a id="__codelineno-0-125" name="__codelineno-0-125"></a> <span class="c1"># If an exception is thrown, instead of throwing an exception, set `_is_single_choice_field` to &#39;False&#39;</span>
9150
+ <a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="c1"># because the fields that were not discovered are still necessary.</span>
9151
+ <a id="__codelineno-0-127" name="__codelineno-0-127"></a> <span class="k">try</span><span class="p">:</span>
9152
+ <a id="__codelineno-0-128" name="__codelineno-0-128"></a> <span class="n">_is_single_choice_field</span> <span class="o">=</span> <span class="n">is_single_choice_field</span><span class="p">(</span><span class="n">filterset</span><span class="p">,</span> <span class="n">field</span><span class="p">)</span>
9153
+ <a id="__codelineno-0-129" name="__codelineno-0-129"></a> <span class="k">except</span> <span class="n">exceptions</span><span class="o">.</span><span class="n">FilterSetFieldNotFound</span><span class="p">:</span>
9154
+ <a id="__codelineno-0-130" name="__codelineno-0-130"></a> <span class="n">_is_single_choice_field</span> <span class="o">=</span> <span class="kc">False</span>
9155
+ <a id="__codelineno-0-131" name="__codelineno-0-131"></a>
9156
+ <a id="__codelineno-0-132" name="__codelineno-0-132"></a> <span class="n">final_filter_params</span><span class="p">[</span><span class="n">field</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span>
9157
+ <a id="__codelineno-0-133" name="__codelineno-0-133"></a> <span class="n">filter_params</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">field</span><span class="p">)</span> <span class="k">if</span> <span class="n">_is_single_choice_field</span> <span class="k">else</span> <span class="n">filter_params</span><span class="o">.</span><span class="n">getlist</span><span class="p">(</span><span class="n">field</span><span class="p">)</span>
9158
+ <a id="__codelineno-0-134" name="__codelineno-0-134"></a> <span class="p">)</span>
9159
+ <a id="__codelineno-0-135" name="__codelineno-0-135"></a>
9160
+ <a id="__codelineno-0-136" name="__codelineno-0-136"></a> <span class="k">return</span> <span class="n">final_filter_params</span>
9135
9161
  </code></pre></div></td></tr></table></div>
9136
9162
  </details>
9137
9163
  </div>
@@ -9264,8 +9290,7 @@ associated with the model and its name is expected to be <code>{ModelName}Filter
9264
9290
 
9265
9291
  <details class="quote">
9266
9292
  <summary>Source code in <code>nautobot/core/utils/filtering.py</code></summary>
9267
- <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-85"> 85</a></span>
9268
- <span class="normal"><a href="#__codelineno-0-86"> 86</a></span>
9293
+ <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-86"> 86</a></span>
9269
9294
  <span class="normal"><a href="#__codelineno-0-87"> 87</a></span>
9270
9295
  <span class="normal"><a href="#__codelineno-0-88"> 88</a></span>
9271
9296
  <span class="normal"><a href="#__codelineno-0-89"> 89</a></span>
@@ -9344,87 +9369,90 @@ associated with the model and its name is expected to be <code>{ModelName}Filter
9344
9369
  <span class="normal"><a href="#__codelineno-0-162">162</a></span>
9345
9370
  <span class="normal"><a href="#__codelineno-0-163">163</a></span>
9346
9371
  <span class="normal"><a href="#__codelineno-0-164">164</a></span>
9347
- <span class="normal"><a href="#__codelineno-0-165">165</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-85" name="__codelineno-0-85"></a><span class="k">def</span> <span class="nf">get_filterset_parameter_form_field</span><span class="p">(</span><span class="n">model</span><span class="p">,</span> <span class="n">parameter</span><span class="p">,</span> <span class="n">filterset</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
9348
- <a id="__codelineno-0-86" name="__codelineno-0-86"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
9349
- <a id="__codelineno-0-87" name="__codelineno-0-87"></a><span class="sd"> Return the relevant form field instance for a filterset parameter e.g DynamicModelMultipleChoiceField, forms.IntegerField e.t.c</span>
9350
- <a id="__codelineno-0-88" name="__codelineno-0-88"></a><span class="sd"> &quot;&quot;&quot;</span>
9351
- <a id="__codelineno-0-89" name="__codelineno-0-89"></a> <span class="c1"># Avoid circular import</span>
9352
- <a id="__codelineno-0-90" name="__codelineno-0-90"></a> <span class="kn">from</span> <span class="nn">nautobot.dcim.models</span> <span class="kn">import</span> <span class="n">Device</span>
9353
- <a id="__codelineno-0-91" name="__codelineno-0-91"></a> <span class="kn">from</span> <span class="nn">nautobot.extras.filters</span> <span class="kn">import</span> <span class="n">ContentTypeMultipleChoiceFilter</span><span class="p">,</span> <span class="n">CustomFieldFilterMixin</span><span class="p">,</span> <span class="n">StatusFilter</span>
9354
- <a id="__codelineno-0-92" name="__codelineno-0-92"></a> <span class="kn">from</span> <span class="nn">nautobot.extras.models</span> <span class="kn">import</span> <span class="n">ConfigContext</span><span class="p">,</span> <span class="n">Role</span><span class="p">,</span> <span class="n">Status</span><span class="p">,</span> <span class="n">Tag</span>
9355
- <a id="__codelineno-0-93" name="__codelineno-0-93"></a> <span class="kn">from</span> <span class="nn">nautobot.extras.utils</span> <span class="kn">import</span> <span class="n">ChangeLoggedModelsQuery</span><span class="p">,</span> <span class="n">RoleModelsQuery</span><span class="p">,</span> <span class="n">TaggableClassesQuery</span>
9356
- <a id="__codelineno-0-94" name="__codelineno-0-94"></a> <span class="kn">from</span> <span class="nn">nautobot.core.filters</span> <span class="kn">import</span> <span class="n">MultiValueDecimalFilter</span><span class="p">,</span> <span class="n">MultiValueFloatFilter</span>
9357
- <a id="__codelineno-0-95" name="__codelineno-0-95"></a> <span class="kn">from</span> <span class="nn">nautobot.core.forms</span> <span class="kn">import</span> <span class="p">(</span>
9358
- <a id="__codelineno-0-96" name="__codelineno-0-96"></a> <span class="n">DynamicModelMultipleChoiceField</span><span class="p">,</span>
9359
- <a id="__codelineno-0-97" name="__codelineno-0-97"></a> <span class="n">MultipleContentTypeField</span><span class="p">,</span>
9360
- <a id="__codelineno-0-98" name="__codelineno-0-98"></a> <span class="n">StaticSelect2Multiple</span><span class="p">,</span>
9361
- <a id="__codelineno-0-99" name="__codelineno-0-99"></a> <span class="p">)</span>
9362
- <a id="__codelineno-0-100" name="__codelineno-0-100"></a> <span class="kn">from</span> <span class="nn">nautobot.virtualization.models</span> <span class="kn">import</span> <span class="n">VirtualMachine</span>
9363
- <a id="__codelineno-0-101" name="__codelineno-0-101"></a>
9364
- <a id="__codelineno-0-102" name="__codelineno-0-102"></a> <span class="k">if</span> <span class="n">filterset</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">filterset</span><span class="o">.</span><span class="n">Meta</span><span class="o">.</span><span class="n">model</span> <span class="o">!=</span> <span class="n">model</span><span class="p">:</span>
9365
- <a id="__codelineno-0-103" name="__codelineno-0-103"></a> <span class="n">filterset</span> <span class="o">=</span> <span class="n">get_filterset_for_model</span><span class="p">(</span><span class="n">model</span><span class="p">)()</span>
9366
- <a id="__codelineno-0-104" name="__codelineno-0-104"></a> <span class="n">field</span> <span class="o">=</span> <span class="n">get_filterset_field</span><span class="p">(</span><span class="n">filterset</span><span class="p">,</span> <span class="n">parameter</span><span class="p">)</span>
9367
- <a id="__codelineno-0-105" name="__codelineno-0-105"></a> <span class="n">form_field</span> <span class="o">=</span> <span class="n">field</span><span class="o">.</span><span class="n">field</span>
9368
- <a id="__codelineno-0-106" name="__codelineno-0-106"></a>
9369
- <a id="__codelineno-0-107" name="__codelineno-0-107"></a> <span class="c1"># TODO(Culver): We are having to replace some widgets here because multivalue_field_factory that generates these isn&#39;t smart enough</span>
9370
- <a id="__codelineno-0-108" name="__codelineno-0-108"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="n">CustomFieldFilterMixin</span><span class="p">):</span>
9371
- <a id="__codelineno-0-109" name="__codelineno-0-109"></a> <span class="n">form_field</span> <span class="o">=</span> <span class="n">field</span><span class="o">.</span><span class="n">custom_field</span><span class="o">.</span><span class="n">to_filter_form_field</span><span class="p">(</span><span class="n">lookup_expr</span><span class="o">=</span><span class="n">field</span><span class="o">.</span><span class="n">lookup_expr</span><span class="p">)</span>
9372
- <a id="__codelineno-0-110" name="__codelineno-0-110"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="p">(</span><span class="n">MultiValueDecimalFilter</span><span class="p">,</span> <span class="n">MultiValueFloatFilter</span><span class="p">)):</span>
9373
- <a id="__codelineno-0-111" name="__codelineno-0-111"></a> <span class="n">form_field</span> <span class="o">=</span> <span class="n">forms</span><span class="o">.</span><span class="n">DecimalField</span><span class="p">()</span>
9374
- <a id="__codelineno-0-112" name="__codelineno-0-112"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="n">NumberFilter</span><span class="p">):</span>
9375
- <a id="__codelineno-0-113" name="__codelineno-0-113"></a> <span class="n">form_field</span> <span class="o">=</span> <span class="n">forms</span><span class="o">.</span><span class="n">IntegerField</span><span class="p">()</span>
9376
- <a id="__codelineno-0-114" name="__codelineno-0-114"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="n">ModelMultipleChoiceFilter</span><span class="p">):</span>
9377
- <a id="__codelineno-0-115" name="__codelineno-0-115"></a> <span class="n">related_model</span> <span class="o">=</span> <span class="n">Status</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="n">StatusFilter</span><span class="p">)</span> <span class="k">else</span> <span class="n">field</span><span class="o">.</span><span class="n">extra</span><span class="p">[</span><span class="s2">&quot;queryset&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">model</span>
9378
- <a id="__codelineno-0-116" name="__codelineno-0-116"></a> <span class="n">form_attr</span> <span class="o">=</span> <span class="p">{</span>
9379
- <a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="s2">&quot;queryset&quot;</span><span class="p">:</span> <span class="n">related_model</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">(),</span>
9380
- <a id="__codelineno-0-118" name="__codelineno-0-118"></a> <span class="s2">&quot;to_field_name&quot;</span><span class="p">:</span> <span class="n">field</span><span class="o">.</span><span class="n">extra</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;to_field_name&quot;</span><span class="p">,</span> <span class="s2">&quot;id&quot;</span><span class="p">),</span>
9381
- <a id="__codelineno-0-119" name="__codelineno-0-119"></a> <span class="p">}</span>
9382
- <a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="c1"># ConfigContext requires content_type set to Device and VirtualMachine</span>
9383
- <a id="__codelineno-0-121" name="__codelineno-0-121"></a> <span class="k">if</span> <span class="n">model</span> <span class="o">==</span> <span class="n">ConfigContext</span><span class="p">:</span>
9384
- <a id="__codelineno-0-122" name="__codelineno-0-122"></a> <span class="n">form_attr</span><span class="p">[</span><span class="s2">&quot;query_params&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;content_types&quot;</span><span class="p">:</span> <span class="p">[</span><span class="n">Device</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">label_lower</span><span class="p">,</span> <span class="n">VirtualMachine</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">label_lower</span><span class="p">]}</span>
9385
- <a id="__codelineno-0-123" name="__codelineno-0-123"></a> <span class="c1"># Status and Tag api requires content_type, to limit result to only related content_types</span>
9386
- <a id="__codelineno-0-124" name="__codelineno-0-124"></a> <span class="k">elif</span> <span class="n">related_model</span> <span class="ow">in</span> <span class="p">[</span><span class="n">Role</span><span class="p">,</span> <span class="n">Status</span><span class="p">,</span> <span class="n">Tag</span><span class="p">]:</span>
9387
- <a id="__codelineno-0-125" name="__codelineno-0-125"></a> <span class="n">form_attr</span><span class="p">[</span><span class="s2">&quot;query_params&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;content_types&quot;</span><span class="p">:</span> <span class="n">model</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">label_lower</span><span class="p">}</span>
9388
- <a id="__codelineno-0-126" name="__codelineno-0-126"></a>
9389
- <a id="__codelineno-0-127" name="__codelineno-0-127"></a> <span class="n">form_field</span> <span class="o">=</span> <span class="n">DynamicModelMultipleChoiceField</span><span class="p">(</span><span class="o">**</span><span class="n">form_attr</span><span class="p">)</span>
9390
- <a id="__codelineno-0-128" name="__codelineno-0-128"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span>
9391
- <a id="__codelineno-0-129" name="__codelineno-0-129"></a> <span class="n">field</span><span class="p">,</span> <span class="n">ContentTypeMultipleChoiceFilter</span>
9392
- <a id="__codelineno-0-130" name="__codelineno-0-130"></a> <span class="p">):</span> <span class="c1"># While there are other objects using `ContentTypeMultipleChoiceFilter`, the case where</span>
9393
- <a id="__codelineno-0-131" name="__codelineno-0-131"></a> <span class="c1"># models that have such a filter and the `verbose_name_plural` has multiple words is ony one: &quot;dynamic groups&quot;.</span>
9394
- <a id="__codelineno-0-132" name="__codelineno-0-132"></a> <span class="kn">from</span> <span class="nn">nautobot.core.models.fields</span> <span class="kn">import</span> <span class="n">slugify_dashes_to_underscores</span> <span class="c1"># Avoid circular import</span>
9395
- <a id="__codelineno-0-133" name="__codelineno-0-133"></a>
9396
- <a id="__codelineno-0-134" name="__codelineno-0-134"></a> <span class="n">plural_name</span> <span class="o">=</span> <span class="n">slugify_dashes_to_underscores</span><span class="p">(</span><span class="n">model</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">verbose_name_plural</span><span class="p">)</span>
9397
- <a id="__codelineno-0-135" name="__codelineno-0-135"></a> <span class="c1"># Cable-connectable models use &quot;cable_terminations&quot;, not &quot;cables&quot;, as the feature name</span>
9398
- <a id="__codelineno-0-136" name="__codelineno-0-136"></a> <span class="k">if</span> <span class="n">plural_name</span> <span class="o">==</span> <span class="s2">&quot;cables&quot;</span><span class="p">:</span>
9399
- <a id="__codelineno-0-137" name="__codelineno-0-137"></a> <span class="n">plural_name</span> <span class="o">==</span> <span class="s2">&quot;cable_terminations&quot;</span>
9400
- <a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="k">try</span><span class="p">:</span>
9401
- <a id="__codelineno-0-139" name="__codelineno-0-139"></a> <span class="n">form_field</span> <span class="o">=</span> <span class="n">MultipleContentTypeField</span><span class="p">(</span><span class="n">choices_as_strings</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">feature</span><span class="o">=</span><span class="n">plural_name</span><span class="p">)</span>
9402
- <a id="__codelineno-0-140" name="__codelineno-0-140"></a> <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
9403
- <a id="__codelineno-0-141" name="__codelineno-0-141"></a> <span class="c1"># `MultipleContentTypeField` employs `registry[&quot;model features&quot;][feature]`, which may</span>
9404
- <a id="__codelineno-0-142" name="__codelineno-0-142"></a> <span class="c1"># result in an error if `feature` is not found in the `registry[&quot;model features&quot;]` dict.</span>
9405
- <a id="__codelineno-0-143" name="__codelineno-0-143"></a> <span class="c1"># In this case use queryset</span>
9406
- <a id="__codelineno-0-144" name="__codelineno-0-144"></a> <span class="n">queryset_map</span> <span class="o">=</span> <span class="p">{</span>
9407
- <a id="__codelineno-0-145" name="__codelineno-0-145"></a> <span class="s2">&quot;tags&quot;</span><span class="p">:</span> <span class="n">TaggableClassesQuery</span><span class="p">,</span>
9408
- <a id="__codelineno-0-146" name="__codelineno-0-146"></a> <span class="s2">&quot;job_hooks&quot;</span><span class="p">:</span> <span class="n">ChangeLoggedModelsQuery</span><span class="p">,</span>
9409
- <a id="__codelineno-0-147" name="__codelineno-0-147"></a> <span class="s2">&quot;roles&quot;</span><span class="p">:</span> <span class="n">RoleModelsQuery</span><span class="p">,</span>
9410
- <a id="__codelineno-0-148" name="__codelineno-0-148"></a> <span class="p">}</span>
9411
- <a id="__codelineno-0-149" name="__codelineno-0-149"></a> <span class="n">form_field</span> <span class="o">=</span> <span class="n">MultipleContentTypeField</span><span class="p">(</span>
9412
- <a id="__codelineno-0-150" name="__codelineno-0-150"></a> <span class="n">choices_as_strings</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">queryset</span><span class="o">=</span><span class="n">queryset_map</span><span class="p">[</span><span class="n">plural_name</span><span class="p">]()</span><span class="o">.</span><span class="n">as_queryset</span><span class="p">()</span>
9413
- <a id="__codelineno-0-151" name="__codelineno-0-151"></a> <span class="p">)</span>
9414
- <a id="__codelineno-0-152" name="__codelineno-0-152"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="p">(</span><span class="n">MultipleChoiceFilter</span><span class="p">,</span> <span class="n">ChoiceFilter</span><span class="p">))</span> <span class="ow">and</span> <span class="s2">&quot;choices&quot;</span> <span class="ow">in</span> <span class="n">field</span><span class="o">.</span><span class="n">extra</span><span class="p">:</span>
9415
- <a id="__codelineno-0-153" name="__codelineno-0-153"></a> <span class="n">form_field_class</span> <span class="o">=</span> <span class="n">forms</span><span class="o">.</span><span class="n">ChoiceField</span>
9416
- <a id="__codelineno-0-154" name="__codelineno-0-154"></a> <span class="n">form_field_class</span><span class="o">.</span><span class="n">widget</span> <span class="o">=</span> <span class="n">StaticSelect2Multiple</span><span class="p">()</span>
9417
- <a id="__codelineno-0-155" name="__codelineno-0-155"></a> <span class="n">form_attr</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;choices&quot;</span><span class="p">:</span> <span class="n">field</span><span class="o">.</span><span class="n">extra</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;choices&quot;</span><span class="p">)}</span>
9418
- <a id="__codelineno-0-156" name="__codelineno-0-156"></a>
9419
- <a id="__codelineno-0-157" name="__codelineno-0-157"></a> <span class="n">form_field</span> <span class="o">=</span> <span class="n">form_field_class</span><span class="p">(</span><span class="o">**</span><span class="n">form_attr</span><span class="p">)</span>
9420
- <a id="__codelineno-0-158" name="__codelineno-0-158"></a>
9421
- <a id="__codelineno-0-159" name="__codelineno-0-159"></a> <span class="n">form_field</span><span class="o">.</span><span class="n">required</span> <span class="o">=</span> <span class="kc">False</span>
9422
- <a id="__codelineno-0-160" name="__codelineno-0-160"></a> <span class="n">form_field</span><span class="o">.</span><span class="n">initial</span> <span class="o">=</span> <span class="kc">None</span>
9423
- <a id="__codelineno-0-161" name="__codelineno-0-161"></a> <span class="n">form_field</span><span class="o">.</span><span class="n">widget</span><span class="o">.</span><span class="n">attrs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;required&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
9424
- <a id="__codelineno-0-162" name="__codelineno-0-162"></a>
9425
- <a id="__codelineno-0-163" name="__codelineno-0-163"></a> <span class="n">css_classes</span> <span class="o">=</span> <span class="n">form_field</span><span class="o">.</span><span class="n">widget</span><span class="o">.</span><span class="n">attrs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;class&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
9426
- <a id="__codelineno-0-164" name="__codelineno-0-164"></a> <span class="n">form_field</span><span class="o">.</span><span class="n">widget</span><span class="o">.</span><span class="n">attrs</span><span class="p">[</span><span class="s2">&quot;class&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;form-control &quot;</span> <span class="o">+</span> <span class="n">css_classes</span>
9427
- <a id="__codelineno-0-165" name="__codelineno-0-165"></a> <span class="k">return</span> <span class="n">form_field</span>
9372
+ <span class="normal"><a href="#__codelineno-0-165">165</a></span>
9373
+ <span class="normal"><a href="#__codelineno-0-166">166</a></span>
9374
+ <span class="normal"><a href="#__codelineno-0-167">167</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-86" name="__codelineno-0-86"></a><span class="k">def</span> <span class="nf">get_filterset_parameter_form_field</span><span class="p">(</span><span class="n">model</span><span class="p">,</span> <span class="n">parameter</span><span class="p">,</span> <span class="n">filterset</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
9375
+ <a id="__codelineno-0-87" name="__codelineno-0-87"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
9376
+ <a id="__codelineno-0-88" name="__codelineno-0-88"></a><span class="sd"> Return the relevant form field instance for a filterset parameter e.g DynamicModelMultipleChoiceField, forms.IntegerField e.t.c</span>
9377
+ <a id="__codelineno-0-89" name="__codelineno-0-89"></a><span class="sd"> &quot;&quot;&quot;</span>
9378
+ <a id="__codelineno-0-90" name="__codelineno-0-90"></a> <span class="c1"># Avoid circular import</span>
9379
+ <a id="__codelineno-0-91" name="__codelineno-0-91"></a> <span class="kn">from</span> <span class="nn">nautobot.dcim.models</span> <span class="kn">import</span> <span class="n">Device</span>
9380
+ <a id="__codelineno-0-92" name="__codelineno-0-92"></a> <span class="kn">from</span> <span class="nn">nautobot.extras.filters</span> <span class="kn">import</span> <span class="n">ContentTypeMultipleChoiceFilter</span><span class="p">,</span> <span class="n">CustomFieldFilterMixin</span><span class="p">,</span> <span class="n">StatusFilter</span>
9381
+ <a id="__codelineno-0-93" name="__codelineno-0-93"></a> <span class="kn">from</span> <span class="nn">nautobot.extras.models</span> <span class="kn">import</span> <span class="n">ConfigContext</span><span class="p">,</span> <span class="n">Role</span><span class="p">,</span> <span class="n">Status</span><span class="p">,</span> <span class="n">Tag</span>
9382
+ <a id="__codelineno-0-94" name="__codelineno-0-94"></a> <span class="kn">from</span> <span class="nn">nautobot.extras.utils</span> <span class="kn">import</span> <span class="n">ChangeLoggedModelsQuery</span><span class="p">,</span> <span class="n">RoleModelsQuery</span><span class="p">,</span> <span class="n">TaggableClassesQuery</span>
9383
+ <a id="__codelineno-0-95" name="__codelineno-0-95"></a> <span class="kn">from</span> <span class="nn">nautobot.core.filters</span> <span class="kn">import</span> <span class="n">MultiValueDecimalFilter</span><span class="p">,</span> <span class="n">MultiValueFloatFilter</span>
9384
+ <a id="__codelineno-0-96" name="__codelineno-0-96"></a> <span class="kn">from</span> <span class="nn">nautobot.core.forms</span> <span class="kn">import</span> <span class="p">(</span>
9385
+ <a id="__codelineno-0-97" name="__codelineno-0-97"></a> <span class="n">BOOLEAN_CHOICES</span><span class="p">,</span>
9386
+ <a id="__codelineno-0-98" name="__codelineno-0-98"></a> <span class="n">DynamicModelMultipleChoiceField</span><span class="p">,</span>
9387
+ <a id="__codelineno-0-99" name="__codelineno-0-99"></a> <span class="n">MultipleContentTypeField</span><span class="p">,</span>
9388
+ <a id="__codelineno-0-100" name="__codelineno-0-100"></a> <span class="n">StaticSelect2</span><span class="p">,</span>
9389
+ <a id="__codelineno-0-101" name="__codelineno-0-101"></a> <span class="n">StaticSelect2Multiple</span><span class="p">,</span>
9390
+ <a id="__codelineno-0-102" name="__codelineno-0-102"></a> <span class="p">)</span>
9391
+ <a id="__codelineno-0-103" name="__codelineno-0-103"></a> <span class="kn">from</span> <span class="nn">nautobot.virtualization.models</span> <span class="kn">import</span> <span class="n">VirtualMachine</span>
9392
+ <a id="__codelineno-0-104" name="__codelineno-0-104"></a>
9393
+ <a id="__codelineno-0-105" name="__codelineno-0-105"></a> <span class="k">if</span> <span class="n">filterset</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">filterset</span><span class="o">.</span><span class="n">Meta</span><span class="o">.</span><span class="n">model</span> <span class="o">!=</span> <span class="n">model</span><span class="p">:</span>
9394
+ <a id="__codelineno-0-106" name="__codelineno-0-106"></a> <span class="n">filterset</span> <span class="o">=</span> <span class="n">get_filterset_for_model</span><span class="p">(</span><span class="n">model</span><span class="p">)()</span>
9395
+ <a id="__codelineno-0-107" name="__codelineno-0-107"></a> <span class="n">field</span> <span class="o">=</span> <span class="n">get_filterset_field</span><span class="p">(</span><span class="n">filterset</span><span class="p">,</span> <span class="n">parameter</span><span class="p">)</span>
9396
+ <a id="__codelineno-0-108" name="__codelineno-0-108"></a> <span class="n">form_field</span> <span class="o">=</span> <span class="n">field</span><span class="o">.</span><span class="n">field</span>
9397
+ <a id="__codelineno-0-109" name="__codelineno-0-109"></a>
9398
+ <a id="__codelineno-0-110" name="__codelineno-0-110"></a> <span class="c1"># TODO(Culver): We are having to replace some widgets here because multivalue_field_factory that generates these isn&#39;t smart enough</span>
9399
+ <a id="__codelineno-0-111" name="__codelineno-0-111"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="n">CustomFieldFilterMixin</span><span class="p">):</span>
9400
+ <a id="__codelineno-0-112" name="__codelineno-0-112"></a> <span class="n">form_field</span> <span class="o">=</span> <span class="n">field</span><span class="o">.</span><span class="n">custom_field</span><span class="o">.</span><span class="n">to_filter_form_field</span><span class="p">(</span><span class="n">lookup_expr</span><span class="o">=</span><span class="n">field</span><span class="o">.</span><span class="n">lookup_expr</span><span class="p">)</span>
9401
+ <a id="__codelineno-0-113" name="__codelineno-0-113"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="p">(</span><span class="n">MultiValueDecimalFilter</span><span class="p">,</span> <span class="n">MultiValueFloatFilter</span><span class="p">)):</span>
9402
+ <a id="__codelineno-0-114" name="__codelineno-0-114"></a> <span class="n">form_field</span> <span class="o">=</span> <span class="n">forms</span><span class="o">.</span><span class="n">DecimalField</span><span class="p">()</span>
9403
+ <a id="__codelineno-0-115" name="__codelineno-0-115"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="n">NumberFilter</span><span class="p">):</span>
9404
+ <a id="__codelineno-0-116" name="__codelineno-0-116"></a> <span class="n">form_field</span> <span class="o">=</span> <span class="n">forms</span><span class="o">.</span><span class="n">IntegerField</span><span class="p">()</span>
9405
+ <a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="n">ModelMultipleChoiceFilter</span><span class="p">):</span>
9406
+ <a id="__codelineno-0-118" name="__codelineno-0-118"></a> <span class="n">related_model</span> <span class="o">=</span> <span class="n">Status</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="n">StatusFilter</span><span class="p">)</span> <span class="k">else</span> <span class="n">field</span><span class="o">.</span><span class="n">extra</span><span class="p">[</span><span class="s2">&quot;queryset&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">model</span>
9407
+ <a id="__codelineno-0-119" name="__codelineno-0-119"></a> <span class="n">form_attr</span> <span class="o">=</span> <span class="p">{</span>
9408
+ <a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="s2">&quot;queryset&quot;</span><span class="p">:</span> <span class="n">related_model</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">(),</span>
9409
+ <a id="__codelineno-0-121" name="__codelineno-0-121"></a> <span class="s2">&quot;to_field_name&quot;</span><span class="p">:</span> <span class="n">field</span><span class="o">.</span><span class="n">extra</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;to_field_name&quot;</span><span class="p">,</span> <span class="s2">&quot;id&quot;</span><span class="p">),</span>
9410
+ <a id="__codelineno-0-122" name="__codelineno-0-122"></a> <span class="p">}</span>
9411
+ <a id="__codelineno-0-123" name="__codelineno-0-123"></a> <span class="c1"># ConfigContext requires content_type set to Device and VirtualMachine</span>
9412
+ <a id="__codelineno-0-124" name="__codelineno-0-124"></a> <span class="k">if</span> <span class="n">model</span> <span class="o">==</span> <span class="n">ConfigContext</span><span class="p">:</span>
9413
+ <a id="__codelineno-0-125" name="__codelineno-0-125"></a> <span class="n">form_attr</span><span class="p">[</span><span class="s2">&quot;query_params&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;content_types&quot;</span><span class="p">:</span> <span class="p">[</span><span class="n">Device</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">label_lower</span><span class="p">,</span> <span class="n">VirtualMachine</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">label_lower</span><span class="p">]}</span>
9414
+ <a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="c1"># Status and Tag api requires content_type, to limit result to only related content_types</span>
9415
+ <a id="__codelineno-0-127" name="__codelineno-0-127"></a> <span class="k">elif</span> <span class="n">related_model</span> <span class="ow">in</span> <span class="p">[</span><span class="n">Role</span><span class="p">,</span> <span class="n">Status</span><span class="p">,</span> <span class="n">Tag</span><span class="p">]:</span>
9416
+ <a id="__codelineno-0-128" name="__codelineno-0-128"></a> <span class="n">form_attr</span><span class="p">[</span><span class="s2">&quot;query_params&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;content_types&quot;</span><span class="p">:</span> <span class="n">model</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">label_lower</span><span class="p">}</span>
9417
+ <a id="__codelineno-0-129" name="__codelineno-0-129"></a>
9418
+ <a id="__codelineno-0-130" name="__codelineno-0-130"></a> <span class="n">form_field</span> <span class="o">=</span> <span class="n">DynamicModelMultipleChoiceField</span><span class="p">(</span><span class="o">**</span><span class="n">form_attr</span><span class="p">)</span>
9419
+ <a id="__codelineno-0-131" name="__codelineno-0-131"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span>
9420
+ <a id="__codelineno-0-132" name="__codelineno-0-132"></a> <span class="n">field</span><span class="p">,</span> <span class="n">ContentTypeMultipleChoiceFilter</span>
9421
+ <a id="__codelineno-0-133" name="__codelineno-0-133"></a> <span class="p">):</span> <span class="c1"># While there are other objects using `ContentTypeMultipleChoiceFilter`, the case where</span>
9422
+ <a id="__codelineno-0-134" name="__codelineno-0-134"></a> <span class="c1"># models that have such a filter and the `verbose_name_plural` has multiple words is ony one: &quot;dynamic groups&quot;.</span>
9423
+ <a id="__codelineno-0-135" name="__codelineno-0-135"></a> <span class="kn">from</span> <span class="nn">nautobot.core.models.fields</span> <span class="kn">import</span> <span class="n">slugify_dashes_to_underscores</span> <span class="c1"># Avoid circular import</span>
9424
+ <a id="__codelineno-0-136" name="__codelineno-0-136"></a>
9425
+ <a id="__codelineno-0-137" name="__codelineno-0-137"></a> <span class="n">plural_name</span> <span class="o">=</span> <span class="n">slugify_dashes_to_underscores</span><span class="p">(</span><span class="n">model</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">verbose_name_plural</span><span class="p">)</span>
9426
+ <a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="c1"># Cable-connectable models use &quot;cable_terminations&quot;, not &quot;cables&quot;, as the feature name</span>
9427
+ <a id="__codelineno-0-139" name="__codelineno-0-139"></a> <span class="k">if</span> <span class="n">plural_name</span> <span class="o">==</span> <span class="s2">&quot;cables&quot;</span><span class="p">:</span>
9428
+ <a id="__codelineno-0-140" name="__codelineno-0-140"></a> <span class="n">plural_name</span> <span class="o">==</span> <span class="s2">&quot;cable_terminations&quot;</span>
9429
+ <a id="__codelineno-0-141" name="__codelineno-0-141"></a> <span class="k">try</span><span class="p">:</span>
9430
+ <a id="__codelineno-0-142" name="__codelineno-0-142"></a> <span class="n">form_field</span> <span class="o">=</span> <span class="n">MultipleContentTypeField</span><span class="p">(</span><span class="n">choices_as_strings</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">feature</span><span class="o">=</span><span class="n">plural_name</span><span class="p">)</span>
9431
+ <a id="__codelineno-0-143" name="__codelineno-0-143"></a> <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
9432
+ <a id="__codelineno-0-144" name="__codelineno-0-144"></a> <span class="c1"># `MultipleContentTypeField` employs `registry[&quot;model features&quot;][feature]`, which may</span>
9433
+ <a id="__codelineno-0-145" name="__codelineno-0-145"></a> <span class="c1"># result in an error if `feature` is not found in the `registry[&quot;model features&quot;]` dict.</span>
9434
+ <a id="__codelineno-0-146" name="__codelineno-0-146"></a> <span class="c1"># In this case use queryset</span>
9435
+ <a id="__codelineno-0-147" name="__codelineno-0-147"></a> <span class="n">queryset_map</span> <span class="o">=</span> <span class="p">{</span>
9436
+ <a id="__codelineno-0-148" name="__codelineno-0-148"></a> <span class="s2">&quot;tags&quot;</span><span class="p">:</span> <span class="n">TaggableClassesQuery</span><span class="p">,</span>
9437
+ <a id="__codelineno-0-149" name="__codelineno-0-149"></a> <span class="s2">&quot;job_hooks&quot;</span><span class="p">:</span> <span class="n">ChangeLoggedModelsQuery</span><span class="p">,</span>
9438
+ <a id="__codelineno-0-150" name="__codelineno-0-150"></a> <span class="s2">&quot;roles&quot;</span><span class="p">:</span> <span class="n">RoleModelsQuery</span><span class="p">,</span>
9439
+ <a id="__codelineno-0-151" name="__codelineno-0-151"></a> <span class="p">}</span>
9440
+ <a id="__codelineno-0-152" name="__codelineno-0-152"></a> <span class="n">form_field</span> <span class="o">=</span> <span class="n">MultipleContentTypeField</span><span class="p">(</span>
9441
+ <a id="__codelineno-0-153" name="__codelineno-0-153"></a> <span class="n">choices_as_strings</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">queryset</span><span class="o">=</span><span class="n">queryset_map</span><span class="p">[</span><span class="n">plural_name</span><span class="p">]()</span><span class="o">.</span><span class="n">as_queryset</span><span class="p">()</span>
9442
+ <a id="__codelineno-0-154" name="__codelineno-0-154"></a> <span class="p">)</span>
9443
+ <a id="__codelineno-0-155" name="__codelineno-0-155"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="p">(</span><span class="n">MultipleChoiceFilter</span><span class="p">,</span> <span class="n">ChoiceFilter</span><span class="p">))</span> <span class="ow">and</span> <span class="s2">&quot;choices&quot;</span> <span class="ow">in</span> <span class="n">field</span><span class="o">.</span><span class="n">extra</span><span class="p">:</span>
9444
+ <a id="__codelineno-0-156" name="__codelineno-0-156"></a> <span class="n">form_field</span> <span class="o">=</span> <span class="n">forms</span><span class="o">.</span><span class="n">MultipleChoiceField</span><span class="p">(</span><span class="n">choices</span><span class="o">=</span><span class="n">field</span><span class="o">.</span><span class="n">extra</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;choices&quot;</span><span class="p">),</span> <span class="n">widget</span><span class="o">=</span><span class="n">StaticSelect2Multiple</span><span class="p">)</span>
9445
+ <a id="__codelineno-0-157" name="__codelineno-0-157"></a>
9446
+ <a id="__codelineno-0-158" name="__codelineno-0-158"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="n">BooleanFilter</span><span class="p">):</span>
9447
+ <a id="__codelineno-0-159" name="__codelineno-0-159"></a> <span class="n">form_field</span> <span class="o">=</span> <span class="n">forms</span><span class="o">.</span><span class="n">ChoiceField</span><span class="p">(</span><span class="n">choices</span><span class="o">=</span><span class="n">BOOLEAN_CHOICES</span><span class="p">,</span> <span class="n">widget</span><span class="o">=</span><span class="n">StaticSelect2</span><span class="p">)</span>
9448
+ <a id="__codelineno-0-160" name="__codelineno-0-160"></a>
9449
+ <a id="__codelineno-0-161" name="__codelineno-0-161"></a> <span class="n">form_field</span><span class="o">.</span><span class="n">required</span> <span class="o">=</span> <span class="kc">False</span>
9450
+ <a id="__codelineno-0-162" name="__codelineno-0-162"></a> <span class="n">form_field</span><span class="o">.</span><span class="n">initial</span> <span class="o">=</span> <span class="kc">None</span>
9451
+ <a id="__codelineno-0-163" name="__codelineno-0-163"></a> <span class="n">form_field</span><span class="o">.</span><span class="n">widget</span><span class="o">.</span><span class="n">attrs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;required&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
9452
+ <a id="__codelineno-0-164" name="__codelineno-0-164"></a>
9453
+ <a id="__codelineno-0-165" name="__codelineno-0-165"></a> <span class="n">css_classes</span> <span class="o">=</span> <span class="n">form_field</span><span class="o">.</span><span class="n">widget</span><span class="o">.</span><span class="n">attrs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;class&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
9454
+ <a id="__codelineno-0-166" name="__codelineno-0-166"></a> <span class="n">form_field</span><span class="o">.</span><span class="n">widget</span><span class="o">.</span><span class="n">attrs</span><span class="p">[</span><span class="s2">&quot;class&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;form-control &quot;</span> <span class="o">+</span> <span class="n">css_classes</span>
9455
+ <a id="__codelineno-0-167" name="__codelineno-0-167"></a> <span class="k">return</span> <span class="n">form_field</span>
9428
9456
  </code></pre></div></td></tr></table></div>
9429
9457
  </details>
9430
9458
  </div>
@@ -11134,7 +11162,8 @@ values.</p>
11134
11162
 
11135
11163
  <details class="quote">
11136
11164
  <summary>Source code in <code>nautobot/core/utils/requests.py</code></summary>
11137
- <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-140">140</a></span>
11165
+ <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-139">139</a></span>
11166
+ <span class="normal"><a href="#__codelineno-0-140">140</a></span>
11138
11167
  <span class="normal"><a href="#__codelineno-0-141">141</a></span>
11139
11168
  <span class="normal"><a href="#__codelineno-0-142">142</a></span>
11140
11169
  <span class="normal"><a href="#__codelineno-0-143">143</a></span>
@@ -11166,41 +11195,40 @@ values.</p>
11166
11195
  <span class="normal"><a href="#__codelineno-0-169">169</a></span>
11167
11196
  <span class="normal"><a href="#__codelineno-0-170">170</a></span>
11168
11197
  <span class="normal"><a href="#__codelineno-0-171">171</a></span>
11169
- <span class="normal"><a href="#__codelineno-0-172">172</a></span>
11170
- <span class="normal"><a href="#__codelineno-0-173">173</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-140" name="__codelineno-0-140"></a><span class="k">def</span> <span class="nf">normalize_querydict</span><span class="p">(</span><span class="n">querydict</span><span class="p">,</span> <span class="n">form_class</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
11171
- <a id="__codelineno-0-141" name="__codelineno-0-141"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
11172
- <a id="__codelineno-0-142" name="__codelineno-0-142"></a><span class="sd"> Convert a QueryDict to a normal, mutable dictionary, preserving list values. For example,</span>
11173
- <a id="__codelineno-0-143" name="__codelineno-0-143"></a>
11174
- <a id="__codelineno-0-144" name="__codelineno-0-144"></a><span class="sd"> QueryDict(&#39;foo=1&amp;bar=2&amp;bar=3&amp;baz=&#39;)</span>
11175
- <a id="__codelineno-0-145" name="__codelineno-0-145"></a>
11176
- <a id="__codelineno-0-146" name="__codelineno-0-146"></a><span class="sd"> becomes:</span>
11177
- <a id="__codelineno-0-147" name="__codelineno-0-147"></a>
11178
- <a id="__codelineno-0-148" name="__codelineno-0-148"></a><span class="sd"> {&#39;foo&#39;: &#39;1&#39;, &#39;bar&#39;: [&#39;2&#39;, &#39;3&#39;], &#39;baz&#39;: &#39;&#39;}</span>
11179
- <a id="__codelineno-0-149" name="__codelineno-0-149"></a>
11180
- <a id="__codelineno-0-150" name="__codelineno-0-150"></a><span class="sd"> This function is necessary because QueryDict does not provide any built-in mechanism which preserves multiple</span>
11181
- <a id="__codelineno-0-151" name="__codelineno-0-151"></a><span class="sd"> values.</span>
11182
- <a id="__codelineno-0-152" name="__codelineno-0-152"></a>
11183
- <a id="__codelineno-0-153" name="__codelineno-0-153"></a><span class="sd"> A `form_class` can be provided as a way to hint which query parameters should be treated as lists.</span>
11184
- <a id="__codelineno-0-154" name="__codelineno-0-154"></a><span class="sd"> &quot;&quot;&quot;</span>
11185
- <a id="__codelineno-0-155" name="__codelineno-0-155"></a> <span class="n">result</span> <span class="o">=</span> <span class="p">{}</span>
11186
- <a id="__codelineno-0-156" name="__codelineno-0-156"></a> <span class="k">if</span> <span class="n">querydict</span><span class="p">:</span>
11187
- <a id="__codelineno-0-157" name="__codelineno-0-157"></a> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value_list</span> <span class="ow">in</span> <span class="n">querydict</span><span class="o">.</span><span class="n">lists</span><span class="p">():</span>
11188
- <a id="__codelineno-0-158" name="__codelineno-0-158"></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">value_list</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
11189
- <a id="__codelineno-0-159" name="__codelineno-0-159"></a> <span class="c1"># More than one value in the querydict for this key, so keep it as a list</span>
11190
- <a id="__codelineno-0-160" name="__codelineno-0-160"></a> <span class="c1"># TODO: we could check here and de-listify value_list if the form_class field is a single-value one?</span>
11191
- <a id="__codelineno-0-161" name="__codelineno-0-161"></a> <span class="n">result</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value_list</span>
11192
- <a id="__codelineno-0-162" name="__codelineno-0-162"></a> <span class="k">elif</span> <span class="p">(</span>
11193
- <a id="__codelineno-0-163" name="__codelineno-0-163"></a> <span class="n">form_class</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
11194
- <a id="__codelineno-0-164" name="__codelineno-0-164"></a> <span class="ow">and</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">form_class</span><span class="o">.</span><span class="n">base_fields</span>
11195
- <a id="__codelineno-0-165" name="__codelineno-0-165"></a> <span class="c1"># ModelMultipleChoiceField is *not* itself a subclass of MultipleChoiceField, thanks Django!</span>
11196
- <a id="__codelineno-0-166" name="__codelineno-0-166"></a> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">form_class</span><span class="o">.</span><span class="n">base_fields</span><span class="p">[</span><span class="n">key</span><span class="p">],</span> <span class="p">(</span><span class="n">forms</span><span class="o">.</span><span class="n">MultipleChoiceField</span><span class="p">,</span> <span class="n">forms</span><span class="o">.</span><span class="n">ModelMultipleChoiceField</span><span class="p">))</span>
11197
- <a id="__codelineno-0-167" name="__codelineno-0-167"></a> <span class="p">):</span>
11198
- <a id="__codelineno-0-168" name="__codelineno-0-168"></a> <span class="c1"># Even though there&#39;s only a single value in the querydict for this key, the form wants it as a list</span>
11199
- <a id="__codelineno-0-169" name="__codelineno-0-169"></a> <span class="n">result</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value_list</span>
11200
- <a id="__codelineno-0-170" name="__codelineno-0-170"></a> <span class="k">else</span><span class="p">:</span>
11201
- <a id="__codelineno-0-171" name="__codelineno-0-171"></a> <span class="c1"># Only a single value in the querydict for this key, and no guidance otherwise, so make it single</span>
11202
- <a id="__codelineno-0-172" name="__codelineno-0-172"></a> <span class="n">result</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value_list</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
11203
- <a id="__codelineno-0-173" name="__codelineno-0-173"></a> <span class="k">return</span> <span class="n">result</span>
11198
+ <span class="normal"><a href="#__codelineno-0-172">172</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-139" name="__codelineno-0-139"></a><span class="k">def</span> <span class="nf">normalize_querydict</span><span class="p">(</span><span class="n">querydict</span><span class="p">,</span> <span class="n">form_class</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
11199
+ <a id="__codelineno-0-140" name="__codelineno-0-140"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
11200
+ <a id="__codelineno-0-141" name="__codelineno-0-141"></a><span class="sd"> Convert a QueryDict to a normal, mutable dictionary, preserving list values. For example,</span>
11201
+ <a id="__codelineno-0-142" name="__codelineno-0-142"></a>
11202
+ <a id="__codelineno-0-143" name="__codelineno-0-143"></a><span class="sd"> QueryDict(&#39;foo=1&amp;bar=2&amp;bar=3&amp;baz=&#39;)</span>
11203
+ <a id="__codelineno-0-144" name="__codelineno-0-144"></a>
11204
+ <a id="__codelineno-0-145" name="__codelineno-0-145"></a><span class="sd"> becomes:</span>
11205
+ <a id="__codelineno-0-146" name="__codelineno-0-146"></a>
11206
+ <a id="__codelineno-0-147" name="__codelineno-0-147"></a><span class="sd"> {&#39;foo&#39;: &#39;1&#39;, &#39;bar&#39;: [&#39;2&#39;, &#39;3&#39;], &#39;baz&#39;: &#39;&#39;}</span>
11207
+ <a id="__codelineno-0-148" name="__codelineno-0-148"></a>
11208
+ <a id="__codelineno-0-149" name="__codelineno-0-149"></a><span class="sd"> This function is necessary because QueryDict does not provide any built-in mechanism which preserves multiple</span>
11209
+ <a id="__codelineno-0-150" name="__codelineno-0-150"></a><span class="sd"> values.</span>
11210
+ <a id="__codelineno-0-151" name="__codelineno-0-151"></a>
11211
+ <a id="__codelineno-0-152" name="__codelineno-0-152"></a><span class="sd"> A `form_class` can be provided as a way to hint which query parameters should be treated as lists.</span>
11212
+ <a id="__codelineno-0-153" name="__codelineno-0-153"></a><span class="sd"> &quot;&quot;&quot;</span>
11213
+ <a id="__codelineno-0-154" name="__codelineno-0-154"></a> <span class="n">result</span> <span class="o">=</span> <span class="p">{}</span>
11214
+ <a id="__codelineno-0-155" name="__codelineno-0-155"></a> <span class="k">if</span> <span class="n">querydict</span><span class="p">:</span>
11215
+ <a id="__codelineno-0-156" name="__codelineno-0-156"></a> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value_list</span> <span class="ow">in</span> <span class="n">querydict</span><span class="o">.</span><span class="n">lists</span><span class="p">():</span>
11216
+ <a id="__codelineno-0-157" name="__codelineno-0-157"></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">value_list</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
11217
+ <a id="__codelineno-0-158" name="__codelineno-0-158"></a> <span class="c1"># More than one value in the querydict for this key, so keep it as a list</span>
11218
+ <a id="__codelineno-0-159" name="__codelineno-0-159"></a> <span class="c1"># TODO: we could check here and de-listify value_list if the form_class field is a single-value one?</span>
11219
+ <a id="__codelineno-0-160" name="__codelineno-0-160"></a> <span class="n">result</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value_list</span>
11220
+ <a id="__codelineno-0-161" name="__codelineno-0-161"></a> <span class="k">elif</span> <span class="p">(</span>
11221
+ <a id="__codelineno-0-162" name="__codelineno-0-162"></a> <span class="n">form_class</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
11222
+ <a id="__codelineno-0-163" name="__codelineno-0-163"></a> <span class="ow">and</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">form_class</span><span class="o">.</span><span class="n">base_fields</span>
11223
+ <a id="__codelineno-0-164" name="__codelineno-0-164"></a> <span class="c1"># ModelMultipleChoiceField is *not* itself a subclass of MultipleChoiceField, thanks Django!</span>
11224
+ <a id="__codelineno-0-165" name="__codelineno-0-165"></a> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">form_class</span><span class="o">.</span><span class="n">base_fields</span><span class="p">[</span><span class="n">key</span><span class="p">],</span> <span class="p">(</span><span class="n">forms</span><span class="o">.</span><span class="n">MultipleChoiceField</span><span class="p">,</span> <span class="n">forms</span><span class="o">.</span><span class="n">ModelMultipleChoiceField</span><span class="p">))</span>
11225
+ <a id="__codelineno-0-166" name="__codelineno-0-166"></a> <span class="p">):</span>
11226
+ <a id="__codelineno-0-167" name="__codelineno-0-167"></a> <span class="c1"># Even though there&#39;s only a single value in the querydict for this key, the form wants it as a list</span>
11227
+ <a id="__codelineno-0-168" name="__codelineno-0-168"></a> <span class="n">result</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value_list</span>
11228
+ <a id="__codelineno-0-169" name="__codelineno-0-169"></a> <span class="k">else</span><span class="p">:</span>
11229
+ <a id="__codelineno-0-170" name="__codelineno-0-170"></a> <span class="c1"># Only a single value in the querydict for this key, and no guidance otherwise, so make it single</span>
11230
+ <a id="__codelineno-0-171" name="__codelineno-0-171"></a> <span class="n">result</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value_list</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
11231
+ <a id="__codelineno-0-172" name="__codelineno-0-172"></a> <span class="k">return</span> <span class="n">result</span>
11204
11232
  </code></pre></div></td></tr></table></div>
11205
11233
  </details>
11206
11234
  </div>
@@ -11755,13 +11783,21 @@ and in that case we need to not import models ourselves.</p>
11755
11783
  <span class="normal"><a href="#__codelineno-0-100">100</a></span>
11756
11784
  <span class="normal"><a href="#__codelineno-0-101">101</a></span>
11757
11785
  <span class="normal"><a href="#__codelineno-0-102">102</a></span>
11758
- <span class="normal"><a href="#__codelineno-0-103">103</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-97" name="__codelineno-0-97"></a><span class="k">def</span> <span class="nf">render_jinja2</span><span class="p">(</span><span class="n">template_code</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
11786
+ <span class="normal"><a href="#__codelineno-0-103">103</a></span>
11787
+ <span class="normal"><a href="#__codelineno-0-104">104</a></span>
11788
+ <span class="normal"><a href="#__codelineno-0-105">105</a></span>
11789
+ <span class="normal"><a href="#__codelineno-0-106">106</a></span>
11790
+ <span class="normal"><a href="#__codelineno-0-107">107</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-97" name="__codelineno-0-97"></a><span class="k">def</span> <span class="nf">render_jinja2</span><span class="p">(</span><span class="n">template_code</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
11759
11791
  <a id="__codelineno-0-98" name="__codelineno-0-98"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
11760
11792
  <a id="__codelineno-0-99" name="__codelineno-0-99"></a><span class="sd"> Render a Jinja2 template with the provided context. Return the rendered content.</span>
11761
11793
  <a id="__codelineno-0-100" name="__codelineno-0-100"></a><span class="sd"> &quot;&quot;&quot;</span>
11762
11794
  <a id="__codelineno-0-101" name="__codelineno-0-101"></a> <span class="n">rendering_engine</span> <span class="o">=</span> <span class="n">engines</span><span class="p">[</span><span class="s2">&quot;jinja&quot;</span><span class="p">]</span>
11763
11795
  <a id="__codelineno-0-102" name="__codelineno-0-102"></a> <span class="n">template</span> <span class="o">=</span> <span class="n">rendering_engine</span><span class="o">.</span><span class="n">from_string</span><span class="p">(</span><span class="n">template_code</span><span class="p">)</span>
11764
- <a id="__codelineno-0-103" name="__codelineno-0-103"></a> <span class="k">return</span> <span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">context</span><span class="o">=</span><span class="n">context</span><span class="p">)</span>
11796
+ <a id="__codelineno-0-103" name="__codelineno-0-103"></a> <span class="c1"># For reasons unknown to me, django-jinja2 `template.render()` implicitly calls `mark_safe()` on the rendered text.</span>
11797
+ <a id="__codelineno-0-104" name="__codelineno-0-104"></a> <span class="c1"># This is a security risk in general, especially so in our case because we&#39;re often using this function to render</span>
11798
+ <a id="__codelineno-0-105" name="__codelineno-0-105"></a> <span class="c1"># a user-provided template and don&#39;t want to open ourselves up to script injection or similar issues.</span>
11799
+ <a id="__codelineno-0-106" name="__codelineno-0-106"></a> <span class="c1"># There&#39;s no `mark_unsafe()` function, but concatenating a SafeString to an ordinary string (even &quot;&quot;) suffices.</span>
11800
+ <a id="__codelineno-0-107" name="__codelineno-0-107"></a> <span class="k">return</span> <span class="s2">&quot;&quot;</span> <span class="o">+</span> <span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">context</span><span class="o">=</span><span class="n">context</span><span class="p">)</span>
11765
11801
  </code></pre></div></td></tr></table></div>
11766
11802
  </details>
11767
11803
  </div>
@@ -11982,11 +12018,7 @@ the first layer of keys/values is checked. <code>exclude</code> is a list or tup
11982
12018
 
11983
12019
  <details class="quote">
11984
12020
  <summary>Source code in <code>nautobot/core/utils/data.py</code></summary>
11985
- <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-106">106</a></span>
11986
- <span class="normal"><a href="#__codelineno-0-107">107</a></span>
11987
- <span class="normal"><a href="#__codelineno-0-108">108</a></span>
11988
- <span class="normal"><a href="#__codelineno-0-109">109</a></span>
11989
- <span class="normal"><a href="#__codelineno-0-110">110</a></span>
12021
+ <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-110">110</a></span>
11990
12022
  <span class="normal"><a href="#__codelineno-0-111">111</a></span>
11991
12023
  <span class="normal"><a href="#__codelineno-0-112">112</a></span>
11992
12024
  <span class="normal"><a href="#__codelineno-0-113">113</a></span>
@@ -11995,20 +12027,24 @@ the first layer of keys/values is checked. <code>exclude</code> is a list or tup
11995
12027
  <span class="normal"><a href="#__codelineno-0-116">116</a></span>
11996
12028
  <span class="normal"><a href="#__codelineno-0-117">117</a></span>
11997
12029
  <span class="normal"><a href="#__codelineno-0-118">118</a></span>
11998
- <span class="normal"><a href="#__codelineno-0-119">119</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-106" name="__codelineno-0-106"></a><span class="k">def</span> <span class="nf">shallow_compare_dict</span><span class="p">(</span><span class="n">source_dict</span><span class="p">,</span> <span class="n">destination_dict</span><span class="p">,</span> <span class="n">exclude</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
11999
- <a id="__codelineno-0-107" name="__codelineno-0-107"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
12000
- <a id="__codelineno-0-108" name="__codelineno-0-108"></a><span class="sd"> Return a new dictionary of the different keys. The values of `destination_dict` are returned. Only the equality of</span>
12001
- <a id="__codelineno-0-109" name="__codelineno-0-109"></a><span class="sd"> the first layer of keys/values is checked. `exclude` is a list or tuple of keys to be ignored.</span>
12002
- <a id="__codelineno-0-110" name="__codelineno-0-110"></a><span class="sd"> &quot;&quot;&quot;</span>
12003
- <a id="__codelineno-0-111" name="__codelineno-0-111"></a> <span class="n">difference</span> <span class="o">=</span> <span class="p">{}</span>
12004
- <a id="__codelineno-0-112" name="__codelineno-0-112"></a>
12005
- <a id="__codelineno-0-113" name="__codelineno-0-113"></a> <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">destination_dict</span><span class="p">:</span>
12006
- <a id="__codelineno-0-114" name="__codelineno-0-114"></a> <span class="k">if</span> <span class="n">source_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="o">!=</span> <span class="n">destination_dict</span><span class="p">[</span><span class="n">key</span><span class="p">]:</span>
12007
- <a id="__codelineno-0-115" name="__codelineno-0-115"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">exclude</span><span class="p">,</span> <span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">))</span> <span class="ow">and</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">exclude</span><span class="p">:</span>
12008
- <a id="__codelineno-0-116" name="__codelineno-0-116"></a> <span class="k">continue</span>
12009
- <a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="n">difference</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">destination_dict</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
12010
- <a id="__codelineno-0-118" name="__codelineno-0-118"></a>
12011
- <a id="__codelineno-0-119" name="__codelineno-0-119"></a> <span class="k">return</span> <span class="n">difference</span>
12030
+ <span class="normal"><a href="#__codelineno-0-119">119</a></span>
12031
+ <span class="normal"><a href="#__codelineno-0-120">120</a></span>
12032
+ <span class="normal"><a href="#__codelineno-0-121">121</a></span>
12033
+ <span class="normal"><a href="#__codelineno-0-122">122</a></span>
12034
+ <span class="normal"><a href="#__codelineno-0-123">123</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-110" name="__codelineno-0-110"></a><span class="k">def</span> <span class="nf">shallow_compare_dict</span><span class="p">(</span><span class="n">source_dict</span><span class="p">,</span> <span class="n">destination_dict</span><span class="p">,</span> <span class="n">exclude</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
12035
+ <a id="__codelineno-0-111" name="__codelineno-0-111"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
12036
+ <a id="__codelineno-0-112" name="__codelineno-0-112"></a><span class="sd"> Return a new dictionary of the different keys. The values of `destination_dict` are returned. Only the equality of</span>
12037
+ <a id="__codelineno-0-113" name="__codelineno-0-113"></a><span class="sd"> the first layer of keys/values is checked. `exclude` is a list or tuple of keys to be ignored.</span>
12038
+ <a id="__codelineno-0-114" name="__codelineno-0-114"></a><span class="sd"> &quot;&quot;&quot;</span>
12039
+ <a id="__codelineno-0-115" name="__codelineno-0-115"></a> <span class="n">difference</span> <span class="o">=</span> <span class="p">{}</span>
12040
+ <a id="__codelineno-0-116" name="__codelineno-0-116"></a>
12041
+ <a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">destination_dict</span><span class="p">:</span>
12042
+ <a id="__codelineno-0-118" name="__codelineno-0-118"></a> <span class="k">if</span> <span class="n">source_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="o">!=</span> <span class="n">destination_dict</span><span class="p">[</span><span class="n">key</span><span class="p">]:</span>
12043
+ <a id="__codelineno-0-119" name="__codelineno-0-119"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">exclude</span><span class="p">,</span> <span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">))</span> <span class="ow">and</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">exclude</span><span class="p">:</span>
12044
+ <a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="k">continue</span>
12045
+ <a id="__codelineno-0-121" name="__codelineno-0-121"></a> <span class="n">difference</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">destination_dict</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
12046
+ <a id="__codelineno-0-122" name="__codelineno-0-122"></a>
12047
+ <a id="__codelineno-0-123" name="__codelineno-0-123"></a> <span class="k">return</span> <span class="n">difference</span>
12012
12048
  </code></pre></div></td></tr></table></div>
12013
12049
  </details>
12014
12050
  </div>
@@ -12121,11 +12157,7 @@ worker count to the description.</p>
12121
12157
 
12122
12158
  <details class="quote">
12123
12159
  <summary>Source code in <code>nautobot/core/utils/data.py</code></summary>
12124
- <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-122">122</a></span>
12125
- <span class="normal"><a href="#__codelineno-0-123">123</a></span>
12126
- <span class="normal"><a href="#__codelineno-0-124">124</a></span>
12127
- <span class="normal"><a href="#__codelineno-0-125">125</a></span>
12128
- <span class="normal"><a href="#__codelineno-0-126">126</a></span>
12160
+ <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-126">126</a></span>
12129
12161
  <span class="normal"><a href="#__codelineno-0-127">127</a></span>
12130
12162
  <span class="normal"><a href="#__codelineno-0-128">128</a></span>
12131
12163
  <span class="normal"><a href="#__codelineno-0-129">129</a></span>
@@ -12141,27 +12173,31 @@ worker count to the description.</p>
12141
12173
  <span class="normal"><a href="#__codelineno-0-139">139</a></span>
12142
12174
  <span class="normal"><a href="#__codelineno-0-140">140</a></span>
12143
12175
  <span class="normal"><a href="#__codelineno-0-141">141</a></span>
12144
- <span class="normal"><a href="#__codelineno-0-142">142</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-122" name="__codelineno-0-122"></a><span class="k">def</span> <span class="nf">to_meters</span><span class="p">(</span><span class="n">length</span><span class="p">,</span> <span class="n">unit</span><span class="p">):</span>
12145
- <a id="__codelineno-0-123" name="__codelineno-0-123"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
12146
- <a id="__codelineno-0-124" name="__codelineno-0-124"></a><span class="sd"> Convert the given length to meters.</span>
12147
- <a id="__codelineno-0-125" name="__codelineno-0-125"></a><span class="sd"> &quot;&quot;&quot;</span>
12148
- <a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="n">length</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">length</span><span class="p">)</span>
12149
- <a id="__codelineno-0-127" name="__codelineno-0-127"></a> <span class="k">if</span> <span class="n">length</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
12150
- <a id="__codelineno-0-128" name="__codelineno-0-128"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Length must be a positive integer&quot;</span><span class="p">)</span>
12151
- <a id="__codelineno-0-129" name="__codelineno-0-129"></a>
12152
- <a id="__codelineno-0-130" name="__codelineno-0-130"></a> <span class="n">valid_units</span> <span class="o">=</span> <span class="n">choices</span><span class="o">.</span><span class="n">CableLengthUnitChoices</span><span class="o">.</span><span class="n">values</span><span class="p">()</span>
12153
- <a id="__codelineno-0-131" name="__codelineno-0-131"></a> <span class="k">if</span> <span class="n">unit</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">valid_units</span><span class="p">:</span>
12154
- <a id="__codelineno-0-132" name="__codelineno-0-132"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Unknown unit </span><span class="si">{</span><span class="n">unit</span><span class="si">}</span><span class="s2">. Must be one of the following: </span><span class="si">{</span><span class="s1">&#39;, &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">valid_units</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
12176
+ <span class="normal"><a href="#__codelineno-0-142">142</a></span>
12177
+ <span class="normal"><a href="#__codelineno-0-143">143</a></span>
12178
+ <span class="normal"><a href="#__codelineno-0-144">144</a></span>
12179
+ <span class="normal"><a href="#__codelineno-0-145">145</a></span>
12180
+ <span class="normal"><a href="#__codelineno-0-146">146</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-126" name="__codelineno-0-126"></a><span class="k">def</span> <span class="nf">to_meters</span><span class="p">(</span><span class="n">length</span><span class="p">,</span> <span class="n">unit</span><span class="p">):</span>
12181
+ <a id="__codelineno-0-127" name="__codelineno-0-127"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
12182
+ <a id="__codelineno-0-128" name="__codelineno-0-128"></a><span class="sd"> Convert the given length to meters.</span>
12183
+ <a id="__codelineno-0-129" name="__codelineno-0-129"></a><span class="sd"> &quot;&quot;&quot;</span>
12184
+ <a id="__codelineno-0-130" name="__codelineno-0-130"></a> <span class="n">length</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">length</span><span class="p">)</span>
12185
+ <a id="__codelineno-0-131" name="__codelineno-0-131"></a> <span class="k">if</span> <span class="n">length</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
12186
+ <a id="__codelineno-0-132" name="__codelineno-0-132"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Length must be a positive integer&quot;</span><span class="p">)</span>
12155
12187
  <a id="__codelineno-0-133" name="__codelineno-0-133"></a>
12156
- <a id="__codelineno-0-134" name="__codelineno-0-134"></a> <span class="k">if</span> <span class="n">unit</span> <span class="o">==</span> <span class="n">choices</span><span class="o">.</span><span class="n">CableLengthUnitChoices</span><span class="o">.</span><span class="n">UNIT_METER</span><span class="p">:</span>
12157
- <a id="__codelineno-0-135" name="__codelineno-0-135"></a> <span class="k">return</span> <span class="n">length</span>
12158
- <a id="__codelineno-0-136" name="__codelineno-0-136"></a> <span class="k">if</span> <span class="n">unit</span> <span class="o">==</span> <span class="n">choices</span><span class="o">.</span><span class="n">CableLengthUnitChoices</span><span class="o">.</span><span class="n">UNIT_CENTIMETER</span><span class="p">:</span>
12159
- <a id="__codelineno-0-137" name="__codelineno-0-137"></a> <span class="k">return</span> <span class="n">length</span> <span class="o">/</span> <span class="mi">100</span>
12160
- <a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="k">if</span> <span class="n">unit</span> <span class="o">==</span> <span class="n">choices</span><span class="o">.</span><span class="n">CableLengthUnitChoices</span><span class="o">.</span><span class="n">UNIT_FOOT</span><span class="p">:</span>
12161
- <a id="__codelineno-0-139" name="__codelineno-0-139"></a> <span class="k">return</span> <span class="n">length</span> <span class="o">*</span> <span class="n">Decimal</span><span class="p">(</span><span class="s2">&quot;0.3048&quot;</span><span class="p">)</span>
12162
- <a id="__codelineno-0-140" name="__codelineno-0-140"></a> <span class="k">if</span> <span class="n">unit</span> <span class="o">==</span> <span class="n">choices</span><span class="o">.</span><span class="n">CableLengthUnitChoices</span><span class="o">.</span><span class="n">UNIT_INCH</span><span class="p">:</span>
12163
- <a id="__codelineno-0-141" name="__codelineno-0-141"></a> <span class="k">return</span> <span class="n">length</span> <span class="o">*</span> <span class="n">Decimal</span><span class="p">(</span><span class="s2">&quot;0.3048&quot;</span><span class="p">)</span> <span class="o">*</span> <span class="mi">12</span>
12164
- <a id="__codelineno-0-142" name="__codelineno-0-142"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Unknown unit </span><span class="si">{</span><span class="n">unit</span><span class="si">}</span><span class="s2">. Must be &#39;m&#39;, &#39;cm&#39;, &#39;ft&#39;, or &#39;in&#39;.&quot;</span><span class="p">)</span>
12188
+ <a id="__codelineno-0-134" name="__codelineno-0-134"></a> <span class="n">valid_units</span> <span class="o">=</span> <span class="n">choices</span><span class="o">.</span><span class="n">CableLengthUnitChoices</span><span class="o">.</span><span class="n">values</span><span class="p">()</span>
12189
+ <a id="__codelineno-0-135" name="__codelineno-0-135"></a> <span class="k">if</span> <span class="n">unit</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">valid_units</span><span class="p">:</span>
12190
+ <a id="__codelineno-0-136" name="__codelineno-0-136"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Unknown unit </span><span class="si">{</span><span class="n">unit</span><span class="si">}</span><span class="s2">. Must be one of the following: </span><span class="si">{</span><span class="s1">&#39;, &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">valid_units</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
12191
+ <a id="__codelineno-0-137" name="__codelineno-0-137"></a>
12192
+ <a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="k">if</span> <span class="n">unit</span> <span class="o">==</span> <span class="n">choices</span><span class="o">.</span><span class="n">CableLengthUnitChoices</span><span class="o">.</span><span class="n">UNIT_METER</span><span class="p">:</span>
12193
+ <a id="__codelineno-0-139" name="__codelineno-0-139"></a> <span class="k">return</span> <span class="n">length</span>
12194
+ <a id="__codelineno-0-140" name="__codelineno-0-140"></a> <span class="k">if</span> <span class="n">unit</span> <span class="o">==</span> <span class="n">choices</span><span class="o">.</span><span class="n">CableLengthUnitChoices</span><span class="o">.</span><span class="n">UNIT_CENTIMETER</span><span class="p">:</span>
12195
+ <a id="__codelineno-0-141" name="__codelineno-0-141"></a> <span class="k">return</span> <span class="n">length</span> <span class="o">/</span> <span class="mi">100</span>
12196
+ <a id="__codelineno-0-142" name="__codelineno-0-142"></a> <span class="k">if</span> <span class="n">unit</span> <span class="o">==</span> <span class="n">choices</span><span class="o">.</span><span class="n">CableLengthUnitChoices</span><span class="o">.</span><span class="n">UNIT_FOOT</span><span class="p">:</span>
12197
+ <a id="__codelineno-0-143" name="__codelineno-0-143"></a> <span class="k">return</span> <span class="n">length</span> <span class="o">*</span> <span class="n">Decimal</span><span class="p">(</span><span class="s2">&quot;0.3048&quot;</span><span class="p">)</span>
12198
+ <a id="__codelineno-0-144" name="__codelineno-0-144"></a> <span class="k">if</span> <span class="n">unit</span> <span class="o">==</span> <span class="n">choices</span><span class="o">.</span><span class="n">CableLengthUnitChoices</span><span class="o">.</span><span class="n">UNIT_INCH</span><span class="p">:</span>
12199
+ <a id="__codelineno-0-145" name="__codelineno-0-145"></a> <span class="k">return</span> <span class="n">length</span> <span class="o">*</span> <span class="n">Decimal</span><span class="p">(</span><span class="s2">&quot;0.3048&quot;</span><span class="p">)</span> <span class="o">*</span> <span class="mi">12</span>
12200
+ <a id="__codelineno-0-146" name="__codelineno-0-146"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Unknown unit </span><span class="si">{</span><span class="n">unit</span><span class="si">}</span><span class="s2">. Must be &#39;m&#39;, &#39;cm&#39;, &#39;ft&#39;, or &#39;in&#39;.&quot;</span><span class="p">)</span>
12165
12201
  </code></pre></div></td></tr></table></div>
12166
12202
  </details>
12167
12203
  </div>