nautobot 2.2.3__py3-none-any.whl → 2.2.4__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 (301) hide show
  1. nautobot/core/settings.py +6 -4
  2. nautobot/core/settings.yaml +51 -16
  3. nautobot/core/templates/admin/base.html +2 -2
  4. nautobot/core/templates/base_django.html +2 -2
  5. nautobot/core/templates/buttons/export.html +47 -47
  6. nautobot/core/templates/inc/javascript.html +3 -0
  7. nautobot/core/templates/inc/media.html +3 -0
  8. nautobot/core/templates/login.html +2 -2
  9. nautobot/core/templates/nautobot_config.py.j2 +2 -0
  10. nautobot/core/tests/test_jobs.py +79 -2
  11. nautobot/core/tests/test_views.py +33 -0
  12. nautobot/core/views/mixins.py +4 -0
  13. nautobot/dcim/tests/test_views.py +239 -55
  14. nautobot/dcim/views.py +23 -20
  15. nautobot/extras/api/serializers.py +17 -6
  16. nautobot/extras/tests/test_context_managers.py +18 -0
  17. nautobot/extras/utils.py +2 -1
  18. nautobot/extras/views.py +35 -21
  19. nautobot/ipam/views.py +6 -6
  20. nautobot/project-static/docs/404.html +107 -51
  21. nautobot/project-static/docs/apps/index.html +107 -51
  22. nautobot/project-static/docs/apps/nautobot-apps.html +107 -51
  23. nautobot/project-static/docs/assets/_mkdocstrings.css +6 -1
  24. nautobot/project-static/docs/assets/extra.css +7 -0
  25. nautobot/project-static/docs/assets/javascripts/bundle.3220b9d7.min.js +29 -0
  26. nautobot/project-static/docs/assets/javascripts/bundle.3220b9d7.min.js.map +7 -0
  27. nautobot/project-static/docs/assets/stylesheets/main.66ac8b77.min.css +1 -0
  28. nautobot/project-static/docs/assets/stylesheets/main.66ac8b77.min.css.map +1 -0
  29. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +107 -51
  30. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +107 -51
  31. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +107 -51
  32. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +107 -51
  33. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +107 -51
  34. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +107 -51
  35. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +107 -51
  36. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +107 -51
  37. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +107 -51
  38. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +107 -51
  39. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +107 -51
  40. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +107 -51
  41. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +107 -51
  42. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +107 -51
  43. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +107 -51
  44. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +107 -51
  45. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +107 -51
  46. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +107 -51
  47. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +107 -51
  48. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +107 -51
  49. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +107 -51
  50. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +107 -51
  51. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +107 -51
  52. nautobot/project-static/docs/development/apps/api/configuration-view.html +110 -54
  53. nautobot/project-static/docs/development/apps/api/database-backend-config.html +110 -54
  54. nautobot/project-static/docs/development/apps/api/models/django-admin.html +107 -51
  55. nautobot/project-static/docs/development/apps/api/models/global-search.html +110 -54
  56. nautobot/project-static/docs/development/apps/api/models/graphql.html +113 -57
  57. nautobot/project-static/docs/development/apps/api/models/index.html +107 -51
  58. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +113 -57
  59. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +107 -51
  60. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +110 -54
  61. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +107 -51
  62. nautobot/project-static/docs/development/apps/api/platform-features/index.html +107 -51
  63. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +110 -54
  64. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +110 -54
  65. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +110 -54
  66. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +110 -54
  67. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +107 -51
  68. nautobot/project-static/docs/development/apps/api/prometheus.html +110 -54
  69. nautobot/project-static/docs/development/apps/api/setup.html +107 -51
  70. nautobot/project-static/docs/development/apps/api/testing.html +113 -57
  71. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +110 -54
  72. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +110 -54
  73. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +107 -51
  74. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +107 -51
  75. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +113 -57
  76. nautobot/project-static/docs/development/apps/api/views/base-template.html +107 -51
  77. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +110 -54
  78. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +107 -51
  79. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +110 -54
  80. nautobot/project-static/docs/development/apps/api/views/index.html +107 -51
  81. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +113 -57
  82. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +122 -66
  83. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +110 -54
  84. nautobot/project-static/docs/development/apps/api/views/notes.html +110 -54
  85. nautobot/project-static/docs/development/apps/api/views/rest-api.html +107 -51
  86. nautobot/project-static/docs/development/apps/api/views/urls.html +107 -51
  87. nautobot/project-static/docs/development/apps/index.html +128 -72
  88. nautobot/project-static/docs/development/apps/migration/code-updates.html +107 -51
  89. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +107 -51
  90. nautobot/project-static/docs/development/apps/migration/from-v1.html +107 -51
  91. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +107 -51
  92. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +107 -51
  93. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +107 -51
  94. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +107 -51
  95. nautobot/project-static/docs/development/apps/porting-from-netbox.html +110 -54
  96. nautobot/project-static/docs/development/core/application-registry.html +119 -63
  97. nautobot/project-static/docs/development/core/best-practices.html +122 -66
  98. nautobot/project-static/docs/development/core/bootstrap-ui.html +107 -51
  99. nautobot/project-static/docs/development/core/caching.html +107 -51
  100. nautobot/project-static/docs/development/core/controllers.html +107 -51
  101. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +113 -57
  102. nautobot/project-static/docs/development/core/generic-views.html +110 -54
  103. nautobot/project-static/docs/development/core/getting-started.html +135 -79
  104. nautobot/project-static/docs/development/core/homepage.html +110 -54
  105. nautobot/project-static/docs/development/core/index.html +107 -51
  106. nautobot/project-static/docs/development/core/model-checklist.html +107 -51
  107. nautobot/project-static/docs/development/core/model-features.html +107 -51
  108. nautobot/project-static/docs/development/core/natural-keys.html +110 -54
  109. nautobot/project-static/docs/development/core/navigation-menu.html +107 -51
  110. nautobot/project-static/docs/development/core/release-checklist.html +107 -51
  111. nautobot/project-static/docs/development/core/role-internals.html +107 -51
  112. nautobot/project-static/docs/development/core/settings.html +107 -51
  113. nautobot/project-static/docs/development/core/style-guide.html +110 -54
  114. nautobot/project-static/docs/development/core/templates.html +113 -57
  115. nautobot/project-static/docs/development/core/testing.html +125 -69
  116. nautobot/project-static/docs/development/core/user-preferences.html +107 -51
  117. nautobot/project-static/docs/development/index.html +107 -51
  118. nautobot/project-static/docs/development/jobs/index.html +173 -117
  119. nautobot/project-static/docs/development/jobs/migration/from-v1.html +110 -54
  120. nautobot/project-static/docs/docker/index.html +3 -3
  121. nautobot/project-static/docs/index.html +125 -69
  122. nautobot/project-static/docs/installation/selinux-troubleshooting.html +3 -3
  123. nautobot/project-static/docs/release-notes/index.html +107 -51
  124. nautobot/project-static/docs/release-notes/version-1.0.html +107 -51
  125. nautobot/project-static/docs/release-notes/version-1.1.html +107 -51
  126. nautobot/project-static/docs/release-notes/version-1.2.html +107 -51
  127. nautobot/project-static/docs/release-notes/version-1.3.html +107 -51
  128. nautobot/project-static/docs/release-notes/version-1.4.html +107 -51
  129. nautobot/project-static/docs/release-notes/version-1.5.html +116 -60
  130. nautobot/project-static/docs/release-notes/version-1.6.html +107 -51
  131. nautobot/project-static/docs/release-notes/version-2.0.html +110 -54
  132. nautobot/project-static/docs/release-notes/version-2.1.html +107 -51
  133. nautobot/project-static/docs/release-notes/version-2.2.html +321 -117
  134. nautobot/project-static/docs/requirements.txt +2 -2
  135. nautobot/project-static/docs/search/search_index.json +1 -1
  136. nautobot/project-static/docs/sitemap.xml +262 -262
  137. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  138. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +107 -51
  139. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +107 -51
  140. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +107 -51
  141. nautobot/project-static/docs/user-guide/administration/configuration/index.html +107 -51
  142. nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +251 -164
  143. nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +113 -57
  144. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +107 -51
  145. nautobot/project-static/docs/user-guide/administration/guides/caching.html +113 -57
  146. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +107 -51
  147. nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +107 -51
  148. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +107 -51
  149. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +113 -57
  150. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +107 -51
  151. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +107 -51
  152. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +107 -51
  153. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +171 -112
  154. nautobot/project-static/docs/user-guide/administration/installation/docker.html +13 -8626
  155. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +117 -61
  156. nautobot/project-static/docs/user-guide/administration/installation/health-checks.html +13 -8614
  157. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +252 -165
  158. nautobot/project-static/docs/user-guide/administration/installation/index.html +165 -192
  159. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +411 -691
  160. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +248 -229
  161. nautobot/project-static/docs/user-guide/administration/installation/selinux-troubleshooting.html +13 -8118
  162. nautobot/project-static/docs/user-guide/administration/installation/services.html +350 -240
  163. nautobot/project-static/docs/user-guide/administration/installation-extras/docker.html +8684 -0
  164. nautobot/project-static/docs/user-guide/administration/installation-extras/health-checks.html +8672 -0
  165. nautobot/project-static/docs/user-guide/administration/installation-extras/selinux-troubleshooting.html +8176 -0
  166. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +110 -54
  167. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +110 -54
  168. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +155 -99
  169. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +107 -51
  170. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +109 -53
  171. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +107 -51
  172. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +107 -51
  173. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +107 -51
  174. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +107 -51
  175. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +107 -51
  176. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +107 -51
  177. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +113 -57
  178. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +113 -57
  179. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +107 -51
  180. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +107 -51
  181. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +107 -51
  182. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +107 -51
  183. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +110 -54
  184. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +107 -51
  185. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +110 -54
  186. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +110 -54
  187. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +110 -54
  188. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +110 -54
  189. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +107 -51
  190. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +107 -51
  191. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +113 -57
  192. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +110 -54
  193. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +110 -54
  194. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +110 -54
  195. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +110 -54
  196. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +116 -60
  197. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +110 -54
  198. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +110 -54
  199. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +119 -63
  200. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +110 -54
  201. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +110 -54
  202. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +113 -57
  203. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +113 -57
  204. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +113 -57
  205. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +107 -51
  206. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +113 -57
  207. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +107 -51
  208. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +110 -54
  209. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +110 -54
  210. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +107 -51
  211. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +110 -54
  212. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +110 -54
  213. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +107 -51
  214. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +107 -51
  215. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +107 -51
  216. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +110 -54
  217. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +110 -54
  218. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +110 -54
  219. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +110 -54
  220. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +107 -51
  221. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +113 -57
  222. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +110 -54
  223. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +110 -54
  224. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +110 -54
  225. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +125 -69
  226. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +113 -57
  227. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +128 -72
  228. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +110 -54
  229. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +107 -51
  230. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +110 -54
  231. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +116 -60
  232. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +107 -51
  233. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +113 -57
  234. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +107 -51
  235. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +110 -54
  236. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +107 -51
  237. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +107 -51
  238. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +107 -51
  239. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +107 -51
  240. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +113 -57
  241. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +113 -57
  242. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +107 -51
  243. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +113 -57
  244. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +107 -51
  245. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +107 -51
  246. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +107 -51
  247. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +107 -51
  248. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +107 -51
  249. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +107 -51
  250. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +107 -51
  251. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +107 -51
  252. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +107 -51
  253. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +110 -54
  254. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +113 -57
  255. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +107 -51
  256. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +110 -54
  257. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +107 -51
  258. nautobot/project-static/docs/user-guide/index.html +109 -53
  259. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +107 -51
  260. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +113 -57
  261. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +128 -72
  262. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +107 -51
  263. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +125 -69
  264. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +107 -51
  265. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +110 -54
  266. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +125 -69
  267. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +110 -54
  268. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +107 -51
  269. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +107 -51
  270. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +128 -72
  271. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +113 -57
  272. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +113 -57
  273. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +110 -54
  274. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +119 -63
  275. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +107 -51
  276. nautobot/project-static/docs/user-guide/platform-functionality/note.html +110 -54
  277. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +116 -60
  278. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +110 -54
  279. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +131 -75
  280. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +149 -93
  281. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +110 -54
  282. nautobot/project-static/docs/user-guide/platform-functionality/role.html +107 -51
  283. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +116 -60
  284. nautobot/project-static/docs/user-guide/platform-functionality/status.html +119 -63
  285. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +110 -54
  286. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +137 -81
  287. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +110 -54
  288. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +107 -51
  289. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +110 -54
  290. nautobot/tenancy/views.py +2 -6
  291. nautobot/virtualization/views.py +5 -9
  292. {nautobot-2.2.3.dist-info → nautobot-2.2.4.dist-info}/METADATA +2 -2
  293. {nautobot-2.2.3.dist-info → nautobot-2.2.4.dist-info}/RECORD +297 -294
  294. nautobot/project-static/docs/assets/javascripts/bundle.bd41221c.min.js +0 -29
  295. nautobot/project-static/docs/assets/javascripts/bundle.bd41221c.min.js.map +0 -7
  296. nautobot/project-static/docs/assets/stylesheets/main.bcfcd587.min.css +0 -1
  297. nautobot/project-static/docs/assets/stylesheets/main.bcfcd587.min.css.map +0 -1
  298. {nautobot-2.2.3.dist-info → nautobot-2.2.4.dist-info}/LICENSE.txt +0 -0
  299. {nautobot-2.2.3.dist-info → nautobot-2.2.4.dist-info}/NOTICE +0 -0
  300. {nautobot-2.2.3.dist-info → nautobot-2.2.4.dist-info}/WHEEL +0 -0
  301. {nautobot-2.2.3.dist-info → nautobot-2.2.4.dist-info}/entry_points.txt +0 -0
