nautobot 2.4.0__py3-none-any.whl → 2.4.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of nautobot might be problematic. Click here for more details.
- nautobot/apps/__init__.py +1 -1
- nautobot/apps/api.py +8 -8
- nautobot/apps/change_logging.py +2 -2
- nautobot/apps/choices.py +4 -4
- nautobot/apps/events.py +3 -3
- nautobot/apps/factory.py +2 -2
- nautobot/apps/filters.py +1 -1
- nautobot/apps/forms.py +20 -20
- nautobot/apps/graphql.py +2 -2
- nautobot/apps/jobs.py +8 -8
- nautobot/apps/models.py +19 -19
- nautobot/apps/tables.py +1 -1
- nautobot/apps/testing.py +10 -10
- nautobot/apps/ui.py +2 -2
- nautobot/apps/utils.py +7 -7
- nautobot/apps/views.py +7 -7
- nautobot/circuits/api/serializers.py +0 -1
- nautobot/circuits/api/views.py +8 -4
- nautobot/circuits/tables.py +1 -2
- nautobot/circuits/templates/circuits/circuit_create.html +7 -1
- nautobot/circuits/views.py +3 -3
- nautobot/cloud/api/views.py +10 -6
- nautobot/cloud/models.py +1 -1
- nautobot/cloud/views.py +16 -0
- nautobot/core/api/fields.py +5 -5
- nautobot/core/api/filter_backends.py +9 -3
- nautobot/core/api/schema.py +2 -13
- nautobot/core/api/serializers.py +34 -40
- nautobot/core/api/views.py +4 -56
- nautobot/core/celery/log.py +4 -4
- nautobot/core/celery/schedulers.py +1 -1
- nautobot/core/choices.py +2 -2
- nautobot/core/events/__init__.py +3 -3
- nautobot/core/filters.py +16 -21
- nautobot/core/fixtures/user-data.json +59 -0
- nautobot/core/forms/__init__.py +19 -19
- nautobot/core/forms/fields.py +11 -14
- nautobot/core/forms/forms.py +2 -33
- nautobot/core/graphql/types.py +1 -1
- nautobot/core/jobs/__init__.py +7 -28
- nautobot/core/jobs/cleanup.py +12 -48
- nautobot/core/jobs/groups.py +1 -1
- nautobot/core/management/commands/validate_models.py +1 -1
- nautobot/core/models/__init__.py +1 -1
- nautobot/core/models/query_functions.py +2 -2
- nautobot/core/models/tree_queries.py +3 -6
- nautobot/core/settings.py +2 -29
- nautobot/core/settings.yaml +0 -21
- nautobot/core/tables.py +60 -74
- nautobot/core/templates/inc/media.html +0 -3
- nautobot/core/templates/inc/nav_menu.html +0 -1
- nautobot/core/templates/nautobot_config.py.j2 +0 -13
- nautobot/core/templates/search.html +0 -7
- nautobot/core/templates/utilities/render_jinja2.html +1 -1
- nautobot/core/templates/utilities/templatetags/tag.html +1 -1
- nautobot/core/templates/utilities/theme_preview.html +0 -7
- nautobot/core/templatetags/helpers.py +2 -11
- nautobot/core/testing/__init__.py +8 -8
- nautobot/core/testing/api.py +15 -170
- nautobot/core/testing/filters.py +2 -25
- nautobot/core/testing/forms.py +0 -2
- nautobot/core/testing/mixins.py +2 -7
- nautobot/core/testing/views.py +29 -44
- nautobot/core/tests/integration/test_app_home.py +1 -0
- nautobot/core/tests/integration/test_app_navbar.py +1 -0
- nautobot/core/tests/integration/test_filters.py +2 -0
- nautobot/core/tests/integration/test_home.py +1 -0
- nautobot/core/tests/integration/test_navbar.py +1 -0
- nautobot/core/tests/integration/test_view_authentication.py +0 -1
- nautobot/core/tests/runner.py +1 -1
- nautobot/core/tests/test_api.py +1 -98
- nautobot/core/tests/test_csv.py +3 -25
- nautobot/core/tests/test_forms.py +0 -1
- nautobot/core/tests/test_jobs.py +1 -303
- nautobot/core/tests/test_settings_schema.py +0 -7
- nautobot/core/tests/test_tables.py +0 -100
- nautobot/core/tests/test_utils.py +1 -63
- nautobot/core/tests/test_views.py +3 -30
- nautobot/core/ui/nav.py +0 -1
- nautobot/core/ui/object_detail.py +1 -15
- nautobot/core/urls.py +0 -11
- nautobot/core/utils/lookup.py +8 -11
- nautobot/core/utils/requests.py +9 -24
- nautobot/core/views/__init__.py +0 -42
- nautobot/core/views/generic.py +176 -78
- nautobot/core/views/mixins.py +34 -94
- nautobot/core/views/renderers.py +6 -6
- nautobot/dcim/api/serializers.py +62 -54
- nautobot/dcim/api/views.py +113 -47
- nautobot/dcim/filters/__init__.py +2 -31
- nautobot/dcim/forms.py +17 -36
- nautobot/dcim/graphql/types.py +2 -2
- nautobot/dcim/models/__init__.py +1 -1
- nautobot/dcim/models/device_component_templates.py +2 -2
- nautobot/dcim/models/device_components.py +20 -22
- nautobot/dcim/models/devices.py +1 -10
- nautobot/dcim/models/locations.py +3 -3
- nautobot/dcim/models/power.py +5 -6
- nautobot/dcim/models/racks.py +4 -4
- nautobot/dcim/tables/__init__.py +3 -3
- nautobot/dcim/tables/devices.py +5 -7
- nautobot/dcim/tables/devicetypes.py +2 -2
- nautobot/dcim/tables/racks.py +1 -1
- nautobot/dcim/templates/dcim/controller_create.html +7 -1
- nautobot/dcim/templates/dcim/controller_retrieve.html +9 -1
- nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +0 -2
- nautobot/dcim/templates/dcim/controllermanageddevicegroup_retrieve.html +0 -5
- nautobot/dcim/templates/dcim/device.html +9 -1
- nautobot/dcim/templates/dcim/device_edit.html +37 -36
- nautobot/dcim/templates/dcim/location.html +9 -1
- nautobot/dcim/templates/dcim/location_edit.html +7 -1
- nautobot/dcim/templates/dcim/rack.html +9 -1
- nautobot/dcim/templates/dcim/rack_edit.html +7 -1
- nautobot/dcim/templates/dcim/rackreservation.html +9 -1
- nautobot/dcim/templates/dcim/virtualdevicecontext_retrieve.html +9 -1
- nautobot/dcim/templates/dcim/virtualdevicecontext_update.html +7 -1
- nautobot/dcim/tests/test_api.py +3 -16
- nautobot/dcim/tests/test_filters.py +0 -33
- nautobot/dcim/tests/test_forms.py +2 -51
- nautobot/dcim/tests/test_graphql.py +0 -52
- nautobot/dcim/tests/test_models.py +5 -34
- nautobot/dcim/tests/test_views.py +83 -21
- nautobot/dcim/views.py +13 -1
- nautobot/extras/api/customfields.py +2 -2
- nautobot/extras/api/serializers.py +85 -90
- nautobot/extras/api/views.py +27 -22
- nautobot/extras/constants.py +0 -2
- nautobot/extras/filters/__init__.py +6 -8
- nautobot/extras/forms/base.py +2 -2
- nautobot/extras/forms/forms.py +31 -139
- nautobot/extras/forms/mixins.py +5 -13
- nautobot/extras/group_sync.py +3 -3
- nautobot/extras/health_checks.py +2 -1
- nautobot/extras/jobs.py +12 -70
- nautobot/extras/managers.py +1 -3
- nautobot/extras/migrations/0018_joblog_data_migration.py +9 -7
- nautobot/extras/models/__init__.py +1 -1
- nautobot/extras/models/contacts.py +1 -1
- nautobot/extras/models/customfields.py +11 -12
- nautobot/extras/models/groups.py +9 -11
- nautobot/extras/models/jobs.py +4 -23
- nautobot/extras/models/models.py +2 -2
- nautobot/extras/plugins/__init__.py +2 -13
- nautobot/extras/plugins/marketplace_manifest.yml +79 -84
- nautobot/extras/plugins/tables.py +14 -16
- nautobot/extras/plugins/views.py +69 -65
- nautobot/extras/registry.py +1 -1
- nautobot/extras/secrets/__init__.py +2 -2
- nautobot/extras/tables.py +5 -7
- nautobot/extras/templates/extras/dynamicgroup.html +9 -1
- nautobot/extras/templates/extras/job_detail.html +0 -16
- nautobot/extras/templates/extras/job_edit.html +0 -1
- nautobot/extras/templates/extras/jobqueue_retrieve.html +9 -1
- nautobot/extras/templates/extras/marketplace.html +11 -29
- nautobot/extras/templates/extras/plugin_detail.html +15 -32
- nautobot/extras/templates/extras/plugins_tiles.html +10 -21
- nautobot/extras/test_jobs/api_test_job.py +1 -1
- nautobot/extras/test_jobs/atomic_transaction.py +2 -2
- nautobot/extras/test_jobs/dry_run.py +1 -1
- nautobot/extras/test_jobs/fail.py +5 -5
- nautobot/extras/test_jobs/file_output.py +1 -1
- nautobot/extras/test_jobs/file_upload_fail.py +1 -1
- nautobot/extras/test_jobs/file_upload_pass.py +1 -1
- nautobot/extras/test_jobs/ipaddress_vars.py +1 -3
- nautobot/extras/test_jobs/jobs_module/jobs_submodule/jobs.py +1 -1
- nautobot/extras/test_jobs/location_with_custom_field.py +1 -1
- nautobot/extras/test_jobs/log_redaction.py +1 -1
- nautobot/extras/test_jobs/log_skip_db_logging.py +1 -1
- nautobot/extras/test_jobs/modify_db.py +1 -1
- nautobot/extras/test_jobs/object_var_optional.py +1 -1
- nautobot/extras/test_jobs/object_var_required.py +1 -1
- nautobot/extras/test_jobs/object_vars.py +1 -1
- nautobot/extras/test_jobs/pass.py +3 -3
- nautobot/extras/test_jobs/profiling.py +1 -1
- nautobot/extras/test_jobs/relative_import.py +3 -3
- nautobot/extras/test_jobs/soft_time_limit_greater_than_time_limit.py +1 -1
- nautobot/extras/test_jobs/task_queues.py +1 -1
- nautobot/extras/tests/integration/test_plugin_banner.py +2 -0
- nautobot/extras/tests/test_api.py +13 -13
- nautobot/extras/tests/test_customfields.py +1 -1
- nautobot/extras/tests/test_datasources.py +1 -2
- nautobot/extras/tests/test_dynamicgroups.py +1 -1
- nautobot/extras/tests/test_filters.py +6 -6
- nautobot/extras/tests/test_forms.py +1 -20
- nautobot/extras/tests/test_jobs.py +19 -160
- nautobot/extras/tests/test_models.py +10 -10
- nautobot/extras/tests/test_plugins.py +9 -62
- nautobot/extras/tests/test_relationships.py +9 -120
- nautobot/extras/tests/test_views.py +191 -52
- nautobot/extras/utils.py +2 -3
- nautobot/extras/views.py +98 -30
- nautobot/ipam/api/fields.py +3 -3
- nautobot/ipam/api/serializers.py +33 -41
- nautobot/ipam/api/views.py +117 -68
- nautobot/ipam/factory.py +1 -1
- nautobot/ipam/filters.py +2 -3
- nautobot/ipam/lookups.py +62 -101
- nautobot/ipam/models.py +16 -66
- nautobot/ipam/querysets.py +2 -2
- nautobot/ipam/tables.py +7 -23
- nautobot/ipam/templates/ipam/ipaddress.html +9 -1
- nautobot/ipam/templates/ipam/ipaddress_bulk_add.html +7 -1
- nautobot/ipam/templates/ipam/ipaddress_edit.html +7 -1
- nautobot/ipam/templates/ipam/prefix.html +9 -1
- nautobot/ipam/templates/ipam/prefix_edit.html +7 -1
- nautobot/ipam/templates/ipam/vlan.html +9 -1
- nautobot/ipam/templates/ipam/vlan_edit.html +7 -1
- nautobot/ipam/templates/ipam/vrf_edit.html +7 -1
- nautobot/ipam/tests/test_api.py +3 -416
- nautobot/ipam/tests/test_forms.py +47 -49
- nautobot/ipam/tests/test_migrations.py +30 -30
- nautobot/ipam/tests/test_models.py +34 -95
- nautobot/ipam/tests/test_querysets.py +1 -63
- nautobot/ipam/tests/test_views.py +0 -3
- nautobot/ipam/utils/__init__.py +6 -36
- nautobot/ipam/views.py +87 -61
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css.map +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css.map +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css +2 -40
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css.map +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css.map +1 -1
- nautobot/project-static/docs/404.html +4 -46
- nautobot/project-static/docs/apps/index.html +4 -46
- nautobot/project-static/docs/apps/nautobot-apps.html +6 -47
- nautobot/project-static/docs/assets/_mkdocstrings.css +1 -25
- nautobot/project-static/docs/assets/javascripts/{bundle.88dd0f4e.min.js → bundle.83f73b43.min.js} +2 -2
- nautobot/project-static/docs/assets/javascripts/{bundle.88dd0f4e.min.js.map → bundle.83f73b43.min.js.map} +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +10 -62
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +7 -59
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +122 -374
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +18 -90
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +21 -95
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +6 -53
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +5 -52
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +17 -79
- nautobot/project-static/docs/code-reference/nautobot/apps/events.html +28 -102
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +21 -108
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +38 -131
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +65 -239
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +165 -581
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +36 -109
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +167 -453
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +211 -493
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +8 -60
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +15 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +55 -407
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +205 -585
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +412 -858
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +7 -59
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +186 -448
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +147 -365
- nautobot/project-static/docs/development/apps/api/configuration-view.html +4 -46
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +4 -46
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +4 -46
- nautobot/project-static/docs/development/apps/api/models/global-search.html +4 -46
- nautobot/project-static/docs/development/apps/api/models/graphql.html +4 -46
- nautobot/project-static/docs/development/apps/api/models/index.html +4 -46
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +4 -46
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +4 -46
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +4 -46
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +4 -46
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +4 -46
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +4 -46
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +4 -46
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +4 -46
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +4 -46
- nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +7 -68
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +4 -46
- nautobot/project-static/docs/development/apps/api/prometheus.html +4 -46
- nautobot/project-static/docs/development/apps/api/setup.html +4 -46
- nautobot/project-static/docs/development/apps/api/testing.html +4 -46
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +4 -46
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +4 -46
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +4 -46
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +4 -46
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +4 -46
- nautobot/project-static/docs/development/apps/api/views/base-template.html +4 -46
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +4 -46
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +4 -46
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +4 -46
- nautobot/project-static/docs/development/apps/api/views/index.html +4 -46
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +4 -46
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +4 -46
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +4 -46
- nautobot/project-static/docs/development/apps/api/views/notes.html +4 -46
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +6 -52
- nautobot/project-static/docs/development/apps/api/views/urls.html +4 -46
- nautobot/project-static/docs/development/apps/index.html +4 -46
- nautobot/project-static/docs/development/apps/migration/code-updates.html +4 -46
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +4 -46
- nautobot/project-static/docs/development/apps/migration/from-v1.html +4 -46
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +4 -46
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +4 -46
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +4 -46
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +4 -46
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +8 -50
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +4 -46
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +14 -211
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +4 -46
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +4 -46
- nautobot/project-static/docs/development/core/application-registry.html +4 -46
- nautobot/project-static/docs/development/core/best-practices.html +4 -46
- nautobot/project-static/docs/development/core/bootstrap-ui.html +4 -46
- nautobot/project-static/docs/development/core/caching.html +4 -46
- nautobot/project-static/docs/development/core/controllers.html +4 -46
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +74 -73
- nautobot/project-static/docs/development/core/generic-views.html +4 -46
- nautobot/project-static/docs/development/core/getting-started.html +224 -249
- nautobot/project-static/docs/development/core/homepage.html +7 -49
- nautobot/project-static/docs/development/core/index.html +4 -46
- nautobot/project-static/docs/development/core/{minikube-dev-environment-for-k8s-jobs.html → local-k8s.html} +168 -469
- nautobot/project-static/docs/development/core/model-checklist.html +12 -56
- nautobot/project-static/docs/development/core/model-features.html +4 -46
- nautobot/project-static/docs/development/core/natural-keys.html +4 -46
- nautobot/project-static/docs/development/core/navigation-menu.html +4 -46
- nautobot/project-static/docs/development/core/release-checklist.html +7 -49
- nautobot/project-static/docs/development/core/role-internals.html +4 -46
- nautobot/project-static/docs/development/core/settings.html +4 -46
- nautobot/project-static/docs/development/core/style-guide.html +7 -49
- nautobot/project-static/docs/development/core/templates.html +4 -46
- nautobot/project-static/docs/development/core/testing.html +4 -46
- nautobot/project-static/docs/development/core/ui-component-framework.html +273 -369
- nautobot/project-static/docs/development/core/user-preferences.html +4 -46
- nautobot/project-static/docs/development/index.html +4 -46
- nautobot/project-static/docs/development/jobs/index.html +122 -216
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +4 -46
- nautobot/project-static/docs/index.html +23 -54
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/overview/application_stack.html +7 -47
- nautobot/project-static/docs/overview/design_philosophy.html +4 -46
- nautobot/project-static/docs/release-notes/index.html +12 -52
- nautobot/project-static/docs/release-notes/version-1.0.html +193 -234
- nautobot/project-static/docs/release-notes/version-1.1.html +190 -231
- nautobot/project-static/docs/release-notes/version-1.2.html +265 -306
- nautobot/project-static/docs/release-notes/version-1.3.html +291 -332
- nautobot/project-static/docs/release-notes/version-1.4.html +377 -417
- nautobot/project-static/docs/release-notes/version-1.5.html +566 -605
- nautobot/project-static/docs/release-notes/version-1.6.html +447 -904
- nautobot/project-static/docs/release-notes/version-2.0.html +489 -528
- nautobot/project-static/docs/release-notes/version-2.1.html +324 -363
- nautobot/project-static/docs/release-notes/version-2.2.html +317 -356
- nautobot/project-static/docs/release-notes/version-2.3.html +352 -997
- nautobot/project-static/docs/release-notes/version-2.4.html +101 -417
- nautobot/project-static/docs/requirements.txt +2 -2
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +287 -295
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +4 -46
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +4 -46
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +6 -48
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +4 -46
- nautobot/project-static/docs/user-guide/administration/configuration/redis.html +4 -46
- nautobot/project-static/docs/user-guide/administration/configuration/settings.html +8 -110
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +4 -46
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +4 -46
- nautobot/project-static/docs/user-guide/administration/guides/docker.html +4 -46
- nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +4 -46
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +4 -46
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +4 -46
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +4 -46
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +4 -46
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +6 -48
- nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +4 -46
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +4 -46
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +4 -46
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +8 -66
- nautobot/project-static/docs/user-guide/administration/installation/index.html +4 -46
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +5 -47
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +4 -46
- nautobot/project-static/docs/user-guide/administration/installation/services.html +4 -46
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +4 -46
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +4 -46
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +4 -46
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +4 -46
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +4 -46
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +4 -46
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +4 -46
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +4 -46
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +4 -46
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +8 -49
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +4 -46
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +4 -46
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +12 -50
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +7 -49
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +4 -46
- nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +4 -46
- nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +4 -46
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +4 -46
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +4 -46
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +4 -46
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +4 -46
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +4 -46
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +4 -46
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +4 -46
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +4 -46
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +4 -46
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +4 -46
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +7 -51
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +4 -46
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +4 -46
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +4 -46
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +7 -49
- nautobot/project-static/docs/user-guide/index.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +8 -50
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/events.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +7 -50
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +7 -49
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +5 -47
- nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +25 -94
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +5 -74
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +4 -46
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +4 -46
- nautobot/project-static/js/forms.js +1 -1
- nautobot/tenancy/api/views.py +13 -9
- nautobot/tenancy/views.py +2 -4
- nautobot/users/admin.py +1 -1
- nautobot/users/api/serializers.py +4 -5
- nautobot/users/api/views.py +3 -3
- nautobot/virtualization/api/serializers.py +4 -4
- nautobot/virtualization/api/views.py +24 -5
- nautobot/virtualization/filters.py +3 -20
- nautobot/virtualization/models.py +1 -1
- nautobot/virtualization/tables.py +2 -2
- nautobot/virtualization/templates/virtualization/cluster_edit.html +7 -1
- nautobot/virtualization/templates/virtualization/virtualmachine.html +9 -1
- nautobot/virtualization/templates/virtualization/virtualmachine_edit.html +8 -2
- nautobot/virtualization/tests/test_filters.py +0 -17
- nautobot/wireless/filters.py +2 -2
- nautobot/wireless/forms.py +1 -1
- nautobot/wireless/templates/wireless/wirelessnetwork_retrieve.html +9 -1
- nautobot/wireless/tests/test_filters.py +1 -29
- nautobot/wireless/views.py +10 -0
- {nautobot-2.4.0.dist-info → nautobot-2.4.0b1.dist-info}/METADATA +6 -6
- {nautobot-2.4.0.dist-info → nautobot-2.4.0b1.dist-info}/RECORD +543 -591
- {nautobot-2.4.0.dist-info → nautobot-2.4.0b1.dist-info}/WHEEL +1 -1
- nautobot/core/api/constants.py +0 -11
- nautobot/core/jobs/bulk_actions.py +0 -248
- nautobot/core/templates/about.html +0 -67
- nautobot/core/templates/inc/tenancy_form_panel.html +0 -9
- nautobot/core/templates/inc/tenant_table_row.html +0 -11
- nautobot/core/utils/querysets.py +0 -64
- nautobot/dcim/migrations/0067_controllermanageddevicegroup_tenant.py +0 -25
- nautobot/dcim/tests/integration/test_controller.py +0 -62
- nautobot/dcim/tests/integration/test_controller_managed_device_group.py +0 -71
- nautobot/dcim/tests/test_jobs.py +0 -118
- nautobot/extras/migrations/0120_job_is_singleton_job_is_singleton_override.py +0 -22
- nautobot/extras/migrations/0121_alter_team_contacts.py +0 -17
- nautobot/extras/test_jobs/singleton.py +0 -16
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_edit.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_edit_button.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_list_nav.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_list_view.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue_add.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue_config.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_completed.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_nav.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_pending.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_run_form.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_nautobot_login.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_run_job.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_run_scheduled_job_form.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_scheduled_job_result.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/buttons-example.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/cluster-type-before-after-example.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/object-fields-panel-example_2.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/stats-panel-example-code.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/central-mode.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-add.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-create-1.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-create-2.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/radio-profile-add.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/radio-profile-create.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/supported-data-rate-add.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/supported-data-rate-create.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-add.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-create-1.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-create-2.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-network-add.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-network-create.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +0 -9444
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +0 -9722
- nautobot/wireless/tests/integration/__init__.py +0 -0
- nautobot/wireless/tests/integration/test_radio_profile.py +0 -42
- {nautobot-2.4.0.dist-info → nautobot-2.4.0b1.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.4.0.dist-info → nautobot-2.4.0b1.dist-info}/NOTICE +0 -0
- {nautobot-2.4.0.dist-info → nautobot-2.4.0b1.dist-info}/entry_points.txt +0 -0
nautobot/core/views/mixins.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import ClassVar, Optional
|
|
3
2
|
|
|
4
3
|
from django.contrib import messages
|
|
5
4
|
from django.contrib.auth.mixins import AccessMixin
|
|
@@ -23,7 +22,6 @@ from django.utils.encoding import iri_to_uri
|
|
|
23
22
|
from django.utils.html import format_html
|
|
24
23
|
from django.utils.http import url_has_allowed_host_and_scheme
|
|
25
24
|
from django.views.generic.edit import FormView
|
|
26
|
-
from django_filters import FilterSet
|
|
27
25
|
from drf_spectacular.utils import extend_schema
|
|
28
26
|
from rest_framework import exceptions, mixins
|
|
29
27
|
from rest_framework.decorators import action as drf_action
|
|
@@ -39,7 +37,6 @@ from nautobot.core.forms import (
|
|
|
39
37
|
CSVFileField,
|
|
40
38
|
restrict_form_fields,
|
|
41
39
|
)
|
|
42
|
-
from nautobot.core.jobs import BulkDeleteObjects, BulkEditObjects
|
|
43
40
|
from nautobot.core.utils import lookup, permissions
|
|
44
41
|
from nautobot.core.utils.requests import get_filterable_params_from_filter_params, normalize_querydict
|
|
45
42
|
from nautobot.core.views.renderers import NautobotHTMLRenderer
|
|
@@ -51,7 +48,7 @@ from nautobot.core.views.utils import (
|
|
|
51
48
|
)
|
|
52
49
|
from nautobot.extras.context_managers import deferred_change_logging_for_bulk_operation
|
|
53
50
|
from nautobot.extras.forms import NoteForm
|
|
54
|
-
from nautobot.extras.models import ExportTemplate,
|
|
51
|
+
from nautobot.extras.models import ExportTemplate, SavedView, UserSavedViewAssociation
|
|
55
52
|
from nautobot.extras.tables import NoteTable, ObjectChangeTable
|
|
56
53
|
from nautobot.extras.utils import bulk_delete_with_bulk_change_logging, get_base_template, remove_prefix_from_cf_key
|
|
57
54
|
|
|
@@ -226,7 +223,7 @@ class NautobotViewSetMixin(GenericViewSet, AccessMixin, GetReturnURLMixin, FormV
|
|
|
226
223
|
# filterset and filter_params will be initialized in filter_queryset() in ObjectListViewMixin
|
|
227
224
|
filter_params = None
|
|
228
225
|
filterset = None
|
|
229
|
-
filterset_class
|
|
226
|
+
filterset_class = None
|
|
230
227
|
filterset_form_class = None
|
|
231
228
|
form_class = None
|
|
232
229
|
create_form_class = None
|
|
@@ -476,11 +473,7 @@ class NautobotViewSetMixin(GenericViewSet, AccessMixin, GetReturnURLMixin, FormV
|
|
|
476
473
|
def get_filter_params(self, request):
|
|
477
474
|
"""Helper function - take request.GET and discard any parameters that are not used for queryset filtering."""
|
|
478
475
|
params = request.GET.copy()
|
|
479
|
-
filter_params = get_filterable_params_from_filter_params(
|
|
480
|
-
params,
|
|
481
|
-
self.non_filter_params,
|
|
482
|
-
self.filterset_class(), # pylint: disable=not-callable # only called if filterset_class is not None
|
|
483
|
-
)
|
|
476
|
+
filter_params = get_filterable_params_from_filter_params(params, self.non_filter_params, self.filterset_class())
|
|
484
477
|
if params.get("saved_view") and not filter_params and not params.get("all_filters_removed"):
|
|
485
478
|
return SavedView.objects.get(pk=params.get("saved_view")).config.get("filter_params", {})
|
|
486
479
|
return filter_params
|
|
@@ -586,11 +579,11 @@ class NautobotViewSetMixin(GenericViewSet, AccessMixin, GetReturnURLMixin, FormV
|
|
|
586
579
|
if self.action == "bulk_destroy":
|
|
587
580
|
queryset = self.get_queryset()
|
|
588
581
|
bulk_delete_all = bool(self.request.POST.get("_all"))
|
|
582
|
+
if bulk_delete_all:
|
|
583
|
+
return ConfirmationForm
|
|
589
584
|
|
|
590
585
|
class BulkDestroyForm(ConfirmationForm):
|
|
591
|
-
pk = ModelMultipleChoiceField(
|
|
592
|
-
queryset=queryset, widget=MultipleHiddenInput, required=not bulk_delete_all
|
|
593
|
-
)
|
|
586
|
+
pk = ModelMultipleChoiceField(queryset=queryset, widget=MultipleHiddenInput)
|
|
594
587
|
|
|
595
588
|
return BulkDestroyForm
|
|
596
589
|
else:
|
|
@@ -636,8 +629,8 @@ class ObjectListViewMixin(NautobotViewSetMixin, mixins.ListModelMixin):
|
|
|
636
629
|
"""
|
|
637
630
|
|
|
638
631
|
action_buttons = ("add", "import", "export")
|
|
639
|
-
filterset_class
|
|
640
|
-
filterset_form_class
|
|
632
|
+
filterset_class = None
|
|
633
|
+
filterset_form_class = None
|
|
641
634
|
hide_hierarchy_ui = False
|
|
642
635
|
non_filter_params = (
|
|
643
636
|
"export", # trigger for CSV/export-template/YAML export # 3.0 TODO: remove, irrelevant after #4746
|
|
@@ -787,8 +780,7 @@ class ObjectDestroyViewMixin(NautobotViewSetMixin, mixins.DestroyModelMixin):
|
|
|
787
780
|
return self.perform_destroy(request, **kwargs)
|
|
788
781
|
return Response(context)
|
|
789
782
|
|
|
790
|
-
|
|
791
|
-
def perform_destroy(self, request, **kwargs): # pylint:disable=arguments-renamed
|
|
783
|
+
def perform_destroy(self, request, **kwargs):
|
|
792
784
|
"""
|
|
793
785
|
Function to validate the ObjectDeleteConfirmationForm and to delete the object.
|
|
794
786
|
"""
|
|
@@ -920,9 +912,9 @@ class ObjectEditViewMixin(NautobotViewSetMixin, mixins.CreateModelMixin, mixins.
|
|
|
920
912
|
return self.form_invalid(form)
|
|
921
913
|
|
|
922
914
|
|
|
923
|
-
class
|
|
915
|
+
class EditAndDeleteAllModelMixin:
|
|
924
916
|
"""
|
|
925
|
-
UI mixin to bulk destroy and bulk edit all model instances.
|
|
917
|
+
UI mixin to bulk destroy all and bulk edit all model instances.
|
|
926
918
|
"""
|
|
927
919
|
|
|
928
920
|
def _get_bulk_edit_delete_all_queryset(self, request):
|
|
@@ -942,7 +934,7 @@ class BulkEditAndBulkDeleteModelMixin:
|
|
|
942
934
|
filterset_class = getattr(self, "filterset_class", None)
|
|
943
935
|
|
|
944
936
|
if request.GET and filterset_class is not None:
|
|
945
|
-
queryset = filterset_class(request.GET, model.objects.all()).qs
|
|
937
|
+
queryset = filterset_class(request.GET, model.objects.all()).qs
|
|
946
938
|
# We take this approach because filterset.qs has already applied .distinct(),
|
|
947
939
|
# and performing a .delete directly on a queryset with .distinct applied is not allowed.
|
|
948
940
|
queryset = self.queryset.filter(pk__in=queryset)
|
|
@@ -950,67 +942,24 @@ class BulkEditAndBulkDeleteModelMixin:
|
|
|
950
942
|
queryset = model.objects.all()
|
|
951
943
|
return queryset
|
|
952
944
|
|
|
953
|
-
def
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
job_form = BulkDeleteObjects.as_form(
|
|
963
|
-
data={
|
|
964
|
-
"pk_list": pk_list,
|
|
965
|
-
"content_type": ContentType.objects.get_for_model(model),
|
|
966
|
-
"delete_all": delete_all,
|
|
967
|
-
"filter_query_params": filter_query_params,
|
|
968
|
-
}
|
|
969
|
-
)
|
|
970
|
-
# BulkDeleteObjects job form cannot be invalid; Hence no handling of invalid case.
|
|
971
|
-
job_form.is_valid()
|
|
972
|
-
job_kwargs = BulkDeleteObjects.prepare_job_kwargs(job_form.cleaned_data)
|
|
973
|
-
job_result = JobResult.enqueue_job(
|
|
974
|
-
job_model,
|
|
975
|
-
request.user,
|
|
976
|
-
**BulkDeleteObjects.serialize_data(job_kwargs),
|
|
977
|
-
)
|
|
978
|
-
return redirect("extras:jobresult", pk=job_result.pk)
|
|
979
|
-
|
|
980
|
-
def send_bulk_edit_objects_to_job(self, request, form, model):
|
|
981
|
-
"""Prepare and enqueue a bulk edit job."""
|
|
982
|
-
job_model = Job.objects.get_for_class_path(BulkEditObjects.class_path)
|
|
983
|
-
form_data = normalize_querydict(request.POST, form)
|
|
984
|
-
if filterset_class := lookup.get_filterset_for_model(model):
|
|
985
|
-
filter_query_params = normalize_querydict(request.GET, filterset=filterset_class())
|
|
986
|
-
else:
|
|
987
|
-
filter_query_params = None
|
|
988
|
-
job_form = BulkEditObjects.as_form(
|
|
989
|
-
data={
|
|
990
|
-
"form_data": form_data,
|
|
991
|
-
"content_type": ContentType.objects.get_for_model(model),
|
|
992
|
-
"edit_all": request.POST.get("_all") is not None,
|
|
993
|
-
"filter_query_params": filter_query_params,
|
|
994
|
-
}
|
|
995
|
-
)
|
|
996
|
-
# NOTE: BulkEditObjects cant be invalid, so there is no need for handling invalid error
|
|
997
|
-
job_form.is_valid()
|
|
998
|
-
job_kwargs = BulkEditObjects.prepare_job_kwargs(job_form.cleaned_data)
|
|
999
|
-
job_result = JobResult.enqueue_job(
|
|
1000
|
-
job_model,
|
|
1001
|
-
request.user,
|
|
1002
|
-
**BulkEditObjects.serialize_data(job_kwargs),
|
|
1003
|
-
)
|
|
1004
|
-
return redirect("extras:jobresult", pk=job_result.pk)
|
|
945
|
+
def _bulk_delete_all_context(self, request, queryset):
|
|
946
|
+
model = queryset.model
|
|
947
|
+
return {
|
|
948
|
+
"obj_type_plural": model._meta.verbose_name_plural,
|
|
949
|
+
"return_url": self.get_return_url(request),
|
|
950
|
+
"total_objs_to_delete": queryset.count(),
|
|
951
|
+
"delete_all": True,
|
|
952
|
+
"table": None,
|
|
953
|
+
}
|
|
1005
954
|
|
|
1006
955
|
|
|
1007
|
-
class ObjectBulkDestroyViewMixin(NautobotViewSetMixin, BulkDestroyModelMixin,
|
|
956
|
+
class ObjectBulkDestroyViewMixin(NautobotViewSetMixin, BulkDestroyModelMixin, EditAndDeleteAllModelMixin):
|
|
1008
957
|
"""
|
|
1009
958
|
UI mixin to bulk destroy model instances.
|
|
1010
959
|
"""
|
|
1011
960
|
|
|
1012
|
-
bulk_destroy_form_class
|
|
1013
|
-
filterset_class
|
|
961
|
+
bulk_destroy_form_class = None
|
|
962
|
+
filterset_class = None
|
|
1014
963
|
|
|
1015
964
|
def _process_bulk_destroy_form(self, form):
|
|
1016
965
|
request = self.request
|
|
@@ -1043,8 +992,7 @@ class ObjectBulkDestroyViewMixin(NautobotViewSetMixin, BulkDestroyModelMixin, Bu
|
|
|
1043
992
|
"""
|
|
1044
993
|
return self.perform_bulk_destroy(request, **kwargs)
|
|
1045
994
|
|
|
1046
|
-
|
|
1047
|
-
def perform_bulk_destroy(self, request, **kwargs): # pylint:disable=arguments-renamed
|
|
995
|
+
def perform_bulk_destroy(self, request, **kwargs):
|
|
1048
996
|
"""
|
|
1049
997
|
request.POST "_delete": Function to render the user selection of objects in a table form/BulkDestroyConfirmationForm via Response that is passed to NautobotHTMLRenderer.
|
|
1050
998
|
request.POST "_confirm": Function to validate the table form/BulkDestroyConfirmationForm and to perform the action of bulk destroy. Render the form with errors if exceptions are raised.
|
|
@@ -1054,23 +1002,21 @@ class ObjectBulkDestroyViewMixin(NautobotViewSetMixin, BulkDestroyModelMixin, Bu
|
|
|
1054
1002
|
data = {}
|
|
1055
1003
|
# Are we deleting *all* objects in the queryset or just a selected subset?
|
|
1056
1004
|
if delete_all:
|
|
1057
|
-
self.pk_list = []
|
|
1058
1005
|
queryset = self._get_bulk_edit_delete_all_queryset(self.request)
|
|
1006
|
+
data = self._bulk_delete_all_context(request, queryset)
|
|
1059
1007
|
else:
|
|
1060
1008
|
self.pk_list = list(request.POST.getlist("pk"))
|
|
1061
|
-
queryset = queryset.filter(pk__in=self.pk_list)
|
|
1062
1009
|
|
|
1010
|
+
form_class = self.get_form_class(**kwargs)
|
|
1063
1011
|
if "_confirm" in request.POST:
|
|
1064
|
-
form_class = self.get_form_class(**kwargs)
|
|
1065
1012
|
form = form_class(request.POST, initial=normalize_querydict(request.GET, form_class=form_class))
|
|
1066
1013
|
if form.is_valid():
|
|
1067
|
-
return self.
|
|
1014
|
+
return self.form_valid(form)
|
|
1068
1015
|
else:
|
|
1069
1016
|
return self.form_invalid(form)
|
|
1070
|
-
table = None
|
|
1071
1017
|
if not delete_all:
|
|
1072
1018
|
table_class = self.get_table_class()
|
|
1073
|
-
table = table_class(queryset, orderable=False)
|
|
1019
|
+
table = table_class(queryset.filter(pk__in=self.pk_list), orderable=False)
|
|
1074
1020
|
if not table.rows:
|
|
1075
1021
|
messages.warning(
|
|
1076
1022
|
request,
|
|
@@ -1078,13 +1024,7 @@ class ObjectBulkDestroyViewMixin(NautobotViewSetMixin, BulkDestroyModelMixin, Bu
|
|
|
1078
1024
|
)
|
|
1079
1025
|
return redirect(self.get_return_url(request))
|
|
1080
1026
|
|
|
1081
|
-
|
|
1082
|
-
{
|
|
1083
|
-
"table": table,
|
|
1084
|
-
"total_objs_to_delete": queryset.count(),
|
|
1085
|
-
"delete_all": delete_all,
|
|
1086
|
-
}
|
|
1087
|
-
)
|
|
1027
|
+
data.update({"table": table})
|
|
1088
1028
|
return Response(data)
|
|
1089
1029
|
|
|
1090
1030
|
|
|
@@ -1142,14 +1082,14 @@ class ObjectBulkCreateViewMixin(NautobotViewSetMixin): # 3.0 TODO: remove, unus
|
|
|
1142
1082
|
return self.form_invalid(form)
|
|
1143
1083
|
|
|
1144
1084
|
|
|
1145
|
-
class ObjectBulkUpdateViewMixin(NautobotViewSetMixin, BulkUpdateModelMixin,
|
|
1085
|
+
class ObjectBulkUpdateViewMixin(NautobotViewSetMixin, BulkUpdateModelMixin, EditAndDeleteAllModelMixin):
|
|
1146
1086
|
"""
|
|
1147
1087
|
UI mixin to bulk update model instances.
|
|
1148
1088
|
"""
|
|
1149
1089
|
|
|
1150
|
-
filterset_class
|
|
1090
|
+
filterset_class = None
|
|
1091
|
+
bulk_update_form_class = None
|
|
1151
1092
|
|
|
1152
|
-
# NOTE: Performing BulkEdit Objects has been moved to a system job, but the logic remains here to ensure backward compatibility.
|
|
1153
1093
|
def _process_bulk_update_form(self, form):
|
|
1154
1094
|
request = self.request
|
|
1155
1095
|
queryset = self.get_queryset()
|
|
@@ -1260,7 +1200,7 @@ class ObjectBulkUpdateViewMixin(NautobotViewSetMixin, BulkUpdateModelMixin, Bulk
|
|
|
1260
1200
|
form = form_class(queryset.model, request.POST, edit_all=edit_all)
|
|
1261
1201
|
restrict_form_fields(form, request.user)
|
|
1262
1202
|
if form.is_valid():
|
|
1263
|
-
return self.
|
|
1203
|
+
return self.form_valid(form)
|
|
1264
1204
|
else:
|
|
1265
1205
|
return self.form_invalid(form)
|
|
1266
1206
|
table = None
|
nautobot/core/views/renderers.py
CHANGED
|
@@ -244,11 +244,12 @@ class NautobotHTMLRenderer(renderers.BrowsableAPIRenderer):
|
|
|
244
244
|
restrict_form_fields(form, request.user)
|
|
245
245
|
elif view.action == "bulk_destroy":
|
|
246
246
|
pk_list = getattr(view, "pk_list", [])
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
247
|
+
if pk_list:
|
|
248
|
+
initial = {
|
|
249
|
+
"pk": pk_list,
|
|
250
|
+
"return_url": return_url,
|
|
251
|
+
}
|
|
252
|
+
form = form_class(initial=initial)
|
|
252
253
|
delete_all = request.POST.get("_all")
|
|
253
254
|
if not delete_all:
|
|
254
255
|
table = self.construct_table(view, pk_list=pk_list)
|
|
@@ -346,7 +347,6 @@ class NautobotHTMLRenderer(renderers.BrowsableAPIRenderer):
|
|
|
346
347
|
# Ensure the proper inheritance of context variables is applied: the view's returned data takes priority over the viewset's get_extra_context
|
|
347
348
|
context.update(view.get_extra_context(request, instance))
|
|
348
349
|
context.update(self.get_template_context(data, renderer_context))
|
|
349
|
-
|
|
350
350
|
return context
|
|
351
351
|
|
|
352
352
|
def render(self, data, accepted_media_type=None, renderer_context=None):
|
nautobot/dcim/api/serializers.py
CHANGED
|
@@ -247,15 +247,15 @@ class LocationSerializer(
|
|
|
247
247
|
# https://www.django-rest-framework.org/api-guide/validators/#optional-fields
|
|
248
248
|
validators = []
|
|
249
249
|
|
|
250
|
-
def validate(self,
|
|
250
|
+
def validate(self, data):
|
|
251
251
|
# Validate uniqueness of (parent, name) since we omitted the automatically created validator from Meta.
|
|
252
|
-
if
|
|
252
|
+
if data.get("parent") and data.get("name"):
|
|
253
253
|
validator = UniqueTogetherValidator(queryset=Location.objects.all(), fields=("parent", "name"))
|
|
254
|
-
validator(
|
|
254
|
+
validator(data, self)
|
|
255
255
|
|
|
256
|
-
super().validate(
|
|
256
|
+
super().validate(data)
|
|
257
257
|
|
|
258
|
-
return
|
|
258
|
+
return data
|
|
259
259
|
|
|
260
260
|
|
|
261
261
|
#
|
|
@@ -285,20 +285,20 @@ class RackSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
|
|
|
285
285
|
# This prevents facility_id and rack_group from being interpreted as required fields.
|
|
286
286
|
validators = []
|
|
287
287
|
|
|
288
|
-
def validate(self,
|
|
288
|
+
def validate(self, data):
|
|
289
289
|
# Validate uniqueness of (rack_group, name) since we omitted the automatically-created validator above.
|
|
290
|
-
if
|
|
290
|
+
if data.get("rack_group", None):
|
|
291
291
|
validator = UniqueTogetherValidator(queryset=Rack.objects.all(), fields=("rack_group", "name"))
|
|
292
|
-
validator(
|
|
292
|
+
validator(data, self)
|
|
293
293
|
# Validate uniqueness of (rack_group, facility_id) since we omitted the automatically-created validator above.
|
|
294
|
-
if
|
|
294
|
+
if data.get("facility_id", None) and data.get("rack_group", None):
|
|
295
295
|
validator = UniqueTogetherValidator(queryset=Rack.objects.all(), fields=("rack_group", "facility_id"))
|
|
296
|
-
validator(
|
|
296
|
+
validator(data, self)
|
|
297
297
|
|
|
298
298
|
# Enforce model validation
|
|
299
|
-
super().validate(
|
|
299
|
+
super().validate(data)
|
|
300
300
|
|
|
301
|
-
return
|
|
301
|
+
return data
|
|
302
302
|
|
|
303
303
|
|
|
304
304
|
class RackUnitSerializer(serializers.Serializer):
|
|
@@ -369,7 +369,7 @@ class ManufacturerSerializer(NautobotModelSerializer):
|
|
|
369
369
|
fields = "__all__"
|
|
370
370
|
|
|
371
371
|
|
|
372
|
-
class DeviceFamilySerializer(
|
|
372
|
+
class DeviceFamilySerializer(NautobotModelSerializer):
|
|
373
373
|
device_type_count = serializers.IntegerField(read_only=True)
|
|
374
374
|
|
|
375
375
|
class Meta:
|
|
@@ -534,6 +534,14 @@ class DeviceSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
|
|
|
534
534
|
"vc_priority": {"label": "Virtual chassis priority"},
|
|
535
535
|
}
|
|
536
536
|
|
|
537
|
+
def get_additional_detail_view_tabs(self):
|
|
538
|
+
"""Add "Virtual Chassis" as a separate detail tab."""
|
|
539
|
+
tabs = super().get_additional_detail_view_tabs()
|
|
540
|
+
tabs["Virtual Chassis"] = [
|
|
541
|
+
{"Virtual Chassis": {"fields": ["virtual_chassis", "vc_position", "vc_priority"]}},
|
|
542
|
+
]
|
|
543
|
+
return tabs
|
|
544
|
+
|
|
537
545
|
def get_field_names(self, declared_fields, info):
|
|
538
546
|
"""
|
|
539
547
|
Add a couple of special fields to the serializer.
|
|
@@ -550,20 +558,20 @@ class DeviceSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
|
|
|
550
558
|
def get_config_context(self, obj):
|
|
551
559
|
return obj.get_config_context()
|
|
552
560
|
|
|
553
|
-
def validate(self,
|
|
561
|
+
def validate(self, data):
|
|
554
562
|
# Validate uniqueness of (rack, position, face) since we omitted the automatically-created validator from Meta.
|
|
555
|
-
if
|
|
563
|
+
if data.get("rack") and data.get("position") and data.get("face"):
|
|
556
564
|
validator = UniqueTogetherValidator(
|
|
557
565
|
queryset=Device.objects.all(),
|
|
558
566
|
fields=("rack", "position", "face"),
|
|
559
567
|
message=f"The position and face is already occupied on this rack. {UniqueTogetherValidator.message}",
|
|
560
568
|
)
|
|
561
|
-
validator(
|
|
569
|
+
validator(data, self)
|
|
562
570
|
|
|
563
571
|
# Enforce model validation
|
|
564
|
-
super().validate(
|
|
572
|
+
super().validate(data)
|
|
565
573
|
|
|
566
|
-
return
|
|
574
|
+
return data
|
|
567
575
|
|
|
568
576
|
|
|
569
577
|
class DeviceNAPALMSerializer(serializers.Serializer):
|
|
@@ -636,22 +644,22 @@ class PowerPortSerializer(
|
|
|
636
644
|
|
|
637
645
|
|
|
638
646
|
class InterfaceCommonSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
|
|
639
|
-
def validate(self,
|
|
647
|
+
def validate(self, data):
|
|
640
648
|
# Validate many-to-many VLAN assignments
|
|
641
|
-
mode =
|
|
649
|
+
mode = data.get("mode", getattr(self.instance, "mode", None))
|
|
642
650
|
|
|
643
651
|
if mode != InterfaceModeChoices.MODE_TAGGED:
|
|
644
|
-
if
|
|
652
|
+
if data.get("tagged_vlans"):
|
|
645
653
|
raise serializers.ValidationError(
|
|
646
654
|
{
|
|
647
655
|
"tagged_vlans": f"Mode must be set to {InterfaceModeChoices.MODE_TAGGED} when specifying tagged_vlans"
|
|
648
656
|
}
|
|
649
657
|
)
|
|
650
658
|
|
|
651
|
-
if
|
|
659
|
+
if data.get("tagged_vlans") != [] and self.instance and self.instance.tagged_vlans.exists():
|
|
652
660
|
raise serializers.ValidationError({"tagged_vlans": f"Clear tagged_vlans to set mode to {mode}"})
|
|
653
661
|
|
|
654
|
-
return super().validate(
|
|
662
|
+
return super().validate(data)
|
|
655
663
|
|
|
656
664
|
|
|
657
665
|
class InterfaceSerializer(
|
|
@@ -663,7 +671,7 @@ class InterfaceSerializer(
|
|
|
663
671
|
type = ChoiceField(choices=InterfaceTypeChoices)
|
|
664
672
|
mode = ChoiceField(choices=InterfaceModeChoices, allow_blank=True, required=False)
|
|
665
673
|
mac_address = serializers.CharField(allow_blank=True, allow_null=True, required=False)
|
|
666
|
-
ip_address_count = serializers.IntegerField(read_only=True
|
|
674
|
+
ip_address_count = serializers.IntegerField(read_only=True)
|
|
667
675
|
|
|
668
676
|
class Meta:
|
|
669
677
|
model = Interface
|
|
@@ -752,18 +760,18 @@ class InventoryItemSerializer(TaggedModelSerializerMixin, TreeModelSerializerMix
|
|
|
752
760
|
# https://www.django-rest-framework.org/api-guide/validators/#optional-fields
|
|
753
761
|
validators = []
|
|
754
762
|
|
|
755
|
-
def validate(self,
|
|
763
|
+
def validate(self, data):
|
|
756
764
|
# Validate uniqueness of (device, parent, name) since we omitted the automatically created validator from Meta.
|
|
757
|
-
if
|
|
765
|
+
if data.get("device") and data.get("parent") and data.get("name"):
|
|
758
766
|
validator = UniqueTogetherValidator(
|
|
759
767
|
queryset=InventoryItem.objects.all(),
|
|
760
768
|
fields=("device", "parent", "name"),
|
|
761
769
|
)
|
|
762
|
-
validator(
|
|
770
|
+
validator(data, self)
|
|
763
771
|
|
|
764
|
-
super().validate(
|
|
772
|
+
super().validate(data)
|
|
765
773
|
|
|
766
|
-
return
|
|
774
|
+
return data
|
|
767
775
|
|
|
768
776
|
|
|
769
777
|
#
|
|
@@ -1010,21 +1018,21 @@ class ModuleBaySerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
|
|
|
1010
1018
|
fields = "__all__"
|
|
1011
1019
|
validators = []
|
|
1012
1020
|
|
|
1013
|
-
def validate(self,
|
|
1021
|
+
def validate(self, data):
|
|
1014
1022
|
"""Validate device and module field constraints for module bay."""
|
|
1015
|
-
if
|
|
1023
|
+
if data.get("parent_device") and data.get("parent_module"):
|
|
1016
1024
|
raise serializers.ValidationError("Only one of parent_device or parent_module must be set")
|
|
1017
|
-
if
|
|
1025
|
+
if data.get("parent_device"):
|
|
1018
1026
|
validator = UniqueTogetherValidator(
|
|
1019
1027
|
queryset=self.Meta.model.objects.all(), fields=("parent_device", "name")
|
|
1020
1028
|
)
|
|
1021
|
-
validator(
|
|
1022
|
-
if
|
|
1029
|
+
validator(data, self)
|
|
1030
|
+
if data.get("parent_module"):
|
|
1023
1031
|
validator = UniqueTogetherValidator(
|
|
1024
1032
|
queryset=self.Meta.model.objects.all(), fields=("parent_module", "name")
|
|
1025
1033
|
)
|
|
1026
|
-
validator(
|
|
1027
|
-
return super().validate(
|
|
1034
|
+
validator(data, self)
|
|
1035
|
+
return super().validate(data)
|
|
1028
1036
|
|
|
1029
1037
|
|
|
1030
1038
|
class ModuleBayTemplateSerializer(NautobotModelSerializer):
|
|
@@ -1033,17 +1041,17 @@ class ModuleBayTemplateSerializer(NautobotModelSerializer):
|
|
|
1033
1041
|
fields = "__all__"
|
|
1034
1042
|
validators = []
|
|
1035
1043
|
|
|
1036
|
-
def validate(self,
|
|
1044
|
+
def validate(self, data):
|
|
1037
1045
|
"""Validate device_type and module_type field constraints for module bay template."""
|
|
1038
|
-
if
|
|
1046
|
+
if data.get("device_type") and data.get("module_type"):
|
|
1039
1047
|
raise serializers.ValidationError("Only one of device_type or module_type must be set")
|
|
1040
|
-
if
|
|
1048
|
+
if data.get("device_type"):
|
|
1041
1049
|
validator = UniqueTogetherValidator(queryset=self.Meta.model.objects.all(), fields=("device_type", "name"))
|
|
1042
|
-
validator(
|
|
1043
|
-
if
|
|
1050
|
+
validator(data, self)
|
|
1051
|
+
if data.get("module_type"):
|
|
1044
1052
|
validator = UniqueTogetherValidator(queryset=self.Meta.model.objects.all(), fields=("module_type", "name"))
|
|
1045
|
-
validator(
|
|
1046
|
-
return super().validate(
|
|
1053
|
+
validator(data, self)
|
|
1054
|
+
return super().validate(data)
|
|
1047
1055
|
|
|
1048
1056
|
|
|
1049
1057
|
class ModuleSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
|
|
@@ -1053,17 +1061,17 @@ class ModuleSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
|
|
|
1053
1061
|
|
|
1054
1062
|
validators = []
|
|
1055
1063
|
|
|
1056
|
-
def validate(self,
|
|
1064
|
+
def validate(self, data):
|
|
1057
1065
|
"""Validate asset_Tag, serial, parent_module_bay and location field constraints for module."""
|
|
1058
|
-
if
|
|
1066
|
+
if data.get("parent_module_bay") and data.get("location"):
|
|
1059
1067
|
raise serializers.ValidationError("Only one of parent_module_bay or location must be set")
|
|
1060
|
-
if
|
|
1068
|
+
if data.get("serial"):
|
|
1061
1069
|
validator = UniqueTogetherValidator(queryset=Module.objects.all(), fields=("module_type", "serial"))
|
|
1062
|
-
validator(
|
|
1063
|
-
if
|
|
1070
|
+
validator(data, self)
|
|
1071
|
+
if data.get("asset_tag"):
|
|
1064
1072
|
validator = UniqueValidator(queryset=Module.objects.all())
|
|
1065
|
-
validator(
|
|
1066
|
-
return super().validate(
|
|
1073
|
+
validator(data["asset_tag"], self.fields["asset_tag"])
|
|
1074
|
+
return super().validate(data)
|
|
1067
1075
|
|
|
1068
1076
|
|
|
1069
1077
|
class ModuleTypeSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
|
|
@@ -1072,16 +1080,16 @@ class ModuleTypeSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
|
|
|
1072
1080
|
fields = "__all__"
|
|
1073
1081
|
|
|
1074
1082
|
|
|
1075
|
-
class VirtualDeviceContextSerializer(
|
|
1083
|
+
class VirtualDeviceContextSerializer(NautobotModelSerializer):
|
|
1076
1084
|
class Meta:
|
|
1077
1085
|
model = VirtualDeviceContext
|
|
1078
1086
|
fields = "__all__"
|
|
1079
1087
|
|
|
1080
|
-
def validate(self,
|
|
1088
|
+
def validate(self, data):
|
|
1081
1089
|
"""Validate device cannot be changed for VirtualDeviceContext."""
|
|
1082
|
-
if
|
|
1090
|
+
if data.get("device") and self.instance and self.instance.device != data.get("device"):
|
|
1083
1091
|
raise serializers.ValidationError("Changing the device of a VirtualDeviceContext is not allowed.")
|
|
1084
|
-
return super().validate(
|
|
1092
|
+
return super().validate(data)
|
|
1085
1093
|
|
|
1086
1094
|
|
|
1087
1095
|
class InterfaceVDCAssignmentSerializer(ValidatedModelSerializer):
|