nautobot 2.4.6__py3-none-any.whl → 2.4.7__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.
- nautobot/apps/forms.py +2 -0
- nautobot/circuits/templates/circuits/providernetwork.html +1 -1
- nautobot/circuits/templates/circuits/providernetwork_retrieve.html +2 -55
- nautobot/circuits/views.py +20 -23
- nautobot/cloud/templates/cloud/cloudaccount_retrieve.html +2 -40
- nautobot/cloud/views.py +12 -0
- nautobot/core/api/urls.py +2 -2
- nautobot/core/api/views.py +39 -1
- nautobot/core/forms/__init__.py +2 -0
- nautobot/core/forms/fields.py +2 -2
- nautobot/core/forms/widgets.py +18 -0
- nautobot/core/templates/widgets/sluginput.html +5 -1
- nautobot/core/templatetags/helpers.py +15 -1
- nautobot/core/testing/integration.py +6 -2
- nautobot/core/ui/object_detail.py +16 -3
- nautobot/core/utils/lookup.py +2 -2
- nautobot/dcim/forms.py +10 -0
- nautobot/dcim/models/locations.py +9 -0
- nautobot/dcim/templates/dcim/device_list.html +1 -1
- nautobot/dcim/templates/dcim/devicetype.html +1 -1
- nautobot/dcim/templates/dcim/manufacturer.html +1 -63
- nautobot/dcim/templates/dcim/module_list.html +1 -1
- nautobot/dcim/templates/dcim/moduletype_retrieve.html +1 -1
- nautobot/dcim/tests/integration/test_module_bay_position.py +125 -0
- nautobot/dcim/tests/test_models.py +13 -0
- nautobot/dcim/tests/test_views.py +4 -1
- nautobot/dcim/urls.py +1 -45
- nautobot/dcim/views.py +35 -66
- nautobot/extras/choices.py +4 -0
- nautobot/extras/filters/__init__.py +6 -0
- nautobot/extras/forms/forms.py +76 -8
- nautobot/extras/models/customfields.py +10 -9
- nautobot/extras/signals.py +43 -4
- nautobot/extras/tasks.py +4 -2
- nautobot/extras/templates/extras/contact_retrieve.html +1 -58
- nautobot/extras/templates/extras/exporttemplate.html +1 -53
- nautobot/extras/templates/extras/team_retrieve.html +1 -58
- nautobot/extras/tests/test_customfields.py +24 -0
- nautobot/extras/tests/test_views.py +22 -0
- nautobot/extras/urls.py +2 -70
- nautobot/extras/views.py +101 -79
- nautobot/ipam/tables.py +1 -0
- nautobot/project-static/css/base.css +5 -0
- nautobot/project-static/docs/404.html +0 -2
- nautobot/project-static/docs/apps/index.html +0 -2
- nautobot/project-static/docs/apps/nautobot-apps.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/events.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +62 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +7 -5
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +0 -2
- nautobot/project-static/docs/development/apps/api/configuration-view.html +0 -2
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +0 -2
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +0 -2
- nautobot/project-static/docs/development/apps/api/models/global-search.html +0 -2
- nautobot/project-static/docs/development/apps/api/models/graphql.html +0 -2
- nautobot/project-static/docs/development/apps/api/models/index.html +0 -2
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +0 -2
- nautobot/project-static/docs/development/apps/api/prometheus.html +0 -2
- nautobot/project-static/docs/development/apps/api/setup.html +0 -2
- nautobot/project-static/docs/development/apps/api/testing.html +0 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +0 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +0 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +0 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +0 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/base-template.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/index.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/notes.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/urls.html +0 -2
- nautobot/project-static/docs/development/apps/index.html +0 -2
- nautobot/project-static/docs/development/apps/migration/code-updates.html +0 -2
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +0 -2
- nautobot/project-static/docs/development/apps/migration/from-v1.html +0 -2
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +0 -2
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +0 -2
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +0 -2
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +0 -2
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +0 -2
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +0 -2
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +0 -2
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +0 -2
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +0 -2
- nautobot/project-static/docs/development/core/application-registry.html +0 -2
- nautobot/project-static/docs/development/core/best-practices.html +0 -2
- nautobot/project-static/docs/development/core/bootstrap-ui.html +0 -2
- nautobot/project-static/docs/development/core/caching.html +0 -2
- nautobot/project-static/docs/development/core/controllers.html +0 -2
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +0 -2
- nautobot/project-static/docs/development/core/generic-views.html +0 -2
- nautobot/project-static/docs/development/core/getting-started.html +0 -2
- nautobot/project-static/docs/development/core/homepage.html +0 -2
- nautobot/project-static/docs/development/core/index.html +0 -2
- nautobot/project-static/docs/development/core/minikube-dev-environment-for-k8s-jobs.html +0 -2
- nautobot/project-static/docs/development/core/model-checklist.html +0 -2
- nautobot/project-static/docs/development/core/model-features.html +0 -2
- nautobot/project-static/docs/development/core/natural-keys.html +0 -2
- nautobot/project-static/docs/development/core/navigation-menu.html +0 -2
- nautobot/project-static/docs/development/core/release-checklist.html +0 -2
- nautobot/project-static/docs/development/core/role-internals.html +0 -2
- nautobot/project-static/docs/development/core/settings.html +0 -2
- nautobot/project-static/docs/development/core/style-guide.html +0 -2
- nautobot/project-static/docs/development/core/templates.html +0 -2
- nautobot/project-static/docs/development/core/testing.html +0 -2
- nautobot/project-static/docs/development/core/ui-component-framework.html +0 -2
- nautobot/project-static/docs/development/core/user-preferences.html +0 -2
- nautobot/project-static/docs/development/index.html +0 -2
- nautobot/project-static/docs/development/jobs/index.html +0 -2
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +0 -2
- nautobot/project-static/docs/index.html +0 -2
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/overview/application_stack.html +0 -2
- nautobot/project-static/docs/overview/design_philosophy.html +0 -2
- nautobot/project-static/docs/release-notes/index.html +0 -2
- nautobot/project-static/docs/release-notes/version-1.0.html +0 -2
- nautobot/project-static/docs/release-notes/version-1.1.html +0 -2
- nautobot/project-static/docs/release-notes/version-1.2.html +0 -2
- nautobot/project-static/docs/release-notes/version-1.3.html +0 -2
- nautobot/project-static/docs/release-notes/version-1.4.html +0 -2
- nautobot/project-static/docs/release-notes/version-1.5.html +0 -2
- nautobot/project-static/docs/release-notes/version-1.6.html +0 -2
- nautobot/project-static/docs/release-notes/version-2.0.html +0 -2
- nautobot/project-static/docs/release-notes/version-2.1.html +0 -2
- nautobot/project-static/docs/release-notes/version-2.2.html +0 -2
- nautobot/project-static/docs/release-notes/version-2.3.html +0 -2
- nautobot/project-static/docs/release-notes/version-2.4.html +138 -2
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +290 -290
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +0 -2
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +0 -2
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +0 -2
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +0 -2
- nautobot/project-static/docs/user-guide/administration/configuration/redis.html +0 -2
- nautobot/project-static/docs/user-guide/administration/configuration/settings.html +0 -2
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/docker.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +0 -2
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +0 -2
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +0 -2
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +0 -2
- nautobot/project-static/docs/user-guide/administration/installation/index.html +0 -2
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +0 -2
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +0 -2
- nautobot/project-static/docs/user-guide/administration/installation/services.html +0 -2
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +0 -2
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +0 -2
- nautobot/project-static/docs/user-guide/administration/security/index.html +0 -2
- nautobot/project-static/docs/user-guide/administration/security/notices.html +0 -2
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +0 -2
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +0 -2
- nautobot/project-static/docs/user-guide/index.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/events.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +0 -2
- nautobot/project-static/js/forms.js +88 -37
- nautobot/project-static/js/homepage_layout.js +12 -3
- {nautobot-2.4.6.dist-info → nautobot-2.4.7.dist-info}/METADATA +1 -1
- {nautobot-2.4.6.dist-info → nautobot-2.4.7.dist-info}/RECORD +346 -346
- nautobot/dcim/templates/dcim/modulebay_create.html +0 -39
- {nautobot-2.4.6.dist-info → nautobot-2.4.7.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.4.6.dist-info → nautobot-2.4.7.dist-info}/NOTICE +0 -0
- {nautobot-2.4.6.dist-info → nautobot-2.4.7.dist-info}/WHEEL +0 -0
- {nautobot-2.4.6.dist-info → nautobot-2.4.7.dist-info}/entry_points.txt +0 -0
nautobot/apps/forms.py
CHANGED
|
@@ -53,6 +53,7 @@ from nautobot.core.forms.utils import (
|
|
|
53
53
|
from nautobot.core.forms.widgets import (
|
|
54
54
|
APISelect,
|
|
55
55
|
APISelectMultiple,
|
|
56
|
+
AutoPopulateWidget,
|
|
56
57
|
BulkEditNullBooleanSelect,
|
|
57
58
|
ColorSelect,
|
|
58
59
|
ContentTypeSelect,
|
|
@@ -102,6 +103,7 @@ __all__ = (
|
|
|
102
103
|
"APISelect",
|
|
103
104
|
"APISelectMultiple",
|
|
104
105
|
"AddressFieldMixin",
|
|
106
|
+
"AutoPopulateWidget",
|
|
105
107
|
"BootstrapMixin",
|
|
106
108
|
"BulkEditForm",
|
|
107
109
|
"BulkEditNullBooleanSelect",
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
{% extends 'circuits/providernetwork_retrieve.html' %}
|
|
2
|
-
{% comment %}
|
|
2
|
+
{% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
|
|
@@ -1,57 +1,4 @@
|
|
|
1
1
|
{% extends 'generic/object_retrieve.html' %}
|
|
2
|
-
{%
|
|
3
|
-
{% load helpers %}
|
|
4
|
-
{% load plugins %}
|
|
5
|
-
|
|
6
|
-
{% block breadcrumbs %}
|
|
7
|
-
<li><a href="{% url 'circuits:providernetwork_list' %}">Provider Networks</a></li>
|
|
2
|
+
{% block extra_breadcrumbs %}
|
|
8
3
|
<li><a href="{% url 'circuits:providernetwork_list' %}?provider={{ object.provider_id }}">{{ object.provider }}</a></li>
|
|
9
|
-
|
|
10
|
-
{% endblock %}
|
|
11
|
-
|
|
12
|
-
{% block content_left_page %}
|
|
13
|
-
<div class="panel panel-default">
|
|
14
|
-
<div class="panel-heading">
|
|
15
|
-
<strong>Provider Network</strong>
|
|
16
|
-
</div>
|
|
17
|
-
<table class="table table-hover panel-body attr-table">
|
|
18
|
-
<tr>
|
|
19
|
-
<td>Provider</td>
|
|
20
|
-
<td>{{ object.provider|hyperlinked_object }}</td>
|
|
21
|
-
</tr>
|
|
22
|
-
<tr>
|
|
23
|
-
<td>Name</td>
|
|
24
|
-
<td>{{ object.name }}</td>
|
|
25
|
-
</tr>
|
|
26
|
-
<tr>
|
|
27
|
-
<td>Description</td>
|
|
28
|
-
<td>{{ object.description }}</td>
|
|
29
|
-
</tr>
|
|
30
|
-
</table>
|
|
31
|
-
</div>
|
|
32
|
-
{% endblock content_left_page %}
|
|
33
|
-
|
|
34
|
-
{% block content_right_page %}
|
|
35
|
-
<div class="panel panel-default">
|
|
36
|
-
<div class="panel-heading">
|
|
37
|
-
<strong>Comments</strong>
|
|
38
|
-
</div>
|
|
39
|
-
<div class="panel-body rendered-markdown">
|
|
40
|
-
{% if object.comments %}
|
|
41
|
-
{{ object.comments|render_markdown }}
|
|
42
|
-
{% else %}
|
|
43
|
-
<span class="text-muted">None</span>
|
|
44
|
-
{% endif %}
|
|
45
|
-
</div>
|
|
46
|
-
</div>
|
|
47
|
-
{% endblock content_right_page %}
|
|
48
|
-
|
|
49
|
-
{% block content_full_width_page %}
|
|
50
|
-
<div class="panel panel-default">
|
|
51
|
-
<div class="panel-heading">
|
|
52
|
-
<strong>Circuits</strong>
|
|
53
|
-
</div>
|
|
54
|
-
{% include 'inc/table.html' with table=circuits_table %}
|
|
55
|
-
</div>
|
|
56
|
-
{% include 'inc/paginator.html' with paginator=circuits_table.paginator page=circuits_table.page %}
|
|
57
|
-
{% endblock content_full_width_page %}
|
|
4
|
+
{% endblock extra_breadcrumbs %}
|
nautobot/circuits/views.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from django.contrib import messages
|
|
2
2
|
from django.db import transaction
|
|
3
|
-
from django.db.models import Q
|
|
4
3
|
from django.shortcuts import get_object_or_404, redirect, render
|
|
5
4
|
from django.utils.html import format_html
|
|
6
5
|
from django_tables2 import RequestConfig
|
|
@@ -300,28 +299,26 @@ class ProviderNetworkUIViewSet(NautobotUIViewSet):
|
|
|
300
299
|
serializer_class = serializers.ProviderNetworkSerializer
|
|
301
300
|
table_class = tables.ProviderNetworkTable
|
|
302
301
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
.
|
|
313
|
-
.
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
context["circuits_table"] = circuits_table
|
|
324
|
-
return context
|
|
302
|
+
object_detail_content = ObjectDetailContent(
|
|
303
|
+
panels=(
|
|
304
|
+
ObjectFieldsPanel(
|
|
305
|
+
weight=100,
|
|
306
|
+
section=SectionChoices.LEFT_HALF,
|
|
307
|
+
fields="__all__",
|
|
308
|
+
),
|
|
309
|
+
ObjectsTablePanel(
|
|
310
|
+
weight=200,
|
|
311
|
+
section=SectionChoices.FULL_WIDTH,
|
|
312
|
+
table_class=tables.CircuitTable,
|
|
313
|
+
table_filter=["circuit_termination_a__provider_network", "circuit_termination_z__provider_network"],
|
|
314
|
+
prefetch_related_fields=["circuit_terminations__location"],
|
|
315
|
+
select_related_fields=["circuit_type", "tenant"],
|
|
316
|
+
exclude_columns=["provider_network", "circuit_termination_a", "circuit_termination_z"],
|
|
317
|
+
related_field_name="provider_network",
|
|
318
|
+
add_button_route=None,
|
|
319
|
+
),
|
|
320
|
+
)
|
|
321
|
+
)
|
|
325
322
|
|
|
326
323
|
|
|
327
324
|
class CircuitSwapTerminations(generic.ObjectEditView):
|
|
@@ -1,43 +1,5 @@
|
|
|
1
1
|
{% extends 'generic/object_retrieve.html' %}
|
|
2
|
-
{% load helpers %}
|
|
3
|
-
|
|
4
2
|
{% block extra_breadcrumbs %}
|
|
5
|
-
|
|
3
|
+
<li><a href="{% url 'cloud:cloudaccount_list' %}?provider={{ object.provider.pk }}">{{ object.provider }}</a></li>
|
|
6
4
|
{% endblock extra_breadcrumbs %}
|
|
7
|
-
|
|
8
|
-
{% block content_left_page %}
|
|
9
|
-
<div class="panel panel-default">
|
|
10
|
-
<div class="panel-heading">
|
|
11
|
-
<strong>Cloud Account</strong>
|
|
12
|
-
</div>
|
|
13
|
-
<table class="table table-hover panel-body attr-table">
|
|
14
|
-
<tr>
|
|
15
|
-
<td>Name</td>
|
|
16
|
-
<td>
|
|
17
|
-
{{ object.name }}
|
|
18
|
-
</td>
|
|
19
|
-
</tr>
|
|
20
|
-
<tr>
|
|
21
|
-
<td>Provider</td>
|
|
22
|
-
<td>{{ object.provider|hyperlinked_object }}</td>
|
|
23
|
-
</tr>
|
|
24
|
-
<tr>
|
|
25
|
-
<td>Account Number</td>
|
|
26
|
-
<td>
|
|
27
|
-
<span class="hover_copy"><span id="copy_accountnumber">{{ object.account_number }}</span><button type="button" class="btn btn-inline btn-default hover_copy_button" data-clipboard-target="#copy_accountnumber">
|
|
28
|
-
<span class="mdi mdi-content-copy"></span>
|
|
29
|
-
</button>
|
|
30
|
-
</span>
|
|
31
|
-
</td>
|
|
32
|
-
</tr>
|
|
33
|
-
<tr>
|
|
34
|
-
<td>Secrets Group</td>
|
|
35
|
-
<td>{{ object.secrets_group|hyperlinked_object }}</td>
|
|
36
|
-
</tr>
|
|
37
|
-
<tr>
|
|
38
|
-
<td>Description</td>
|
|
39
|
-
<td>{{ object.description|placeholder }}</td>
|
|
40
|
-
</tr>
|
|
41
|
-
</table>
|
|
42
|
-
</div>
|
|
43
|
-
{% endblock content_left_page %}
|
|
5
|
+
{% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
|
nautobot/cloud/views.py
CHANGED
|
@@ -31,6 +31,8 @@ from nautobot.cloud.forms import (
|
|
|
31
31
|
)
|
|
32
32
|
from nautobot.cloud.models import CloudAccount, CloudNetwork, CloudResourceType, CloudService
|
|
33
33
|
from nautobot.cloud.tables import CloudAccountTable, CloudNetworkTable, CloudResourceTypeTable, CloudServiceTable
|
|
34
|
+
from nautobot.core.ui import object_detail
|
|
35
|
+
from nautobot.core.ui.choices import SectionChoices
|
|
34
36
|
from nautobot.core.views.paginator import EnhancedPaginator, get_paginate_count
|
|
35
37
|
from nautobot.core.views.viewsets import NautobotUIViewSet
|
|
36
38
|
from nautobot.ipam.tables import PrefixTable
|
|
@@ -45,6 +47,16 @@ class CloudAccountUIViewSet(NautobotUIViewSet):
|
|
|
45
47
|
table_class = CloudAccountTable
|
|
46
48
|
form_class = CloudAccountForm
|
|
47
49
|
|
|
50
|
+
object_detail_content = object_detail.ObjectDetailContent(
|
|
51
|
+
panels=(
|
|
52
|
+
object_detail.ObjectFieldsPanel(
|
|
53
|
+
weight=100,
|
|
54
|
+
section=SectionChoices.LEFT_HALF,
|
|
55
|
+
fields="__all__",
|
|
56
|
+
),
|
|
57
|
+
)
|
|
58
|
+
)
|
|
59
|
+
|
|
48
60
|
|
|
49
61
|
class CloudNetworkUIViewSet(NautobotUIViewSet):
|
|
50
62
|
queryset = CloudNetwork.objects.all()
|
nautobot/core/api/urls.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from django.conf.urls import include
|
|
2
2
|
from django.urls import path
|
|
3
3
|
from drf_spectacular.views import (
|
|
4
|
-
SpectacularAPIView,
|
|
5
4
|
SpectacularJSONAPIView,
|
|
6
5
|
SpectacularYAMLAPIView,
|
|
7
6
|
)
|
|
@@ -12,6 +11,7 @@ from nautobot.core.api.views import (
|
|
|
12
11
|
GetFilterSetFieldDOMElementAPIView,
|
|
13
12
|
GetFilterSetFieldLookupExpressionChoicesAPIView,
|
|
14
13
|
GraphQLDRFAPIView,
|
|
14
|
+
NautobotSpectacularAPIView,
|
|
15
15
|
NautobotSpectacularRedocView,
|
|
16
16
|
NautobotSpectacularSwaggerView,
|
|
17
17
|
RenderJinjaView,
|
|
@@ -55,7 +55,7 @@ urlpatterns = [
|
|
|
55
55
|
path("docs/", NautobotSpectacularSwaggerView.as_view(url_name="schema"), name="api_docs"),
|
|
56
56
|
path("redoc/", NautobotSpectacularRedocView.as_view(url_name="schema"), name="api_redocs"),
|
|
57
57
|
path("settings-schema/", SettingsJSONSchemaView.as_view(), name="setting_schema_json"),
|
|
58
|
-
path("swagger/",
|
|
58
|
+
path("swagger/", NautobotSpectacularAPIView.as_view(), name="schema"),
|
|
59
59
|
path("swagger.json", SpectacularJSONAPIView.as_view(), name="schema_json"),
|
|
60
60
|
path("swagger.yaml", SpectacularYAMLAPIView.as_view(), name="schema_yaml"),
|
|
61
61
|
# GraphQL
|
nautobot/core/api/views.py
CHANGED
|
@@ -7,6 +7,7 @@ from django import __version__ as DJANGO_VERSION, forms
|
|
|
7
7
|
from django.apps import apps
|
|
8
8
|
from django.conf import settings
|
|
9
9
|
from django.contrib.contenttypes.models import ContentType
|
|
10
|
+
from django.core.cache import cache
|
|
10
11
|
from django.core.exceptions import FieldDoesNotExist, ObjectDoesNotExist, ValidationError
|
|
11
12
|
from django.db import transaction
|
|
12
13
|
from django.db.models import ProtectedError
|
|
@@ -14,10 +15,12 @@ from django.db.models.fields.related import ForeignKey, ManyToManyField, Related
|
|
|
14
15
|
from django.db.models.fields.reverse_related import ManyToManyRel, ManyToOneRel
|
|
15
16
|
from django.http.response import HttpResponseBadRequest
|
|
16
17
|
from django.shortcuts import get_object_or_404, redirect
|
|
18
|
+
from django.utils.decorators import method_decorator
|
|
19
|
+
from django.views.decorators.gzip import gzip_page
|
|
17
20
|
from drf_spectacular.plumbing import get_relative_url, set_query_parameters
|
|
18
21
|
from drf_spectacular.renderers import OpenApiJsonRenderer
|
|
19
22
|
from drf_spectacular.utils import extend_schema
|
|
20
|
-
from drf_spectacular.views import SpectacularRedocView, SpectacularSwaggerView
|
|
23
|
+
from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView
|
|
21
24
|
from graphene_django.settings import graphene_settings
|
|
22
25
|
from graphene_django.views import GraphQLView, HttpError, instantiate_middleware
|
|
23
26
|
from graphql import get_default_backend
|
|
@@ -608,6 +611,41 @@ class NautobotSpectacularRedocView(APIVersioningGetSchemaURLMixin, SpectacularRe
|
|
|
608
611
|
"""Extend SpectacularRedocView to support Nautobot's ?api_version=<version> query parameter."""
|
|
609
612
|
|
|
610
613
|
|
|
614
|
+
@method_decorator(gzip_page, name="dispatch")
|
|
615
|
+
class NautobotSpectacularAPIView(SpectacularAPIView):
|
|
616
|
+
def _get_schema_response(self, request):
|
|
617
|
+
# version specified as parameter to the view always takes precedence. after
|
|
618
|
+
# that we try to source version through the schema view's own versioning_class.
|
|
619
|
+
version = self.api_version or request.version or self._get_version_parameter(request)
|
|
620
|
+
cache_key = f"openapi_schema_cache_{version}_{settings.VERSION}" # Invalidate cache on Nautobot release
|
|
621
|
+
etag = f'W/"{hash(cache_key)}"'
|
|
622
|
+
|
|
623
|
+
# With combined browser cache and backend cache, we have three options:
|
|
624
|
+
# - cache expired on browser, but Etag is the same (no changes in nautobot) -> 70-100ms response
|
|
625
|
+
# - cache expired on browser, Etag is different, cache present on backend -> 400-600ms response
|
|
626
|
+
# - cache expired on browser, Etag is different, no cache on backend -> 3-4s response
|
|
627
|
+
|
|
628
|
+
if_none_match = request.META.get("HTTP_IF_NONE_MATCH", "")
|
|
629
|
+
if if_none_match == etag:
|
|
630
|
+
return Response(status=304)
|
|
631
|
+
|
|
632
|
+
schema = cache.get(cache_key)
|
|
633
|
+
if not schema:
|
|
634
|
+
generator = self.generator_class(urlconf=self.urlconf, api_version=version, patterns=self.patterns)
|
|
635
|
+
schema = generator.get_schema(request=request, public=self.serve_public)
|
|
636
|
+
cache.set(cache_key, schema, 60 * 60 * 24 * 7)
|
|
637
|
+
|
|
638
|
+
return Response(
|
|
639
|
+
data=schema,
|
|
640
|
+
headers={
|
|
641
|
+
"Content-Disposition": f'inline; filename="{self._get_filename(request, version)}"',
|
|
642
|
+
"Cache-Control": f"max-age={3 * 24 * 60 * 60}, public",
|
|
643
|
+
"ETag": etag,
|
|
644
|
+
"Vary": "Accept, Accept-Encoding",
|
|
645
|
+
},
|
|
646
|
+
)
|
|
647
|
+
|
|
648
|
+
|
|
611
649
|
#
|
|
612
650
|
# GraphQL
|
|
613
651
|
#
|
nautobot/core/forms/__init__.py
CHANGED
|
@@ -60,6 +60,7 @@ from nautobot.core.forms.utils import (
|
|
|
60
60
|
from nautobot.core.forms.widgets import (
|
|
61
61
|
APISelect,
|
|
62
62
|
APISelectMultiple,
|
|
63
|
+
AutoPopulateWidget,
|
|
63
64
|
BulkEditNullBooleanSelect,
|
|
64
65
|
ClearableFileInput,
|
|
65
66
|
ColorSelect,
|
|
@@ -86,6 +87,7 @@ __all__ = (
|
|
|
86
87
|
"APISelect",
|
|
87
88
|
"APISelectMultiple",
|
|
88
89
|
"AddressFieldMixin",
|
|
90
|
+
"AutoPopulateWidget",
|
|
89
91
|
"AutoPositionField",
|
|
90
92
|
"AutoPositionPatternField",
|
|
91
93
|
"BootstrapMixin",
|
nautobot/core/forms/fields.py
CHANGED
|
@@ -457,7 +457,7 @@ class AutoPositionField(django_forms.CharField):
|
|
|
457
457
|
source (str, tuple): Name of the field (or a list of field names) that will be used to suggest a position.
|
|
458
458
|
"""
|
|
459
459
|
kwargs.setdefault("label", "Position")
|
|
460
|
-
kwargs.setdefault("widget", forms.
|
|
460
|
+
kwargs.setdefault("widget", forms.AutoPopulateWidget)
|
|
461
461
|
super().__init__(*args, **kwargs)
|
|
462
462
|
if isinstance(source, (tuple, list)):
|
|
463
463
|
source = " ".join(source)
|
|
@@ -473,7 +473,7 @@ class AutoPositionPatternField(ExpandableNameField):
|
|
|
473
473
|
source (str, tuple): Name pattern of the field (or a list of field names) that will be used to suggest a position pattern.
|
|
474
474
|
"""
|
|
475
475
|
kwargs.setdefault("label", "Position")
|
|
476
|
-
kwargs.setdefault("widget", forms.
|
|
476
|
+
kwargs.setdefault("widget", forms.AutoPopulateWidget(attrs={"title": "Regenerate position"}))
|
|
477
477
|
super().__init__(*args, **kwargs)
|
|
478
478
|
if isinstance(source, (tuple, list)):
|
|
479
479
|
source = " ".join(source)
|
nautobot/core/forms/widgets.py
CHANGED
|
@@ -12,6 +12,7 @@ from nautobot.core.forms import utils
|
|
|
12
12
|
__all__ = (
|
|
13
13
|
"APISelect",
|
|
14
14
|
"APISelectMultiple",
|
|
15
|
+
"AutoPopulateWidget",
|
|
15
16
|
"BulkEditNullBooleanSelect",
|
|
16
17
|
"ClearableFileInput",
|
|
17
18
|
"ColorSelect",
|
|
@@ -41,6 +42,23 @@ class SlugWidget(forms.TextInput):
|
|
|
41
42
|
|
|
42
43
|
template_name = "widgets/sluginput.html"
|
|
43
44
|
|
|
45
|
+
def get_context(self, name, value, attrs):
|
|
46
|
+
custom_title = self.attrs.pop("title", None)
|
|
47
|
+
context = super().get_context(name, value, attrs)
|
|
48
|
+
context["widget"]["custom_title"] = custom_title
|
|
49
|
+
return context
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class AutoPopulateWidget(SlugWidget):
|
|
53
|
+
"""
|
|
54
|
+
Subclass SlugWidget and add support for auto-populate JavaScript logic from `form.js`.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
def get_context(self, name, value, attrs):
|
|
58
|
+
attrs["data-autopopulate"] = ""
|
|
59
|
+
context = super().get_context(name, value, attrs)
|
|
60
|
+
return context
|
|
61
|
+
|
|
44
62
|
|
|
45
63
|
class ColorSelect(forms.Select):
|
|
46
64
|
"""
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
<div class="input-group">
|
|
2
2
|
{% include "django/forms/widgets/input.html" %}
|
|
3
3
|
<span class="input-group-btn">
|
|
4
|
-
<button class="btn btn-default reslugify"
|
|
4
|
+
<button class="btn btn-default reslugify"
|
|
5
|
+
type="button"
|
|
6
|
+
title="{% if widget.custom_title %}{{ widget.custom_title }}{% else %}Regenerate slug{% endif %}"
|
|
7
|
+
data-regenerate="{{ widget.attrs.id }}"
|
|
8
|
+
>
|
|
5
9
|
<i class="mdi mdi-refresh"></i>
|
|
6
10
|
</button>
|
|
7
11
|
</span>
|
|
@@ -2,7 +2,7 @@ import datetime
|
|
|
2
2
|
import json
|
|
3
3
|
import logging
|
|
4
4
|
import re
|
|
5
|
-
from urllib.parse import parse_qs
|
|
5
|
+
from urllib.parse import parse_qs, quote_plus
|
|
6
6
|
|
|
7
7
|
from django import template
|
|
8
8
|
from django.conf import settings
|
|
@@ -711,6 +711,20 @@ def render_ancestor_hierarchy(value):
|
|
|
711
711
|
return result
|
|
712
712
|
|
|
713
713
|
|
|
714
|
+
@library.filter()
|
|
715
|
+
@register.filter()
|
|
716
|
+
def render_address(address):
|
|
717
|
+
if address:
|
|
718
|
+
map_link = format_html(
|
|
719
|
+
'<a href="https://maps.google.com/?q={}" target="_blank" class="btn btn-primary btn-xs">'
|
|
720
|
+
'<i class="mdi mdi-map-marker"></i> Map it</a>',
|
|
721
|
+
quote_plus(address),
|
|
722
|
+
)
|
|
723
|
+
address = format_html_join("", "{}<br>", ((line,) for line in address.split("\n")))
|
|
724
|
+
return format_html('<div class="pull-right noprint">{}</div>{}', map_link, address)
|
|
725
|
+
return HTML_NONE
|
|
726
|
+
|
|
727
|
+
|
|
714
728
|
#
|
|
715
729
|
# Tags
|
|
716
730
|
#
|
|
@@ -35,11 +35,15 @@ class ObjectsListMixin:
|
|
|
35
35
|
"""
|
|
36
36
|
self.browser.find_by_css("#object_list_form input.toggle").click()
|
|
37
37
|
|
|
38
|
-
def select_one_item(self):
|
|
38
|
+
def select_one_item(self, pk=None):
|
|
39
39
|
"""
|
|
40
40
|
Click first row checkbox on items table list to select one row.
|
|
41
41
|
"""
|
|
42
|
-
|
|
42
|
+
selector = '#object_list_form input[name="pk"]'
|
|
43
|
+
if pk:
|
|
44
|
+
selector = f'{selector}[value="{pk}"]'
|
|
45
|
+
|
|
46
|
+
self.browser.find_by_css(selector).click()
|
|
43
47
|
|
|
44
48
|
def set_per_page(self, per_page=1):
|
|
45
49
|
"""
|
|
@@ -8,7 +8,7 @@ import logging
|
|
|
8
8
|
from django.contrib.contenttypes.models import ContentType
|
|
9
9
|
from django.core.exceptions import FieldDoesNotExist, ObjectDoesNotExist
|
|
10
10
|
from django.db import models
|
|
11
|
-
from django.db.models import CharField, JSONField, URLField
|
|
11
|
+
from django.db.models import CharField, JSONField, Q, URLField
|
|
12
12
|
from django.db.models.fields.related import ManyToManyField
|
|
13
13
|
from django.template import Context
|
|
14
14
|
from django.template.defaultfilters import truncatechars
|
|
@@ -665,10 +665,14 @@ class ObjectsTablePanel(Panel):
|
|
|
665
665
|
Table (`BaseTable`) instance. Mutually exclusive with `table_class`, `table_filter`, `table_attribute`.
|
|
666
666
|
table_class (obj): The table class that will be instantiated and rendered e.g. CircuitTable, DeviceTable.
|
|
667
667
|
Mutually exclusive with `context_table_key`.
|
|
668
|
-
table_filter (str, optional): The
|
|
668
|
+
table_filter (str, list, optional): The filter(s) to apply to the queryset to initialize the table class.
|
|
669
669
|
For example, in a LocationType detail view, for an ObjectsTablePanel of related Locations, this would
|
|
670
670
|
be `location_type`, because `Location.objects.filter(location_type=obj)` gives the desired queryset.
|
|
671
671
|
Mutually exclusive with `table_attribute`.
|
|
672
|
+
For example, in ProviderNetwork detail view, for an ObjectsTablePanel of related Circuits, this would
|
|
673
|
+
be `["circuit_termination_a__provider_network", "circuit_termination_z__provider_network"]` because
|
|
674
|
+
`Circuit.objects.filter(Q(circuit_termination_a__provider_network=instance)
|
|
675
|
+
| Q(circuit_termination_z__provider_network=instance))` gives the desired queryset.
|
|
672
676
|
table_attribute (str, optional): The attribute of the detail view instance that contains the queryset to
|
|
673
677
|
initialize the table class. e.g. `dynamic_groups`.
|
|
674
678
|
Mutually exclusive with `table_filter`.
|
|
@@ -789,7 +793,16 @@ class ObjectsTablePanel(Panel):
|
|
|
789
793
|
if self.table_attribute:
|
|
790
794
|
body_content_table_queryset = getattr(instance, self.table_attribute)
|
|
791
795
|
else:
|
|
792
|
-
|
|
796
|
+
if isinstance(self.table_filter, str):
|
|
797
|
+
table_filters = [self.table_filter]
|
|
798
|
+
elif isinstance(self.table_filter, list):
|
|
799
|
+
table_filters = self.table_filter
|
|
800
|
+
else:
|
|
801
|
+
table_filters = []
|
|
802
|
+
query = Q()
|
|
803
|
+
for table_filter in table_filters:
|
|
804
|
+
query = query | Q(**{table_filter: instance})
|
|
805
|
+
body_content_table_queryset = body_content_table_model.objects.filter(query)
|
|
793
806
|
|
|
794
807
|
body_content_table_queryset = body_content_table_queryset.restrict(request.user, "view")
|
|
795
808
|
if self.select_related_fields:
|
nautobot/core/utils/lookup.py
CHANGED
|
@@ -291,9 +291,9 @@ def get_table_class_string_from_view_name(view_name):
|
|
|
291
291
|
|
|
292
292
|
view_func = resolve(reverse(view_name)).func
|
|
293
293
|
view_class = getattr(view_func, "cls", getattr(view_func, "view_class", None))
|
|
294
|
-
if hasattr(view_class, "table_class"):
|
|
294
|
+
if hasattr(view_class, "table_class") and view_class.table_class:
|
|
295
295
|
return view_class.table_class.__name__
|
|
296
|
-
if hasattr(view_class, "table"):
|
|
296
|
+
if hasattr(view_class, "table") and view_class.table:
|
|
297
297
|
return view_class.table.__name__
|
|
298
298
|
return None
|
|
299
299
|
|
nautobot/dcim/forms.py
CHANGED
|
@@ -768,6 +768,16 @@ class RackReservationFilterForm(NautobotFilterForm, TenancyFilterForm):
|
|
|
768
768
|
#
|
|
769
769
|
|
|
770
770
|
|
|
771
|
+
class ManufacturerBulkEditForm(NautobotBulkEditForm):
|
|
772
|
+
pk = forms.ModelMultipleChoiceField(queryset=Manufacturer.objects.all(), widget=forms.MultipleHiddenInput())
|
|
773
|
+
description = forms.CharField(max_length=CHARFIELD_MAX_LENGTH, required=False)
|
|
774
|
+
|
|
775
|
+
class Meta:
|
|
776
|
+
nullable_fields = [
|
|
777
|
+
"description",
|
|
778
|
+
]
|
|
779
|
+
|
|
780
|
+
|
|
771
781
|
class ManufacturerForm(NautobotModelForm):
|
|
772
782
|
class Meta:
|
|
773
783
|
model = Manufacturer
|
|
@@ -220,6 +220,15 @@ class Location(TreeModel, PrimaryModel):
|
|
|
220
220
|
def __str__(self):
|
|
221
221
|
return self.name
|
|
222
222
|
|
|
223
|
+
@property
|
|
224
|
+
def display(self):
|
|
225
|
+
"""
|
|
226
|
+
Honor LOCATION_NAME_AS_NATURAL_KEY for display value rendering, else fallback to TreeModel.display().
|
|
227
|
+
"""
|
|
228
|
+
if get_settings_or_config("LOCATION_NAME_AS_NATURAL_KEY"):
|
|
229
|
+
return self.name
|
|
230
|
+
return super().display
|
|
231
|
+
|
|
223
232
|
@classproperty # https://github.com/PyCQA/pylint-django/issues/240
|
|
224
233
|
def natural_key_field_lookups(cls): # pylint: disable=no-self-argument
|
|
225
234
|
"""
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
{% block bulk_buttons %}
|
|
4
4
|
{% if perms.dcim.change_device %}
|
|
5
5
|
<div class="btn-group dropup">
|
|
6
|
-
<button type="button" class="btn btn-sm btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
6
|
+
<button type="button" class="btn btn-sm btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" id="device-bulk-add-components-button">
|
|
7
7
|
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add Components <span class="caret"></span>
|
|
8
8
|
</button>
|
|
9
9
|
<ul class="dropdown-menu">
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
{% block extra_buttons %}
|
|
11
11
|
{% if perms.dcim.change_devicetype %}
|
|
12
12
|
<div class="btn-group">
|
|
13
|
-
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
13
|
+
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" id="device-type-add-components-button">
|
|
14
14
|
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add Components <span class="caret"></span>
|
|
15
15
|
</button>
|
|
16
16
|
<ul class="dropdown-menu">
|
|
@@ -1,64 +1,2 @@
|
|
|
1
1
|
{% extends 'generic/object_retrieve.html' %}
|
|
2
|
-
{%
|
|
3
|
-
|
|
4
|
-
{% block content_left_page %}
|
|
5
|
-
<div class="panel panel-default">
|
|
6
|
-
<div class="panel-heading">
|
|
7
|
-
<strong>Manufacturer</strong>
|
|
8
|
-
</div>
|
|
9
|
-
<table class="table table-hover panel-body attr-table">
|
|
10
|
-
<tr>
|
|
11
|
-
<td>Description</td>
|
|
12
|
-
<td>{{ object.description|placeholder }}</td>
|
|
13
|
-
</tr>
|
|
14
|
-
<tr>
|
|
15
|
-
<td>Devices</td>
|
|
16
|
-
<td>
|
|
17
|
-
<a href="{% url 'dcim:device_list' %}?manufacturer={{ object.name }}">{{ device_table.rows|length }}</a>
|
|
18
|
-
</td>
|
|
19
|
-
</tr>
|
|
20
|
-
{% if cloud_account_table.rows %}
|
|
21
|
-
<tr>
|
|
22
|
-
<td>Cloud Accounts</td>
|
|
23
|
-
<td>
|
|
24
|
-
<a href="{% url 'cloud:cloudaccount_list' %}?provider={{ object.name }}">{{ cloud_account_table.rows|length }}</a>
|
|
25
|
-
</td>
|
|
26
|
-
</tr>
|
|
27
|
-
{% endif %}
|
|
28
|
-
</table>
|
|
29
|
-
</div>
|
|
30
|
-
{% endblock content_left_page %}
|
|
31
|
-
|
|
32
|
-
{% block content_full_width_page %}
|
|
33
|
-
<div class="panel panel-default">
|
|
34
|
-
<div class="panel-heading">
|
|
35
|
-
<strong>Devices</strong>
|
|
36
|
-
</div>
|
|
37
|
-
{% include 'inc/table.html' with table=device_table %}
|
|
38
|
-
{% if perms.dcim.add_device %}
|
|
39
|
-
<div class="panel-footer text-right noprint">
|
|
40
|
-
<a href="{% url 'dcim:device_add' %}?manufacturer={{ object.pk }}" class="btn btn-xs btn-primary">
|
|
41
|
-
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add device
|
|
42
|
-
</a>
|
|
43
|
-
</div>
|
|
44
|
-
{% endif %}
|
|
45
|
-
</div>
|
|
46
|
-
{% include 'inc/paginator.html' with paginator=device_table.paginator page=device_table.page %}
|
|
47
|
-
{% if cloud_account_table.rows %}
|
|
48
|
-
<div class="panel panel-default">
|
|
49
|
-
<div class="panel-heading">
|
|
50
|
-
<strong>Cloud Accounts</strong>
|
|
51
|
-
</div>
|
|
52
|
-
{% include 'inc/table.html' with table=cloud_account_table %}
|
|
53
|
-
{% if perms.cloud.add_cloudaccount %}
|
|
54
|
-
<div class="panel-footer text-right noprint">
|
|
55
|
-
<a href="{% url 'cloud:cloudaccount_add' %}?provider={{ object.pk }}" class="btn btn-xs btn-primary">
|
|
56
|
-
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add Cloud Account
|
|
57
|
-
</a>
|
|
58
|
-
</div>
|
|
59
|
-
{% endif %}
|
|
60
|
-
</div>
|
|
61
|
-
{% include 'inc/paginator.html' with paginator=cloud_account_table.paginator page=cloud_account_table.page %}
|
|
62
|
-
{% endif %}
|
|
63
|
-
<div class="row"></div>
|
|
64
|
-
{% endblock content_full_width_page %}
|
|
2
|
+
{% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
{% block bulk_buttons %}
|
|
4
4
|
{% if perms.dcim.change_module %}
|
|
5
5
|
<div class="btn-group dropup">
|
|
6
|
-
<button type="button" class="btn btn-sm btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
6
|
+
<button type="button" class="btn btn-sm btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" id="module-bulk-add-components-button">
|
|
7
7
|
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add Components <span class="caret"></span>
|
|
8
8
|
</button>
|
|
9
9
|
<ul class="dropdown-menu">
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
{% block extra_buttons %}
|
|
10
10
|
{% if perms.dcim.change_moduletype %}
|
|
11
11
|
<div class="btn-group">
|
|
12
|
-
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
12
|
+
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" id="module-type-add-components-button">
|
|
13
13
|
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add Components <span class="caret"></span>
|
|
14
14
|
</button>
|
|
15
15
|
<ul class="dropdown-menu">
|