nautobot/dcim/views.py CHANGED
@@ -199,6 +199,7 @@ class LocationTypeView(generic.ObjectView):
199
199
  return {
200
200
  "children_table": children_table,
201
201
  "locations_table": locations_table,
202
+ **super().get_extra_context(request, instance),
202
203
  }
203
204
 
204
205
 
@@ -297,6 +298,7 @@ class LocationView(generic.ObjectView):
297
298
  "contact_association_permission": ["extras.add_contactassociation"],
298
299
  # show the button if any of these fields have non-empty value.
299
300
  "show_convert_to_contact_button": instance.contact_name or instance.contact_phone or instance.contact_email,
301
+ **super().get_extra_context(request, instance),
300
302
  }
301
303
 
302
304
 
@@ -494,9 +496,7 @@ class RackGroupView(generic.ObjectView):
494
496
  }
495
497
  RequestConfig(request, paginate).configure(rack_table)
496
498
 
497
- return {
498
- "rack_table": rack_table,
499
- }
499
+ return {"rack_table": rack_table, **super().get_extra_context(request, instance)}
500
500
 
501
501
 
502
502
  class RackGroupEditView(generic.ObjectEditView):
@@ -615,6 +615,7 @@ class RackView(generic.ObjectView):
615
615
  "nonracked_devices": nonracked_devices,
