nautobot 2.4.15__py3-none-any.whl → 2.4.17__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/utils.py +2 -0
- nautobot/cloud/templates/cloud/cloudresourcetype_retrieve.html +3 -3
- nautobot/cloud/views.py +7 -0
- nautobot/core/apps/__init__.py +1 -0
- nautobot/core/celery/__init__.py +2 -1
- nautobot/core/templates/components/panel/panel.html +1 -1
- nautobot/core/templates/inc/paginator.html +3 -3
- nautobot/core/templates/inc/table.html +2 -2
- nautobot/core/templatetags/helpers.py +80 -6
- nautobot/core/testing/mixins.py +1 -1
- nautobot/core/testing/views.py +2 -4
- nautobot/core/ui/bulk_buttons.py +53 -53
- nautobot/core/ui/object_detail.py +9 -4
- nautobot/core/utils/data.py +13 -0
- nautobot/core/utils/deprecation.py +2 -0
- nautobot/dcim/migrations/0073_alter_powerport_power_factor_and_more.py +41 -0
- nautobot/dcim/models/device_component_templates.py +4 -2
- nautobot/dcim/models/device_components.py +3 -2
- nautobot/dcim/templates/dcim/rack_elevation_list.html +4 -4
- nautobot/dcim/views.py +9 -0
- nautobot/extras/models/customfields.py +45 -9
- nautobot/extras/tables.py +12 -0
- nautobot/extras/templates/extras/configcontext_retrieve.html +1 -1
- nautobot/extras/templates/extras/configcontext_update.html +49 -49
- nautobot/extras/templates/extras/configcontextschema_retrieve.html +47 -47
- nautobot/extras/templates/extras/configcontextschema_update.html +18 -18
- nautobot/extras/templates/extras/inc/job_table.html +1 -1
- nautobot/extras/templates/extras/inc/object_contact_header.html +2 -2
- nautobot/extras/templates/extras/marketplace.html +1 -1
- nautobot/extras/templates/extras/note_retrieve.html +53 -53
- nautobot/extras/templates/extras/secretsgroup_retrieve.html +2 -29
- nautobot/extras/templates/extras/tag_retrieve.html +1 -1
- nautobot/extras/templates/extras/tag_update.html +14 -14
- nautobot/extras/templates/extras/team_retrieve.html +1 -1
- nautobot/extras/tests/test_models.py +216 -0
- nautobot/extras/tests/test_plugins.py +12 -0
- nautobot/extras/tests/test_views.py +2 -2
- nautobot/extras/views.py +20 -4
- nautobot/ipam/apps.py +1 -0
- nautobot/ipam/jobs/__init__.py +10 -0
- nautobot/ipam/jobs/cleanup.py +296 -0
- nautobot/ipam/models.py +301 -178
- nautobot/ipam/templates/ipam/inc/ipadress_edit_header.html +3 -3
- nautobot/ipam/templates/ipam/inc/toggle_available.html +2 -2
- nautobot/ipam/templates/ipam/ipaddress_assign.html +1 -1
- nautobot/ipam/templates/ipam/prefix_list.html +1 -1
- nautobot/ipam/templates/ipam/vlan_retrieve.html +1 -77
- nautobot/ipam/tests/test_jobs.py +454 -0
- nautobot/ipam/tests/test_models.py +290 -122
- nautobot/ipam/tests/test_views.py +40 -164
- nautobot/ipam/urls.py +0 -11
- nautobot/ipam/utils/testing.py +9 -4
- nautobot/ipam/views.py +166 -235
- nautobot/project-static/docs/404.html +9 -6
- nautobot/project-static/docs/apps/index.html +9 -6
- nautobot/project-static/docs/apps/nautobot-apps.html +9 -6
- nautobot/project-static/docs/assets/javascripts/bundle.92b07e13.min.js +16 -0
- nautobot/project-static/docs/assets/javascripts/{bundle.50899def.min.js.map → bundle.92b07e13.min.js.map} +2 -2
- nautobot/project-static/docs/assets/javascripts/workers/{search.d50fe291.min.js → search.973d3a69.min.js} +4 -4
- nautobot/project-static/docs/assets/javascripts/workers/{search.d50fe291.min.js.map → search.973d3a69.min.js.map} +1 -1
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +9 -6
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +9 -6
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +9 -6
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +9 -6
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +10 -7
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +9 -6
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +9 -6
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +9 -6
- nautobot/project-static/docs/code-reference/nautobot/apps/events.html +9 -6
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +9 -6
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +9 -6
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +9 -6
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +9 -6
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +9 -6
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +9 -6
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +11 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +9 -6
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +9 -6
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +11 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +9 -6
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +28 -9
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +9 -6
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +69 -7
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +9 -6
- nautobot/project-static/docs/development/apps/api/configuration-view.html +13 -10
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +11 -8
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +13 -10
- nautobot/project-static/docs/development/apps/api/models/global-search.html +10 -7
- nautobot/project-static/docs/development/apps/api/models/graphql.html +18 -15
- nautobot/project-static/docs/development/apps/api/models/index.html +14 -11
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +11 -8
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +15 -12
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +9 -6
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +15 -12
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +9 -6
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +11 -8
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +16 -13
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +12 -10305
- nautobot/project-static/docs/development/apps/api/platform-features/prepopulating-data.html +10722 -0
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +15 -12
- nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +14 -11
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +9 -6
- nautobot/project-static/docs/development/apps/api/prometheus.html +15 -12
- nautobot/project-static/docs/development/apps/api/setup.html +9 -6
- nautobot/project-static/docs/development/apps/api/testing.html +9 -6
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +12 -9
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +9 -6
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +9 -6
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +9 -6
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +20 -17
- nautobot/project-static/docs/development/apps/api/views/base-template.html +9 -6
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +15 -12
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +14 -11
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +9 -6
- nautobot/project-static/docs/development/apps/api/views/index.html +9 -6
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +10 -7
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +24 -21
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +12 -9
- nautobot/project-static/docs/development/apps/api/views/notes.html +10 -7
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +19 -16
- nautobot/project-static/docs/development/apps/api/views/urls.html +11 -8
- nautobot/project-static/docs/development/apps/index.html +9 -6
- nautobot/project-static/docs/development/apps/migration/code-updates.html +19 -16
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +9 -6
- nautobot/project-static/docs/development/apps/migration/from-v1.html +9 -6
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +22 -19
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +9 -6
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +9 -6
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +9 -6
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +9 -6
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/breadcrumbs-titles.html +14 -11
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +27 -24
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +20 -17
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +20 -17
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +9 -6
- nautobot/project-static/docs/development/core/application-registry.html +23 -20
- nautobot/project-static/docs/development/core/best-practices.html +23 -20
- nautobot/project-static/docs/development/core/bootstrap-ui.html +9 -6
- nautobot/project-static/docs/development/core/caching.html +9 -6
- nautobot/project-static/docs/development/core/controllers.html +9 -6
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +10 -7
- nautobot/project-static/docs/development/core/generic-views.html +9 -6
- nautobot/project-static/docs/development/core/getting-started.html +9 -6
- nautobot/project-static/docs/development/core/homepage.html +12 -9
- nautobot/project-static/docs/development/core/index.html +9 -6
- nautobot/project-static/docs/development/core/minikube-dev-environment-for-k8s-jobs.html +9 -6
- nautobot/project-static/docs/development/core/model-checklist.html +9 -6
- nautobot/project-static/docs/development/core/model-features.html +11 -8
- nautobot/project-static/docs/development/core/natural-keys.html +21 -18
- nautobot/project-static/docs/development/core/navigation-menu.html +10 -7
- nautobot/project-static/docs/development/core/release-checklist.html +9 -6
- nautobot/project-static/docs/development/core/role-internals.html +9 -6
- nautobot/project-static/docs/development/core/settings.html +9 -6
- nautobot/project-static/docs/development/core/style-guide.html +32 -29
- nautobot/project-static/docs/development/core/templates.html +9 -6
- nautobot/project-static/docs/development/core/testing.html +10 -7
- nautobot/project-static/docs/development/core/ui-component-framework.html +36 -33
- nautobot/project-static/docs/development/core/user-preferences.html +9 -6
- nautobot/project-static/docs/development/index.html +9 -6
- nautobot/project-static/docs/development/jobs/getting-started.html +13 -10
- nautobot/project-static/docs/development/jobs/index.html +9 -6
- nautobot/project-static/docs/development/jobs/installation.html +23 -20
- nautobot/project-static/docs/development/jobs/job-extensions.html +25 -22
- nautobot/project-static/docs/development/jobs/job-logging.html +12 -9
- nautobot/project-static/docs/development/jobs/job-patterns.html +45 -42
- nautobot/project-static/docs/development/jobs/job-structure.html +53 -50
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +23 -20
- nautobot/project-static/docs/development/jobs/testing.html +14 -11
- nautobot/project-static/docs/index.html +9 -6
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/overview/application_stack.html +9 -6
- nautobot/project-static/docs/overview/design_philosophy.html +9 -6
- nautobot/project-static/docs/release-notes/index.html +9 -6
- nautobot/project-static/docs/release-notes/version-1.0.html +9 -6
- nautobot/project-static/docs/release-notes/version-1.1.html +9 -6
- nautobot/project-static/docs/release-notes/version-1.2.html +10 -7
- nautobot/project-static/docs/release-notes/version-1.3.html +9 -6
- nautobot/project-static/docs/release-notes/version-1.4.html +9 -6
- nautobot/project-static/docs/release-notes/version-1.5.html +13 -10
- nautobot/project-static/docs/release-notes/version-1.6.html +9 -6
- nautobot/project-static/docs/release-notes/version-2.0.html +9 -6
- nautobot/project-static/docs/release-notes/version-2.1.html +9 -6
- nautobot/project-static/docs/release-notes/version-2.2.html +9 -6
- nautobot/project-static/docs/release-notes/version-2.3.html +9 -6
- nautobot/project-static/docs/release-notes/version-2.4.html +342 -6
- nautobot/project-static/docs/requirements.txt +2 -2
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +301 -301
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +15 -12
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +9 -6
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +16 -13
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +9 -6
- nautobot/project-static/docs/user-guide/administration/configuration/redis.html +9 -6
- nautobot/project-static/docs/user-guide/administration/configuration/settings.html +11 -8
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +9 -6
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +9 -6
- nautobot/project-static/docs/user-guide/administration/guides/docker.html +9 -6
- nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +9 -6
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +9 -6
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +9 -6
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +9 -6
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +9 -6
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +16 -13
- nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +9 -6
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +9 -6
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +9 -6
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +9 -6
- nautobot/project-static/docs/user-guide/administration/installation/index.html +9 -6
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +9 -6
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +9 -6
- nautobot/project-static/docs/user-guide/administration/installation/services.html +12 -9
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +13 -10
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +10 -7
- nautobot/project-static/docs/user-guide/administration/security/index.html +9 -6
- nautobot/project-static/docs/user-guide/administration/security/notices.html +9 -6
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +9 -6
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +10 -7
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +9 -6
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +9 -6
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +9 -6
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +9 -6
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +9 -6
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +9 -6
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +9 -6
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +15 -12
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +13 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulefamily.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +11 -8
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +11 -8
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +41 -41
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +197 -54
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +9 -6
- nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +9 -6
- nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +9 -6
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +9 -6
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +9 -6
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +9 -6
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +9 -6
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +9 -6
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +9 -6
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +9 -6
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +9 -6
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +9 -6
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +9 -6
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +9 -6
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +13 -10
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +9 -6
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +9 -6
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +9 -6
- nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +9 -6
- nautobot/project-static/docs/user-guide/index.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +10 -7
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/events.html +11 -8
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/managing-jobs.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +12 -9
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +11 -8
- nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +9 -6
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +9 -6
- nautobot/project-static/fonts/UFL.txt +96 -96
- nautobot/project-static/js/forms.js +35 -2
- nautobot/virtualization/filters.py +7 -0
- {nautobot-2.4.15.dist-info → nautobot-2.4.17.dist-info}/METADATA +6 -6
- {nautobot-2.4.15.dist-info → nautobot-2.4.17.dist-info}/RECORD +373 -368
- nautobot/project-static/docs/assets/javascripts/bundle.50899def.min.js +0 -16
- {nautobot-2.4.15.dist-info → nautobot-2.4.17.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.4.15.dist-info → nautobot-2.4.17.dist-info}/NOTICE +0 -0
- {nautobot-2.4.15.dist-info → nautobot-2.4.17.dist-info}/WHEEL +0 -0
- {nautobot-2.4.15.dist-info → nautobot-2.4.17.dist-info}/entry_points.txt +0 -0
nautobot/apps/utils.py
CHANGED
|
@@ -13,6 +13,7 @@ from nautobot.core.utils.data import (
|
|
|
13
13
|
render_jinja2,
|
|
14
14
|
shallow_compare_dict,
|
|
15
15
|
to_meters,
|
|
16
|
+
validate_jinja2,
|
|
16
17
|
)
|
|
17
18
|
from nautobot.core.utils.deprecation import class_deprecated, class_deprecated_in_favor_of
|
|
18
19
|
from nautobot.core.utils.filtering import (
|
|
@@ -139,5 +140,6 @@ __all__ = (
|
|
|
139
140
|
"swap_status_initials",
|
|
140
141
|
"task_queues_as_choices",
|
|
141
142
|
"to_meters",
|
|
143
|
+
"validate_jinja2",
|
|
142
144
|
"wrap_model_clean_methods",
|
|
143
145
|
)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
{% extends 'generic/object_retrieve.html' %}
|
|
2
|
-
{% block extra_breadcrumbs %}
|
|
3
|
-
<li><a href="{% url 'cloud:cloudresourcetype_list' %}?provider={{ object.provider.pk }}">{{ object.provider }}</a></li>
|
|
1
|
+
{% extends 'generic/object_retrieve.html' %}
|
|
2
|
+
{% block extra_breadcrumbs %}
|
|
3
|
+
<li><a href="{% url 'cloud:cloudresourcetype_list' %}?provider={{ object.provider.pk }}">{{ object.provider }}</a></li>
|
|
4
4
|
{% endblock extra_breadcrumbs %}
|
nautobot/cloud/views.py
CHANGED
|
@@ -94,6 +94,7 @@ class CloudNetworkUIViewSet(NautobotUIViewSet):
|
|
|
94
94
|
table_class=CloudNetworkTable,
|
|
95
95
|
table_filter="parent",
|
|
96
96
|
tab_id="children",
|
|
97
|
+
include_paginator=True,
|
|
97
98
|
),
|
|
98
99
|
),
|
|
99
100
|
),
|
|
@@ -111,6 +112,7 @@ class CloudNetworkUIViewSet(NautobotUIViewSet):
|
|
|
111
112
|
table_filter="cloud_networks",
|
|
112
113
|
exclude_columns=("location_count", "vlan"),
|
|
113
114
|
tab_id="prefixes",
|
|
115
|
+
include_paginator=True,
|
|
114
116
|
),
|
|
115
117
|
),
|
|
116
118
|
),
|
|
@@ -129,6 +131,7 @@ class CloudNetworkUIViewSet(NautobotUIViewSet):
|
|
|
129
131
|
related_field_name="cloud_network",
|
|
130
132
|
exclude_columns=("circuit_termination_a", "circuit_termination_z"),
|
|
131
133
|
tab_id="circuits",
|
|
134
|
+
include_paginator=True,
|
|
132
135
|
),
|
|
133
136
|
),
|
|
134
137
|
),
|
|
@@ -146,6 +149,7 @@ class CloudNetworkUIViewSet(NautobotUIViewSet):
|
|
|
146
149
|
table_filter="cloud_networks",
|
|
147
150
|
exclude_columns=("cloud_network_count"),
|
|
148
151
|
tab_id="cloud_services",
|
|
152
|
+
include_paginator=True,
|
|
149
153
|
),
|
|
150
154
|
),
|
|
151
155
|
),
|
|
@@ -222,6 +226,7 @@ class CloudResourceTypeUIViewSet(NautobotUIViewSet):
|
|
|
222
226
|
table_class=CloudNetworkTable,
|
|
223
227
|
table_filter="cloud_resource_type",
|
|
224
228
|
tab_id="networks",
|
|
229
|
+
include_paginator=True,
|
|
225
230
|
),
|
|
226
231
|
),
|
|
227
232
|
),
|
|
@@ -238,6 +243,7 @@ class CloudResourceTypeUIViewSet(NautobotUIViewSet):
|
|
|
238
243
|
table_class=CloudServiceTable,
|
|
239
244
|
table_filter="cloud_resource_type",
|
|
240
245
|
tab_id="services",
|
|
246
|
+
include_paginator=True,
|
|
241
247
|
),
|
|
242
248
|
),
|
|
243
249
|
),
|
|
@@ -302,6 +308,7 @@ class CloudServiceUIViewSet(NautobotUIViewSet):
|
|
|
302
308
|
table_filter="cloud_services",
|
|
303
309
|
tab_id="cloud_networks",
|
|
304
310
|
add_button_route=None,
|
|
311
|
+
include_paginator=True,
|
|
305
312
|
),
|
|
306
313
|
),
|
|
307
314
|
),
|
nautobot/core/apps/__init__.py
CHANGED
|
@@ -337,6 +337,7 @@ class CoreConfig(NautobotConfig):
|
|
|
337
337
|
from graphene_django.converter import convert_django_field
|
|
338
338
|
|
|
339
339
|
from nautobot.core.graphql import BigInteger
|
|
340
|
+
import nautobot.core.jobs # noqa: F401 # unused-import -- but this import registers the system jobs
|
|
340
341
|
|
|
341
342
|
@convert_django_field.register(JSONField)
|
|
342
343
|
def convert_json(field, registry=None): # pylint: disable=redefined-outer-name
|
nautobot/core/celery/__init__.py
CHANGED
|
@@ -54,7 +54,8 @@ def import_jobs(sender=None, **kwargs):
|
|
|
54
54
|
|
|
55
55
|
Note that app-provided jobs are automatically imported at startup time via NautobotAppConfig.ready()
|
|
56
56
|
"""
|
|
57
|
-
import nautobot.core.jobs
|
|
57
|
+
import nautobot.core.jobs
|
|
58
|
+
import nautobot.ipam.jobs # noqa: F401
|
|
58
59
|
|
|
59
60
|
_import_jobs_from_jobs_root()
|
|
60
61
|
_import_dynamic_jobs_from_apps()
|
|
@@ -5,17 +5,17 @@
|
|
|
5
5
|
<nav>
|
|
6
6
|
<ul class="pagination pull-right">
|
|
7
7
|
{% if page.has_previous %}
|
|
8
|
-
<li><a href="{%
|
|
8
|
+
<li><a href="{% legacy_querystring request page=page.previous_page_number %}"><i class="mdi mdi-chevron-double-left"></i></a></li>
|
|
9
9
|
{% endif %}
|
|
10
10
|
{% for p in page.smart_pages %}
|
|
11
11
|
{% if p %}
|
|
12
|
-
<li{% if page.number == p %} class="active"{% endif %}><a href="{%
|
|
12
|
+
<li{% if page.number == p %} class="active"{% endif %}><a href="{% legacy_querystring request page=p %}">{{ p }}</a></li>
|
|
13
13
|
{% else %}
|
|
14
14
|
<li class="disabled"><span>…</span></li>
|
|
15
15
|
{% endif %}
|
|
16
16
|
{% endfor %}
|
|
17
17
|
{% if page.has_next %}
|
|
18
|
-
<li><a href="{%
|
|
18
|
+
<li><a href="{% legacy_querystring request page=page.next_page_number %}"><i class="mdi mdi-chevron-double-right"></i></a></li>
|
|
19
19
|
{% endif %}
|
|
20
20
|
</ul>
|
|
21
21
|
</nav>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from collections.abc import Iterable
|
|
1
2
|
import datetime
|
|
2
3
|
import json
|
|
3
4
|
import logging
|
|
@@ -23,7 +24,7 @@ import yaml
|
|
|
23
24
|
from nautobot.apps.config import get_app_settings_or_config
|
|
24
25
|
from nautobot.core import forms
|
|
25
26
|
from nautobot.core.constants import PAGINATE_COUNT_DEFAULT
|
|
26
|
-
from nautobot.core.utils import color, config, data, logging as nautobot_logging, lookup
|
|
27
|
+
from nautobot.core.utils import color, config, data, deprecation, logging as nautobot_logging, lookup
|
|
27
28
|
from nautobot.core.utils.requests import add_nautobot_version_query_param_to_url
|
|
28
29
|
|
|
29
30
|
HTML_TRUE = mark_safe('<span class="text-success"><i class="mdi mdi-check-bold" title="Yes"></i></span>')
|
|
@@ -762,6 +763,23 @@ def render_address(address):
|
|
|
762
763
|
return HTML_NONE
|
|
763
764
|
|
|
764
765
|
|
|
766
|
+
@register.filter()
|
|
767
|
+
def render_m2m(queryset, full_listing_link, verbose_name_plural, max_visible=5):
|
|
768
|
+
total_count = queryset.count()
|
|
769
|
+
display_count = min(total_count, max_visible)
|
|
770
|
+
if not display_count:
|
|
771
|
+
return HTML_NONE
|
|
772
|
+
|
|
773
|
+
items = [hyperlinked_object(record) for record in queryset[:display_count]]
|
|
774
|
+
|
|
775
|
+
remaining = total_count - display_count
|
|
776
|
+
if remaining > 0:
|
|
777
|
+
link = format_html('<a href="{}">... View {} more {}</a>', full_listing_link, remaining, verbose_name_plural)
|
|
778
|
+
items.append(link)
|
|
779
|
+
|
|
780
|
+
return format_html_join("", "<div>{}</div>", ((item,) for item in items)) if items else HTML_NONE
|
|
781
|
+
|
|
782
|
+
|
|
765
783
|
@library.filter()
|
|
766
784
|
@register.filter()
|
|
767
785
|
def render_button_class(value):
|
|
@@ -823,11 +841,7 @@ def get_attr(obj, attr, default=None):
|
|
|
823
841
|
return getattr(obj, attr, default)
|
|
824
842
|
|
|
825
843
|
|
|
826
|
-
|
|
827
|
-
def querystring(request, **kwargs):
|
|
828
|
-
"""
|
|
829
|
-
Append or update the page number in a querystring.
|
|
830
|
-
"""
|
|
844
|
+
def _base_querystring(request, **kwargs):
|
|
831
845
|
querydict = request.GET.copy()
|
|
832
846
|
for k, v in kwargs.items():
|
|
833
847
|
if v is not None:
|
|
@@ -841,6 +855,66 @@ def querystring(request, **kwargs):
|
|
|
841
855
|
return ""
|
|
842
856
|
|
|
843
857
|
|
|
858
|
+
# TODO: Remove this tag in Nautobot 3.0.
|
|
859
|
+
|
|
860
|
+
|
|
861
|
+
@register.simple_tag()
|
|
862
|
+
@deprecation.method_deprecated(
|
|
863
|
+
"Leverage `legacy_querystring` instead of `querystring` if this templatetag is required. In Nautobot 3.0, "
|
|
864
|
+
"`querystring` will be removed in preparation for Django 5.2 in which there is a built-in querystring tag "
|
|
865
|
+
"that operates differently. You may find that `django_querystring` is more appropriate for your use case "
|
|
866
|
+
"and is a replica of Django 5.2's `querystring` templatetag."
|
|
867
|
+
)
|
|
868
|
+
def querystring(request, **kwargs):
|
|
869
|
+
return _base_querystring(request, **kwargs)
|
|
870
|
+
|
|
871
|
+
|
|
872
|
+
@register.simple_tag()
|
|
873
|
+
def legacy_querystring(request, **kwargs):
|
|
874
|
+
return _base_querystring(request, **kwargs)
|
|
875
|
+
|
|
876
|
+
|
|
877
|
+
# Note: This is vendored from Django 5.2
|
|
878
|
+
@register.simple_tag(name="django_querystring", takes_context=True)
|
|
879
|
+
def django_querystring(context, query_dict=None, **kwargs):
|
|
880
|
+
"""
|
|
881
|
+
Add, remove, and change parameters of a ``QueryDict`` and return the result
|
|
882
|
+
as a query string. If the ``query_dict`` argument is not provided, default
|
|
883
|
+
to ``request.GET``.
|
|
884
|
+
|
|
885
|
+
For example::
|
|
886
|
+
|
|
887
|
+
{% django_querystring foo=3 %}
|
|
888
|
+
|
|
889
|
+
To remove a key::
|
|
890
|
+
|
|
891
|
+
{% django_querystring foo=None %}
|
|
892
|
+
|
|
893
|
+
To use with pagination::
|
|
894
|
+
|
|
895
|
+
{% django_querystring page=page_obj.next_page_number %}
|
|
896
|
+
|
|
897
|
+
A custom ``QueryDict`` can also be used::
|
|
898
|
+
|
|
899
|
+
{% django_querystring my_query_dict foo=3 %}
|
|
900
|
+
"""
|
|
901
|
+
if query_dict is None:
|
|
902
|
+
query_dict = context.request.GET
|
|
903
|
+
params = query_dict.copy()
|
|
904
|
+
for key, value in kwargs.items():
|
|
905
|
+
if value is None:
|
|
906
|
+
if key in params:
|
|
907
|
+
del params[key]
|
|
908
|
+
elif isinstance(value, Iterable) and not isinstance(value, str):
|
|
909
|
+
params.setlist(key, value)
|
|
910
|
+
else:
|
|
911
|
+
params[key] = value
|
|
912
|
+
if not params and not query_dict:
|
|
913
|
+
return ""
|
|
914
|
+
query_string = params.urlencode()
|
|
915
|
+
return f"?{query_string}"
|
|
916
|
+
|
|
917
|
+
|
|
844
918
|
@register.simple_tag()
|
|
845
919
|
def table_config_button(table, table_name=None, extra_classes="", disabled=False):
|
|
846
920
|
if table_name is None:
|
nautobot/core/testing/mixins.py
CHANGED
|
@@ -156,7 +156,7 @@ class NautobotTestCaseMixin:
|
|
|
156
156
|
"""
|
|
157
157
|
for name in names:
|
|
158
158
|
ct, action = permissions.resolve_permission_ct(name)
|
|
159
|
-
obj_perm = users_models.ObjectPermission(name=name, actions=[action], **kwargs)
|
|
159
|
+
obj_perm, _ = users_models.ObjectPermission.objects.get_or_create(name=name, actions=[action], **kwargs)
|
|
160
160
|
obj_perm.save()
|
|
161
161
|
obj_perm.users.add(self.user)
|
|
162
162
|
obj_perm.object_types.add(ct)
|
nautobot/core/testing/views.py
CHANGED
|
@@ -281,8 +281,7 @@ class ViewTestCases:
|
|
|
281
281
|
if getattr(obj, "is_contact_associable_model", False):
|
|
282
282
|
self.assertBodyContains(
|
|
283
283
|
response,
|
|
284
|
-
f'
|
|
285
|
-
html=True,
|
|
284
|
+
f'href="{obj.get_absolute_url()}#contacts" onclick="switch_tab(this.href)"',
|
|
286
285
|
)
|
|
287
286
|
else:
|
|
288
287
|
self.assertNotContains(response, f"{obj.get_absolute_url()}#contacts")
|
|
@@ -304,8 +303,7 @@ class ViewTestCases:
|
|
|
304
303
|
if getattr(obj, "is_contact_associable_model", False):
|
|
305
304
|
self.assertBodyContains(
|
|
306
305
|
response,
|
|
307
|
-
f'
|
|
308
|
-
html=True,
|
|
306
|
+
f'href="{obj.get_absolute_url()}#contacts" onclick="switch_tab(this.href)"',
|
|
309
307
|
)
|
|
310
308
|
else:
|
|
311
309
|
self.assertNotContains(response, f"{obj.get_absolute_url()}#contacts")
|
nautobot/core/ui/bulk_buttons.py
CHANGED
|
@@ -1,53 +1,53 @@
|
|
|
1
|
-
from nautobot.core.choices import ButtonActionColorChoices
|
|
2
|
-
from nautobot.core.ui import object_detail
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class BaseBulkButton(object_detail.FormButton):
|
|
6
|
-
"""Base class for bulk action buttons."""
|
|
7
|
-
|
|
8
|
-
action = None
|
|
9
|
-
color = None
|
|
10
|
-
icon = None
|
|
11
|
-
label = None
|
|
12
|
-
weight = None
|
|
13
|
-
|
|
14
|
-
def __init__(self, *, form_id: str, model, **kwargs):
|
|
15
|
-
model_name = model.__name__.lower()
|
|
16
|
-
app_label = model._meta.app_label
|
|
17
|
-
link_name = f"{app_label}:{model_name}_bulk_{self.action}"
|
|
18
|
-
|
|
19
|
-
super().__init__(
|
|
20
|
-
link_name=link_name,
|
|
21
|
-
link_includes_pk=False,
|
|
22
|
-
label=self.label,
|
|
23
|
-
color=self.color,
|
|
24
|
-
icon=self.icon,
|
|
25
|
-
size="xs",
|
|
26
|
-
form_id=form_id,
|
|
27
|
-
weight=self.weight,
|
|
28
|
-
**kwargs,
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class BulkRenameButton(BaseBulkButton):
|
|
33
|
-
action = "rename"
|
|
34
|
-
color = ButtonActionColorChoices.RENAME
|
|
35
|
-
icon = "mdi-pencil"
|
|
36
|
-
label = "Rename"
|
|
37
|
-
weight = 200
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
class BulkEditButton(BaseBulkButton):
|
|
41
|
-
action = "edit"
|
|
42
|
-
color = ButtonActionColorChoices.EDIT
|
|
43
|
-
icon = "mdi-pencil"
|
|
44
|
-
label = "Edit"
|
|
45
|
-
weight = 300
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
class BulkDeleteButton(BaseBulkButton):
|
|
49
|
-
action = "delete"
|
|
50
|
-
color = ButtonActionColorChoices.DELETE
|
|
51
|
-
icon = "mdi-trash-can-outline"
|
|
52
|
-
label = "Delete"
|
|
53
|
-
weight = 400
|
|
1
|
+
from nautobot.core.choices import ButtonActionColorChoices
|
|
2
|
+
from nautobot.core.ui import object_detail
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class BaseBulkButton(object_detail.FormButton):
|
|
6
|
+
"""Base class for bulk action buttons."""
|
|
7
|
+
|
|
8
|
+
action = None
|
|
9
|
+
color = None
|
|
10
|
+
icon = None
|
|
11
|
+
label = None
|
|
12
|
+
weight = None
|
|
13
|
+
|
|
14
|
+
def __init__(self, *, form_id: str, model, **kwargs):
|
|
15
|
+
model_name = model.__name__.lower()
|
|
16
|
+
app_label = model._meta.app_label
|
|
17
|
+
link_name = f"{app_label}:{model_name}_bulk_{self.action}"
|
|
18
|
+
|
|
19
|
+
super().__init__(
|
|
20
|
+
link_name=link_name,
|
|
21
|
+
link_includes_pk=False,
|
|
22
|
+
label=self.label,
|
|
23
|
+
color=self.color,
|
|
24
|
+
icon=self.icon,
|
|
25
|
+
size="xs",
|
|
26
|
+
form_id=form_id,
|
|
27
|
+
weight=self.weight,
|
|
28
|
+
**kwargs,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class BulkRenameButton(BaseBulkButton):
|
|
33
|
+
action = "rename"
|
|
34
|
+
color = ButtonActionColorChoices.RENAME
|
|
35
|
+
icon = "mdi-pencil"
|
|
36
|
+
label = "Rename"
|
|
37
|
+
weight = 200
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class BulkEditButton(BaseBulkButton):
|
|
41
|
+
action = "edit"
|
|
42
|
+
color = ButtonActionColorChoices.EDIT
|
|
43
|
+
icon = "mdi-pencil"
|
|
44
|
+
label = "Edit"
|
|
45
|
+
weight = 300
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class BulkDeleteButton(BaseBulkButton):
|
|
49
|
+
action = "delete"
|
|
50
|
+
color = ButtonActionColorChoices.DELETE
|
|
51
|
+
icon = "mdi-trash-can-outline"
|
|
52
|
+
label = "Delete"
|
|
53
|
+
weight = 400
|
|
@@ -459,7 +459,7 @@ class DistinctViewTab(Tab):
|
|
|
459
459
|
return format_html(
|
|
460
460
|
"{} {}",
|
|
461
461
|
self.label,
|
|
462
|
-
render_to_string("utilities/templatetags/badge.html", badge(related_obj_count)),
|
|
462
|
+
render_to_string("utilities/templatetags/badge.html", badge(related_obj_count, True)),
|
|
463
463
|
)
|
|
464
464
|
except AttributeError:
|
|
465
465
|
logger.warning(
|
|
@@ -704,6 +704,7 @@ class ObjectsTablePanel(Panel):
|
|
|
704
704
|
footer_content_template_path="components/panel/footer_content_table.html",
|
|
705
705
|
footer_buttons=None,
|
|
706
706
|
form_id=None,
|
|
707
|
+
include_paginator=False,
|
|
707
708
|
**kwargs,
|
|
708
709
|
):
|
|
709
710
|
"""Instantiate an ObjectsTable panel.
|
|
@@ -752,6 +753,7 @@ class ObjectsTablePanel(Panel):
|
|
|
752
753
|
footer_buttons (list, optional): A list of Button or FormButton components to render in the panel footer.
|
|
753
754
|
These buttons typically perform actions like bulk delete, edit, or custom form submission.
|
|
754
755
|
form_id (str, optional): A unique ID for this table's form; used to set the `data-form-id` attribute on each `FormButton`.
|
|
756
|
+
include_paginator (bool, optional): If True, renders a paginator in the panel footer.
|
|
755
757
|
"""
|
|
756
758
|
if context_table_key and any(
|
|
757
759
|
[
|
|
@@ -796,6 +798,7 @@ class ObjectsTablePanel(Panel):
|
|
|
796
798
|
self.tab_id = tab_id
|
|
797
799
|
self.footer_buttons = footer_buttons
|
|
798
800
|
self.form_id = form_id
|
|
801
|
+
self.include_paginator = include_paginator
|
|
799
802
|
|
|
800
803
|
super().__init__(
|
|
801
804
|
body_wrapper_template_path=body_wrapper_template_path,
|
|
@@ -953,6 +956,7 @@ class ObjectsTablePanel(Panel):
|
|
|
953
956
|
"footer_buttons": self.footer_buttons,
|
|
954
957
|
"form_id": self.form_id,
|
|
955
958
|
"more_queryset_count": more_queryset_count,
|
|
959
|
+
"include_paginator": self.include_paginator,
|
|
956
960
|
"show_table_config_button": self.show_table_config_button,
|
|
957
961
|
}
|
|
958
962
|
|
|
@@ -1912,7 +1916,8 @@ class _ObjectDetailContactsTab(Tab):
|
|
|
1912
1916
|
"{} {}",
|
|
1913
1917
|
self.label,
|
|
1914
1918
|
render_to_string(
|
|
1915
|
-
"utilities/templatetags/badge.html",
|
|
1919
|
+
"utilities/templatetags/badge.html",
|
|
1920
|
+
badge(get_obj_from_context(context).associated_contacts.count(), True),
|
|
1916
1921
|
),
|
|
1917
1922
|
)
|
|
1918
1923
|
|
|
@@ -1956,7 +1961,7 @@ class _ObjectDetailGroupsTab(Tab):
|
|
|
1956
1961
|
"{} {}",
|
|
1957
1962
|
self.label,
|
|
1958
1963
|
render_to_string(
|
|
1959
|
-
"utilities/templatetags/badge.html", badge(get_obj_from_context(context).dynamic_groups.count())
|
|
1964
|
+
"utilities/templatetags/badge.html", badge(get_obj_from_context(context).dynamic_groups.count(), True)
|
|
1960
1965
|
),
|
|
1961
1966
|
)
|
|
1962
1967
|
|
|
@@ -2003,6 +2008,6 @@ class _ObjectDetailMetadataTab(Tab):
|
|
|
2003
2008
|
self.label,
|
|
2004
2009
|
render_to_string(
|
|
2005
2010
|
"utilities/templatetags/badge.html",
|
|
2006
|
-
badge(get_obj_from_context(context).associated_object_metadata.count()),
|
|
2011
|
+
badge(get_obj_from_context(context).associated_object_metadata.count(), True),
|
|
2007
2012
|
),
|
|
2008
2013
|
)
|
nautobot/core/utils/data.py
CHANGED
|
@@ -92,6 +92,19 @@ def merge_dicts_without_collision(d1, d2):
|
|
|
92
92
|
return {**d1, **d2}
|
|
93
93
|
|
|
94
94
|
|
|
95
|
+
def validate_jinja2(template_code):
|
|
96
|
+
"""
|
|
97
|
+
Parse a Jinja2 template to validate its syntax. Returns True if the template is valid.
|
|
98
|
+
|
|
99
|
+
Raises:
|
|
100
|
+
jinja2.TemplateSyntaxError: If the template is syntactically invalid.
|
|
101
|
+
"""
|
|
102
|
+
rendering_engine = engines["jinja"]
|
|
103
|
+
rendering_engine.env.parse(template_code)
|
|
104
|
+
|
|
105
|
+
return True
|
|
106
|
+
|
|
107
|
+
|
|
95
108
|
def render_jinja2(template_code, context):
|
|
96
109
|
"""
|
|
97
110
|
Render a Jinja2 template with the provided context. Return the rendered content.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Utilities for handling deprecation of code and features."""
|
|
2
2
|
|
|
3
|
+
from functools import wraps
|
|
3
4
|
import logging
|
|
4
5
|
import traceback
|
|
5
6
|
import warnings
|
|
@@ -51,6 +52,7 @@ def method_deprecated(message):
|
|
|
51
52
|
"""Decorator to mark a method as deprecated with a custom message about what to call instead."""
|
|
52
53
|
|
|
53
54
|
def decorate(method):
|
|
55
|
+
@wraps(method)
|
|
54
56
|
def decorated_method(*args, **kwargs):
|
|
55
57
|
warnings.warn(
|
|
56
58
|
f"Method `{method.__name__}` is deprecated, and will be removed in a future Nautobot release. "
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Generated by Django 4.2.23 on 2025-08-22 21:03
|
|
2
|
+
|
|
3
|
+
from decimal import Decimal
|
|
4
|
+
|
|
5
|
+
import django.core.validators
|
|
6
|
+
from django.db import migrations, models
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Migration(migrations.Migration):
|
|
10
|
+
dependencies = [
|
|
11
|
+
("dcim", "0072_alter_powerfeed_options_and_more"),
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
operations = [
|
|
15
|
+
migrations.AlterField(
|
|
16
|
+
model_name="powerport",
|
|
17
|
+
name="power_factor",
|
|
18
|
+
field=models.DecimalField(
|
|
19
|
+
decimal_places=2,
|
|
20
|
+
default=Decimal("0.95"),
|
|
21
|
+
max_digits=4,
|
|
22
|
+
validators=[
|
|
23
|
+
django.core.validators.MinValueValidator(Decimal("0.01")),
|
|
24
|
+
django.core.validators.MaxValueValidator(Decimal("1.00")),
|
|
25
|
+
],
|
|
26
|
+
),
|
|
27
|
+
),
|
|
28
|
+
migrations.AlterField(
|
|
29
|
+
model_name="powerporttemplate",
|
|
30
|
+
name="power_factor",
|
|
31
|
+
field=models.DecimalField(
|
|
32
|
+
decimal_places=2,
|
|
33
|
+
default=Decimal("0.95"),
|
|
34
|
+
max_digits=4,
|
|
35
|
+
validators=[
|
|
36
|
+
django.core.validators.MinValueValidator(Decimal("0.01")),
|
|
37
|
+
django.core.validators.MaxValueValidator(Decimal("1.00")),
|
|
38
|
+
],
|
|
39
|
+
),
|
|
40
|
+
),
|
|
41
|
+
]
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from decimal import Decimal
|
|
2
|
+
|
|
1
3
|
from django.contrib.contenttypes.models import ContentType
|
|
2
4
|
from django.core.exceptions import ObjectDoesNotExist, ValidationError
|
|
3
5
|
from django.core.validators import MaxValueValidator, MinValueValidator
|
|
@@ -252,8 +254,8 @@ class PowerPortTemplate(ModularComponentTemplateModel):
|
|
|
252
254
|
power_factor = models.DecimalField(
|
|
253
255
|
max_digits=4,
|
|
254
256
|
decimal_places=2,
|
|
255
|
-
default="0.95",
|
|
256
|
-
validators=[MinValueValidator(0.01), MaxValueValidator(1.00)],
|
|
257
|
+
default=Decimal("0.95"),
|
|
258
|
+
validators=[MinValueValidator(Decimal("0.01")), MaxValueValidator(Decimal("1.00"))],
|
|
257
259
|
help_text="Power factor (0.01-1.00) for converting between watts (W) and volt-amps (VA). Defaults to 0.95.",
|
|
258
260
|
)
|
|
259
261
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from decimal import Decimal
|
|
1
2
|
import re
|
|
2
3
|
|
|
3
4
|
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
|
|
@@ -402,8 +403,8 @@ class PowerPort(ModularComponentModel, CableTermination, PathEndpoint):
|
|
|
402
403
|
power_factor = models.DecimalField(
|
|
403
404
|
max_digits=4,
|
|
404
405
|
decimal_places=2,
|
|
405
|
-
default="0.95",
|
|
406
|
-
validators=[MinValueValidator(0.01), MaxValueValidator(1.00)],
|
|
406
|
+
default=Decimal("0.95"),
|
|
407
|
+
validators=[MinValueValidator(Decimal("0.01")), MaxValueValidator(Decimal("1.00"))],
|
|
407
408
|
help_text="Power factor (0.01-1.00) for converting between watts (W) and volt-amps (VA). Defaults to 0.95.",
|
|
408
409
|
)
|
|
409
410
|
|
|
@@ -10,12 +10,12 @@
|
|
|
10
10
|
<span class="mdi mdi-checkbox-marked-circle-outline" aria-hidden="true"></span> Show Images
|
|
11
11
|
</button>
|
|
12
12
|
<div class="btn-group" role="group">
|
|
13
|
-
<a href="{% url 'dcim:rack_elevation_list' %}{%
|
|
14
|
-
<a href="{% url 'dcim:rack_elevation_list' %}{%
|
|
13
|
+
<a href="{% url 'dcim:rack_elevation_list' %}{% legacy_querystring request face='front' %}" class="btn btn-default{% if rack_face == 'front' %} active{% endif %}">Front</a>
|
|
14
|
+
<a href="{% url 'dcim:rack_elevation_list' %}{% legacy_querystring request face='rear' %}" class="btn btn-default{% if rack_face == 'rear' %} active{% endif %}">Rear</a>
|
|
15
15
|
</div>
|
|
16
16
|
<div class="btn-group" role="group">
|
|
17
|
-
<a href="{% url 'dcim:rack_elevation_list' %}{%
|
|
18
|
-
<a href="{% url 'dcim:rack_elevation_list' %}{%
|
|
17
|
+
<a href="{% url 'dcim:rack_elevation_list' %}{% legacy_querystring request reverse=None %}" class="btn btn-default{% if not reverse %} active{% endif %}">Normal</a>
|
|
18
|
+
<a href="{% url 'dcim:rack_elevation_list' %}{% legacy_querystring request reverse='true' %}" class="btn btn-default{% if reverse %} active{% endif %}">Reversed</a>
|
|
19
19
|
</div>
|
|
20
20
|
{% endblock %}
|
|
21
21
|
|
nautobot/dcim/views.py
CHANGED
|
@@ -899,6 +899,7 @@ def make_bulk_tab(weight, tab_name, label, url_name, related_attr, table_class,
|
|
|
899
899
|
enable_bulk_actions=True,
|
|
900
900
|
form_id=form_id,
|
|
901
901
|
footer_buttons=bulk_footer_buttons(form_id=form_id, model=model),
|
|
902
|
+
include_paginator=True,
|
|
902
903
|
),
|
|
903
904
|
),
|
|
904
905
|
)
|
|
@@ -1965,6 +1966,7 @@ class DeviceView(generic.ObjectView):
|
|
|
1965
1966
|
exclude_columns=["content_type"],
|
|
1966
1967
|
add_button_route=None,
|
|
1967
1968
|
related_field_name="member_id",
|
|
1969
|
+
include_paginator=True,
|
|
1968
1970
|
),
|
|
1969
1971
|
),
|
|
1970
1972
|
)
|
|
@@ -4794,6 +4796,7 @@ class SoftwareImageFileUIViewSet(NautobotUIViewSet):
|
|
|
4794
4796
|
table_filter="software_image_files",
|
|
4795
4797
|
tab_id="device_types",
|
|
4796
4798
|
add_button_route=None,
|
|
4799
|
+
include_paginator=True,
|
|
4797
4800
|
),
|
|
4798
4801
|
),
|
|
4799
4802
|
),
|
|
@@ -4812,6 +4815,7 @@ class SoftwareImageFileUIViewSet(NautobotUIViewSet):
|
|
|
4812
4815
|
tab_id="devices",
|
|
4813
4816
|
table_title="Devices overridden to use this file",
|
|
4814
4817
|
add_button_route=None,
|
|
4818
|
+
include_paginator=True,
|
|
4815
4819
|
),
|
|
4816
4820
|
),
|
|
4817
4821
|
),
|
|
@@ -4830,6 +4834,7 @@ class SoftwareImageFileUIViewSet(NautobotUIViewSet):
|
|
|
4830
4834
|
tab_id="inventory_items",
|
|
4831
4835
|
table_title="Inventory items overridden to use this file",
|
|
4832
4836
|
add_button_route=None,
|
|
4837
|
+
include_paginator=True,
|
|
4833
4838
|
),
|
|
4834
4839
|
),
|
|
4835
4840
|
),
|
|
@@ -4848,6 +4853,7 @@ class SoftwareImageFileUIViewSet(NautobotUIViewSet):
|
|
|
4848
4853
|
tab_id="virtual_machines",
|
|
4849
4854
|
table_title="Virtual machines overridden to use this file",
|
|
4850
4855
|
add_button_route=None,
|
|
4856
|
+
include_paginator=True,
|
|
4851
4857
|
),
|
|
4852
4858
|
),
|
|
4853
4859
|
),
|
|
@@ -4993,6 +4999,7 @@ class ControllerUIViewSet(NautobotUIViewSet):
|
|
|
4993
4999
|
add_button_route=None,
|
|
4994
5000
|
select_related_fields=["wireless_network"],
|
|
4995
5001
|
exclude_columns=["controller"],
|
|
5002
|
+
include_paginator=True,
|
|
4996
5003
|
),
|
|
4997
5004
|
),
|
|
4998
5005
|
),
|
|
@@ -5056,6 +5063,7 @@ class ControllerManagedDeviceGroupUIViewSet(NautobotUIViewSet):
|
|
|
5056
5063
|
tab_id="wireless_networks",
|
|
5057
5064
|
add_button_route=None,
|
|
5058
5065
|
exclude_columns=["controller_managed_device_group", "controller"],
|
|
5066
|
+
include_paginator=True,
|
|
5059
5067
|
),
|
|
5060
5068
|
),
|
|
5061
5069
|
),
|
|
@@ -5074,6 +5082,7 @@ class ControllerManagedDeviceGroupUIViewSet(NautobotUIViewSet):
|
|
|
5074
5082
|
table_filter="controller_managed_device_groups",
|
|
5075
5083
|
tab_id="radio_profiles",
|
|
5076
5084
|
add_button_route=None,
|
|
5085
|
+
include_paginator=True,
|
|
5077
5086
|
),
|
|
5078
5087
|
),
|
|
5079
5088
|
),
|