616
616
  "next_rack": next_rack,
617
617
  "prev_rack": prev_rack,
618
+ **super().get_extra_context(request, instance),
618
619
  }
619
620
 
620
621
 
@@ -731,9 +732,7 @@ class ManufacturerView(generic.ObjectView):
731
732
  }
732
733
  RequestConfig(request, paginate).configure(device_table)
733
734
 
734
- return {
735
- "device_table": device_table,
736
- }
735
+ return {"device_table": device_table, **super().get_extra_context(request, instance)}
737
736
 
738
737
 
739
738
  class ManufacturerEditView(generic.ObjectEditView):
@@ -839,6 +838,7 @@ class DeviceTypeView(generic.ObjectView):
839
838
  "rear_port_table": rear_port_table,
840
839
  "devicebay_table": devicebay_table,
841
840
  "software_image_files_table": software_image_files_table,
841
+ **super().get_extra_context(request, instance),
842
842
  }
843
843
 
844
844
 
@@ -1237,6 +1237,7 @@ class PlatformView(generic.ObjectView):
1237
1237
  return {
1238
1238
  "device_table": device_table,
1239
1239
  "network_driver_tool_names": get_network_driver_mapping_tool_names(),
1240
+ **super().get_extra_context(request, instance),
1240
1241
  }
1241
1242
 
1242
1243
 
@@ -1246,7 +1247,10 @@ class PlatformEditView(generic.ObjectEditView):
1246
1247
  template_name = "dcim/platform_edit.html"
1247
1248
 
1248
1249
  def get_extra_context(self, request, instance):
1249
- return {"network_driver_names": sorted(get_all_network_driver_mappings().keys())}
1250
+ return {
1251
+ "network_driver_names": sorted(get_all_network_driver_mappings().keys()),
1252
+ **super().get_extra_context(request, instance),
1253
+ }
1250
1254
 
1251
1255
 
1252
1256
  class PlatformDeleteView(generic.ObjectDeleteView):
@@ -1637,7 +1641,7 @@ class ConsolePortView(generic.ObjectView):
1637
1641
  queryset = ConsolePort.objects.all()
1638
1642
 
1639
1643
  def get_extra_context(self, request, instance):
1640
- return {"breadcrumb_url": "dcim:device_consoleports"}
1644
+ return {"breadcrumb_url": "dcim:device_consoleports", **super().get_extra_context(request, instance)}
1641
1645
 
1642
1646
 
1643
1647
  class ConsolePortCreateView(generic.ComponentCreateView):
@@ -1699,7 +1703,7 @@ class ConsoleServerPortView(generic.ObjectView):
1699
1703
  queryset = ConsoleServerPort.objects.all()
1700
1704
 
1701
1705
  def get_extra_context(self, request, instance):
1702
- return {"breadcrumb_url": "dcim:device_consoleserverports"}
1706
+ return {"breadcrumb_url": "dcim:device_consoleserverports", **super().get_extra_context(request, instance)}
1703
1707
 
1704
1708
 
1705
1709
  class ConsoleServerPortCreateView(generic.ComponentCreateView):
@@ -1761,7 +1765,7 @@ class PowerPortView(generic.ObjectView):
1761
1765
  queryset = PowerPort.objects.all()
1762
1766
 
1763
1767
  def get_extra_context(self, request, instance):
1764
- return {"breadcrumb_url": "dcim:device_powerports"}
1768
+ return {"breadcrumb_url": "dcim:device_powerports", **super().get_extra_context(request, instance)}
1765
1769
 
1766
1770
 
1767
1771
  class PowerPortCreateView(generic.ComponentCreateView):
@@ -1823,7 +1827,7 @@ class PowerOutletView(generic.ObjectView):
1823
1827
  queryset = PowerOutlet.objects.all()
1824
1828
 
1825
1829
  def get_extra_context(self, request, instance):
1826
- return {"breadcrumb_url": "dcim:device_poweroutlets"}
1830
+ return {"breadcrumb_url": "dcim:device_poweroutlets", **super().get_extra_context(request, instance)}
1827
1831
 
1828
1832
 
1829
1833
  class PowerOutletCreateView(generic.ComponentCreateView):
@@ -1919,6 +1923,7 @@ class InterfaceView(generic.ObjectView):
1919
1923
  "breadcrumb_url": "dcim:device_interfaces",
1920
1924
  "child_interfaces_table": child_interfaces_tables,
1921
1925
  "redundancy_table": redundancy_table,
1926
+ **super().get_extra_context(request, instance),
1922
1927
  }
1923
1928
 
1924
1929
  def _get_interface_redundancy_groups_table(self, request, instance):
@@ -2005,7 +2010,7 @@ class FrontPortView(generic.ObjectView):
2005
2010
  queryset = FrontPort.objects.all()
2006
2011
 
2007
2012
  def get_extra_context(self, request, instance):
2008
- return {"breadcrumb_url": "dcim:device_frontports"}
2013
+ return {"breadcrumb_url": "dcim:device_frontports", **super().get_extra_context(request, instance)}
2009
2014
 
2010
2015
 
2011
2016
  class FrontPortCreateView(generic.ComponentCreateView):
@@ -2067,7 +2072,7 @@ class RearPortView(generic.ObjectView):
2067
2072
  queryset = RearPort.objects.all()
2068
2073
 
2069
2074
  def get_extra_context(self, request, instance):
2070
- return {"breadcrumb_url": "dcim:device_rearports"}
2075
+ return {"breadcrumb_url": "dcim:device_rearports", **super().get_extra_context(request, instance)}
2071
2076
 
2072
2077
 
2073
2078
  class RearPortCreateView(generic.ComponentCreateView):
@@ -2129,7 +2134,7 @@ class DeviceBayView(generic.ObjectView):
2129
2134
  queryset = DeviceBay.objects.all()
2130
2135
 
2131
2136
  def get_extra_context(self, request, instance):
2132
- return {"breadcrumb_url": "dcim:device_devicebays"}
2137
+ return {"breadcrumb_url": "dcim:device_devicebays", **super().get_extra_context(request, instance)}
2133
2138
 
2134
2139
 
2135
2140
  class DeviceBayCreateView(generic.ComponentCreateView):
@@ -2281,6 +2286,7 @@ class InventoryItemView(generic.ObjectView):
2281
2286
  return {
2282
2287
  "breadcrumb_url": "dcim:device_inventory",
2283
2288
  "software_version_images": software_version_images,
2289
+ **super().get_extra_context(request, instance),
2284
2290
  }
2285
2291
 
2286
2292
 
@@ -2488,6 +2494,7 @@ class PathTraceView(generic.ObjectView):
2488
2494
  "path": path,
2489
2495
  "related_paths": related_paths,
2490
2496
  "total_length": path.get_total_length() if path else None,
2497
+ **super().get_extra_context(request, instance),
2491
2498
  }
2492
2499
 
2493
2500
 
@@ -2698,9 +2705,7 @@ class VirtualChassisView(generic.ObjectView):
2698
2705
  def get_extra_context(self, request, instance):
2699
2706
  members = Device.objects.restrict(request.user).filter(virtual_chassis=instance)
2700
2707
 
2701
- return {
2702
- "members": members,
2703
- }
2708
+ return {"members": members, **super().get_extra_context(request, instance)}
2704
2709
 
2705
2710
 
2706
2711
  class VirtualChassisCreateView(generic.ObjectEditView):
@@ -2938,9 +2943,7 @@ class PowerPanelView(generic.ObjectView):
2938
2943
  powerfeed_table = tables.PowerFeedTable(data=power_feeds, orderable=False)
2939
2944
  powerfeed_table.exclude = ["power_panel"]
2940
2945
 
2941
- return {
2942
- "powerfeed_table": powerfeed_table,
2943
- }
2946
+ return {"powerfeed_table": powerfeed_table, **super().get_extra_context(request, instance)}
2944
2947
 
2945
2948
 
2946
2949
  class PowerPanelEditView(generic.ObjectEditView):
@@ -223,17 +223,28 @@ class ContactAssociationSerializer(NautobotModelSerializer):
223
223
  }
224
224
 
225
225
  def validate(self, data):
226
- # Validate uniqueness of (contact/team, role)
226
+ # Validate uniqueness of (associated object, associated object type, contact/team, role)
227
+ unique_together_fields = None
228
+
227
229
  if data.get("contact") and data.get("role"):
228
- validator = UniqueTogetherValidator(
229
- queryset=ContactAssociation.objects.all(),
230
- fields=("contact", "role"),
230
+ unique_together_fields = (
231
+ "associated_object_type",
232
+ "associated_object_id",
233
+ "contact",
234
+ "role",
231
235
  )
232
- validator(data, self)
233
236
  elif data.get("team") and data.get("role"):
237
+ unique_together_fields = (
238
+ "associated_object_type",
239
+ "associated_object_id",
240
+ "team",
241
+ "role",
242
+ )
243
+
244
+ if unique_together_fields is not None:
234
245
  validator = UniqueTogetherValidator(
235
246
  queryset=ContactAssociation.objects.all(),
236
- fields=("team", "role"),
247
+ fields=unique_together_fields,
237
248
  )
238
249
  validator(data, self)
239
250
 
@@ -12,6 +12,7 @@ from nautobot.extras.context_managers import (
12
12
  web_request_context,
13
13
  )
14
14
  from nautobot.extras.models import Status, Webhook
15
+ from nautobot.extras.utils import bulk_delete_with_bulk_change_logging
15
16
 
16
17
  # Use the proper swappable User model
17
18
  User = get_user_model()
@@ -231,6 +232,23 @@ class BulkEditDeleteChangeLogging(TestCase):
231
232
  location.save()
232
233
  location.delete()
233
234
 
235
+ def test_bulk_delete_has_user_in_change_log(self):
236
+ """Test that the bulk delete operation adds the user to the change log"""
237
+ location_type = LocationType.objects.get(name="Campus")
238
+ location_status = Status.objects.get_for_model(Location).first()
239
+ with web_request_context(self.user):
240
+ location = Location(name="Test Location 1", location_type=location_type, status=location_status)
241
+ location.save()
242
+ location_pk = location.pk
243
+ location_qs = Location.objects.filter(pk=location_pk)
244
+ bulk_delete_with_bulk_change_logging(location_qs)
245
+
246
+ oc_list = get_changes_for_model(location)
247
+ self.assertEqual(len(oc_list), 2)
248
+ self.assertEqual(oc_list[0].action, ObjectChangeActionChoices.ACTION_DELETE)
249
+ self.assertEqual(oc_list[0].user, self.user)
250
+ self.assertEqual(oc_list[0].user_name, self.user.username)
251
+
234
252
  def test_create_then_update(self):
235
253
  """Test that a create followed by an update is logged as a single create"""
236
254
  location_type = LocationType.objects.get(name="Campus")
nautobot/extras/utils.py CHANGED
@@ -637,7 +637,8 @@ def bulk_delete_with_bulk_change_logging(qs, batch_size=1000):
637
637
  ObjectChange.objects.bulk_create(queued_object_changes)
638
638
  queued_object_changes = []
639
639
  oc = obj.to_objectchange(ObjectChangeActionChoices.ACTION_DELETE)
640
- oc.user = change_context.user
640
+ oc.user = change_context.get_user()
641
+ oc.user_name = oc.user.username
641
642
  oc.request_id = change_context.change_id
642
643
  oc.change_context = change_context.context
643
644
  oc.change_context_detail = change_context.context_detail[:CHANGELOG_MAX_CHANGE_CONTEXT_DETAIL]
nautobot/extras/views.py CHANGED
@@ -152,19 +152,18 @@ class ConfigContextView(generic.ObjectView):
152
152
  queryset = ConfigContext.objects.all()
153
153
 
154
154
  def get_extra_context(self, request, instance):
155
+ context = super().get_extra_context(request, instance)
155
156
  # Determine user's preferred output format
156
157
  if request.GET.get("format") in ["json", "yaml"]:
157
- format_ = request.GET.get("format")
158
+ context["format"] = request.GET.get("format")
158
159
  if request.user.is_authenticated:
159
- request.user.set_config("extras.configcontext.format", format_, commit=True)
160
+ request.user.set_config("extras.configcontext.format", context["format"], commit=True)
160
161
  elif request.user.is_authenticated:
161
- format_ = request.user.get_config("extras.configcontext.format", "json")
162
+ context["format"] = request.user.get_config("extras.configcontext.format", "json")
162
163
  else:
163
- format_ = "json"
164
+ context["format"] = "json"
164
165
 
165
- return {
166
- "format": format_,
167
- }
166
+ return context
168
167
 
169
168
 
170
169
  class ConfigContextEditView(generic.ObjectEditView):
@@ -236,19 +235,18 @@ class ConfigContextSchemaView(generic.ObjectView):
236
235
  queryset = ConfigContextSchema.objects.all()
237
236
 
238
237
  def get_extra_context(self, request, instance):
238
+ context = super().get_extra_context(request, instance)
239
239
  # Determine user's preferred output format
240
240
  if request.GET.get("format") in ["json", "yaml"]:
241
- format_ = request.GET.get("format")
241
+ context["format"] = request.GET.get("format")
242
242
  if request.user.is_authenticated:
243
- request.user.set_config("extras.configcontextschema.format", format_, commit=True)
243
+ request.user.set_config("extras.configcontextschema.format", context["format"], commit=True)
244
244
  elif request.user.is_authenticated:
245
- format_ = request.user.get_config("extras.configcontextschema.format", "json")
245
+ context["format"] = request.user.get_config("extras.configcontextschema.format", "json")
246
246
  else:
247
- format_ = "json"
247
+ context["format"] = "json"
248
248
 
249
- return {
250
- "format": format_,
251
- }
249
+ return context
252
250
 
253
251
 
254
252
  class ConfigContextSchemaObjectValidationView(generic.ObjectView):
@@ -994,6 +992,7 @@ class GitRepositoryView(generic.ObjectView):
994
992
  def get_extra_context(self, request, instance):
995
993
  return {
996
994
  "datasource_contents": get_datasource_contents("extras.gitrepository"),
995
+ **super().get_extra_context(request, instance),
997
996
  }
998
997
 
999
998
 
@@ -1520,9 +1519,7 @@ class JobApprovalRequestView(generic.ObjectView):
1520
1519
  else:
1521
1520
  job_form = None
1522
1521
 
1523
- return {
1524
- "job_form": job_form,
1525
- }
1522
+ return {"job_form": job_form, **super().get_extra_context(request, instance)}
1526
1523
 
1527
1524
  def post(self, request, pk):
1528
1525
  """
@@ -1652,7 +1649,11 @@ class ScheduledJobView(generic.ObjectView):
1652
1649
  labels[name] = field.label
1653
1650
  else:
1654
1651
  labels[name] = pretty_name(name)
1655
- return {"labels": labels, "job_class_found": (job_class is not None)}
1652
+ return {
1653
+ "labels": labels,
1654
+ "job_class_found": (job_class is not None),
1655
+ **super().get_extra_context(request, instance),
1656
+ }
1656
1657
 
1657
1658
 
1658
1659
  class ScheduledJobDeleteView(generic.ObjectDeleteView):
@@ -1676,7 +1677,10 @@ class JobHookView(generic.ObjectView):
1676
1677
  queryset = JobHook.objects.all()
1677
1678
 
1678
1679
  def get_extra_context(self, request, instance):
1679
- return {"content_types": instance.content_types.order_by("app_label", "model")}
1680
+ return {
1681
+ "content_types": instance.content_types.order_by("app_label", "model"),
1682
+ **super().get_extra_context(request, instance),
1683
+ }
1680
1684
 
1681
1685
 
1682
1686
  class JobHookEditView(generic.ObjectEditView):
@@ -1761,6 +1765,7 @@ class JobResultView(generic.ObjectView):
1761
1765
  "job": job_class,
1762
1766
  "associated_record": associated_record,
1763
1767
  "result": instance,
1768
+ **super().get_extra_context(request, instance),
1764
1769
  }
1765
1770
 
1766
1771
 
@@ -1848,6 +1853,7 @@ class ObjectChangeView(generic.ObjectView):
1848
1853
  "prev_change": instance.get_prev_change(request.user),
1849
1854
  "related_changes_table": related_changes_table,
1850
1855
  "related_changes_count": related_changes.count(),
1856
+ **super().get_extra_context(request, instance),
1851
1857
  }
1852
1858
 
1853
1859
 
@@ -2192,6 +2198,7 @@ class SecretView(generic.ObjectView):
2192
2198
  "format": format_,
2193
2199
  "provider_name": provider.name if provider else instance.provider,
2194
2200
  "groups_table": groups_table,
2201
+ **super().get_extra_context(request, instance),
2195
2202
  }
2196
2203
 
2197
2204
 
@@ -2407,7 +2414,10 @@ class StatusView(generic.ObjectView):
2407
2414
 
2408
2415
  def get_extra_context(self, request, instance):
2409
2416
  """Return ordered content types."""
2410
- return {"content_types": instance.content_types.order_by("app_label", "model")}
2417
+ return {
2418
+ "content_types": instance.content_types.order_by("app_label", "model"),
2419
+ **super().get_extra_context(request, instance),
2420
+ }
2411
2421
 
2412
2422
 
2413
2423
  #
@@ -2442,6 +2452,7 @@ class TagView(generic.ObjectView):
2442
2452
  "items_count": tagged_items.count(),
2443
2453
  "items_table": items_table,
2444
2454
  "content_types": instance.content_types.order_by("app_label", "model"),
2455
+ **super().get_extra_context(request, instance),
2445
2456
  }
2446
2457
 
2447
2458
 
@@ -2522,7 +2533,10 @@ class WebhookView(generic.ObjectView):
2522
2533
  queryset = Webhook.objects.all()
2523
2534
 
2524
2535
  def get_extra_context(self, request, instance):
2525
- return {"content_types": instance.content_types.order_by("app_label", "model")}
2536
+ return {
2537
+ "content_types": instance.content_types.order_by("app_label", "model"),
2538
+ **super().get_extra_context(request, instance),
2539
+ }
2526
2540
 
2527
2541
 
2528
2542
  class WebhookEditView(generic.ObjectEditView):
nautobot/ipam/views.py CHANGED
@@ -332,6 +332,7 @@ class RouteTargetView(generic.ObjectView):
332
332
  return {
333
333
  "importing_vrfs_table": importing_vrfs_table,
334
334
  "exporting_vrfs_table": exporting_vrfs_table,
335
+ **super().get_extra_context(request, instance),
335
336
  }
336
337
 
337
338
 
@@ -389,9 +390,7 @@ class RIRView(generic.ObjectView):
389
390
  }
390
391
  RequestConfig(request, paginate).configure(assigned_prefix_table)
391
392
 
392
- return {
393
- "assigned_prefix_table": assigned_prefix_table,
394
- }
393
+ return {"assigned_prefix_table": assigned_prefix_table, **super().get_extra_context(request, instance)}
395
394
 
396
395
 
397
396
  class RIREditView(generic.ObjectEditView):
@@ -457,6 +456,7 @@ class PrefixView(generic.ObjectView):
457
456
  return {
458
457
  "vrf_table": vrf_table,
459
458
  "parent_prefix_table": parent_prefix_table,
459
+ **super().get_extra_context(request, instance),
460
460
  }
461
461
 
462
462
 
@@ -780,6 +780,7 @@ class IPAddressView(generic.ObjectView):
780
780
  return {
781
781
  "parent_prefixes_table": parent_prefixes_table,
782
782
  "related_ips_table": related_ips_table,
783
+ **super().get_extra_context(request, instance),
783
784
  }
784
785
 
785
786
 
@@ -1261,6 +1262,7 @@ class VLANGroupView(generic.ObjectView):
1261
1262
  "vlan_table": vlan_table,
1262
1263
  "permissions": permissions,
1263
1264
  "vlans_count": vlans_count,
1265
+ **super().get_extra_context(request, instance),
1264
1266
  }
1265
1267
 
1266
1268
 
@@ -1317,9 +1319,7 @@ class VLANView(generic.ObjectView):
1317
1319
  prefix_table = tables.PrefixTable(list(prefixes))
1318
1320
  prefix_table.exclude = ("vlan",)
1319
1321
 
1320
- return {
1321
- "prefix_table": prefix_table,
1322
- }
1322
+ return {"prefix_table": prefix_table, **super().get_extra_context(request, instance)}
1323
1323
 
1324
1324
 
1325
1325
  class VLANInterfacesView(generic.ObjectView):