nautobot 2.3.15b1__py3-none-any.whl → 2.4.0__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/__init__.py +15 -0
- nautobot/apps/__init__.py +1 -1
- nautobot/apps/api.py +8 -10
- nautobot/apps/change_logging.py +2 -2
- nautobot/apps/choices.py +4 -4
- nautobot/apps/config.py +32 -3
- nautobot/apps/events.py +19 -0
- nautobot/apps/exceptions.py +0 -2
- 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 +44 -9
- nautobot/apps/utils.py +7 -15
- nautobot/apps/views.py +8 -6
- nautobot/circuits/api/serializers.py +1 -0
- nautobot/circuits/api/views.py +4 -8
- nautobot/circuits/navigation.py +0 -57
- nautobot/circuits/templates/circuits/circuit_create.html +1 -7
- nautobot/circuits/templates/circuits/circuit_retrieve.html +0 -71
- nautobot/circuits/templates/circuits/inc/circuit_termination.html +6 -64
- nautobot/circuits/templates/circuits/inc/circuit_termination_cable_fragment.html +40 -0
- nautobot/circuits/templates/circuits/inc/circuit_termination_header_extra_content.html +26 -0
- nautobot/circuits/templates/circuits/provider_retrieve.html +0 -76
- nautobot/circuits/tests/integration/test_relationships.py +33 -24
- nautobot/circuits/tests/test_filters.py +4 -8
- nautobot/circuits/views.py +143 -26
- nautobot/cloud/api/views.py +6 -10
- nautobot/cloud/factory.py +4 -1
- nautobot/cloud/models.py +1 -1
- nautobot/cloud/tests/test_filters.py +5 -4
- nautobot/cloud/views.py +0 -16
- nautobot/core/api/constants.py +11 -0
- nautobot/core/api/fields.py +5 -5
- nautobot/core/api/filter_backends.py +3 -9
- nautobot/core/api/metadata.py +28 -256
- nautobot/core/api/pagination.py +3 -2
- nautobot/core/api/renderers.py +3 -0
- nautobot/core/api/schema.py +13 -2
- nautobot/core/api/serializers.py +54 -268
- nautobot/core/api/urls.py +3 -4
- nautobot/core/api/utils.py +0 -62
- nautobot/core/api/views.py +102 -159
- nautobot/core/apps/__init__.py +22 -575
- nautobot/core/celery/__init__.py +13 -0
- nautobot/core/celery/schedulers.py +48 -3
- nautobot/core/choices.py +2 -2
- nautobot/core/cli/__init__.py +8 -0
- nautobot/core/constants.py +7 -0
- nautobot/core/events/__init__.py +116 -0
- nautobot/core/events/base.py +27 -0
- nautobot/core/events/exceptions.py +10 -0
- nautobot/core/events/redis_broker.py +48 -0
- nautobot/core/events/syslog_broker.py +19 -0
- nautobot/core/exceptions.py +0 -6
- nautobot/core/filters.py +19 -16
- nautobot/core/forms/__init__.py +19 -19
- nautobot/core/forms/fields.py +62 -14
- nautobot/core/forms/forms.py +33 -2
- nautobot/core/forms/utils.py +2 -1
- nautobot/core/graphql/schema.py +3 -1
- nautobot/core/graphql/types.py +1 -1
- nautobot/core/jobs/__init__.py +28 -7
- nautobot/core/jobs/bulk_actions.py +248 -0
- nautobot/core/jobs/cleanup.py +2 -2
- nautobot/core/jobs/groups.py +1 -1
- nautobot/core/management/commands/generate_test_data.py +21 -0
- nautobot/core/management/commands/validate_models.py +1 -1
- nautobot/core/middleware.py +16 -0
- nautobot/core/models/__init__.py +1 -1
- nautobot/core/models/fields.py +11 -7
- nautobot/core/models/query_functions.py +2 -2
- nautobot/core/models/tree_queries.py +2 -2
- nautobot/core/settings.py +71 -4
- nautobot/core/settings.yaml +107 -0
- nautobot/core/tables.py +15 -51
- nautobot/core/tasks.py +1 -1
- nautobot/core/templates/about.html +67 -0
- nautobot/core/templates/components/button/default.html +7 -0
- nautobot/core/templates/components/button/dropdown.html +20 -0
- nautobot/core/templates/components/layout/one_over_two.html +19 -0
- nautobot/core/templates/components/layout/two_over_one.html +19 -0
- nautobot/core/templates/components/panel/body_content_data_table.html +27 -0
- nautobot/core/templates/components/panel/body_content_objects_table.html +4 -0
- nautobot/core/templates/components/panel/body_content_tags.html +6 -0
- nautobot/core/templates/components/panel/body_content_text.html +12 -0
- nautobot/core/templates/components/panel/body_wrapper_generic.html +3 -0
- nautobot/core/templates/components/panel/body_wrapper_key_value_table.html +3 -0
- nautobot/core/templates/components/panel/body_wrapper_table.html +3 -0
- nautobot/core/templates/components/panel/footer_contacts_table.html +20 -0
- nautobot/core/templates/components/panel/footer_content_table.html +14 -0
- nautobot/core/templates/components/panel/grouping_toggle.html +14 -0
- nautobot/core/templates/components/panel/header_extra_content_table.html +3 -0
- nautobot/core/templates/components/panel/panel.html +16 -0
- nautobot/core/templates/components/panel/stats_panel_body.html +8 -0
- nautobot/core/templates/components/tab/content_wrapper.html +3 -0
- nautobot/core/templates/components/tab/label_wrapper.html +5 -0
- nautobot/core/templates/components/tab/label_wrapper_distinct_view.html +3 -0
- nautobot/core/templates/generic/object_retrieve.html +28 -17
- nautobot/core/templates/inc/computed_fields/panel_data.html +4 -7
- nautobot/core/templates/inc/custom_fields/panel.html +2 -2
- nautobot/core/templates/inc/custom_fields/panel_data.html +4 -7
- nautobot/core/templates/inc/footer.html +1 -0
- nautobot/core/templates/inc/media.html +3 -0
- nautobot/core/templates/inc/nav_menu.html +2 -1
- nautobot/core/templates/inc/relationships_panel.html +1 -1
- nautobot/core/templates/inc/tenancy_form_panel.html +9 -0
- nautobot/core/templates/inc/tenant_table_row.html +11 -0
- nautobot/core/templates/nautobot_config.py.j2 +16 -0
- nautobot/core/templates/panel_table.html +12 -0
- nautobot/core/templates/utilities/render_jinja2.html +117 -0
- nautobot/core/templates/utilities/templatetags/tag.html +1 -1
- nautobot/core/templates/utilities/theme_preview.html +7 -0
- nautobot/core/templatetags/helpers.py +104 -6
- nautobot/core/templatetags/ui_framework.py +40 -0
- nautobot/core/testing/__init__.py +8 -8
- nautobot/core/testing/api.py +187 -137
- nautobot/core/testing/context.py +18 -0
- nautobot/core/testing/filters.py +44 -34
- nautobot/core/testing/forms.py +2 -0
- nautobot/core/testing/views.py +68 -146
- nautobot/core/tests/integration/test_app_home.py +0 -1
- nautobot/core/tests/integration/test_app_navbar.py +0 -1
- nautobot/core/tests/integration/test_filters.py +0 -2
- nautobot/core/tests/integration/test_home.py +0 -1
- nautobot/core/tests/integration/test_navbar.py +0 -1
- nautobot/core/tests/integration/test_view_authentication.py +2 -1
- nautobot/core/tests/nautobot_config.py +198 -0
- nautobot/core/tests/runner.py +3 -3
- nautobot/core/tests/test_api.py +154 -176
- nautobot/core/tests/test_events.py +214 -0
- nautobot/core/tests/test_forms.py +1 -0
- nautobot/core/tests/test_jinja_filters.py +1 -0
- nautobot/core/tests/test_jobs.py +387 -14
- nautobot/core/tests/test_navigations.py +7 -241
- nautobot/core/tests/test_settings_schema.py +7 -0
- nautobot/core/tests/test_tables.py +100 -0
- nautobot/core/tests/test_templatetags_helpers.py +16 -0
- nautobot/core/tests/test_ui.py +150 -0
- nautobot/core/tests/test_utils.py +55 -18
- nautobot/core/tests/test_views.py +153 -5
- nautobot/core/ui/__init__.py +0 -0
- nautobot/core/ui/base.py +11 -0
- nautobot/core/ui/choices.py +44 -0
- nautobot/core/ui/homepage.py +167 -0
- nautobot/core/ui/nav.py +280 -0
- nautobot/core/ui/object_detail.py +1855 -0
- nautobot/core/ui/utils.py +36 -0
- nautobot/core/urls.py +15 -0
- nautobot/core/utils/config.py +30 -3
- nautobot/core/utils/lookup.py +12 -2
- nautobot/core/utils/querysets.py +64 -0
- nautobot/core/utils/requests.py +24 -9
- nautobot/core/views/__init__.py +48 -1
- nautobot/core/views/generic.py +82 -177
- nautobot/core/views/mixins.py +98 -38
- nautobot/core/views/paginator.py +8 -5
- nautobot/core/views/renderers.py +9 -9
- nautobot/core/views/utils.py +11 -0
- nautobot/core/wsgi.py +3 -3
- nautobot/dcim/api/serializers.py +82 -189
- nautobot/dcim/api/urls.py +5 -0
- nautobot/dcim/api/views.py +57 -110
- nautobot/dcim/apps.py +1 -0
- nautobot/dcim/choices.py +28 -0
- nautobot/dcim/factory.py +58 -0
- nautobot/dcim/filters/__init__.py +204 -2
- nautobot/dcim/forms.py +221 -9
- nautobot/dcim/graphql/types.py +2 -2
- nautobot/dcim/migrations/0063_interfacevdcassignment_virtualdevicecontext_and_more.py +165 -0
- nautobot/dcim/migrations/0064_virtualdevicecontext_status_data_migration.py +28 -0
- nautobot/dcim/migrations/0065_controller_capabilities_and_more.py +29 -0
- nautobot/dcim/migrations/0066_controllermanageddevicegroup_radio_profiles_and_more.py +33 -0
- nautobot/dcim/migrations/0067_controllermanageddevicegroup_tenant.py +25 -0
- nautobot/dcim/models/__init__.py +5 -1
- nautobot/dcim/models/device_component_templates.py +2 -2
- nautobot/dcim/models/device_components.py +22 -20
- nautobot/dcim/models/devices.py +181 -3
- nautobot/dcim/models/locations.py +3 -3
- nautobot/dcim/models/power.py +6 -5
- nautobot/dcim/models/racks.py +6 -6
- nautobot/dcim/navigation.py +25 -224
- nautobot/dcim/signals.py +44 -0
- nautobot/dcim/tables/__init__.py +5 -3
- nautobot/dcim/tables/devices.py +103 -7
- nautobot/dcim/tables/devicetypes.py +2 -2
- nautobot/dcim/tables/racks.py +1 -1
- nautobot/dcim/templates/dcim/controller/base.html +10 -0
- nautobot/dcim/templates/dcim/controller_create.html +2 -7
- nautobot/dcim/templates/dcim/controller_retrieve.html +6 -10
- nautobot/dcim/templates/dcim/controller_wirelessnetworks.html +25 -0
- nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +68 -0
- nautobot/dcim/templates/dcim/controllermanageddevicegroup_retrieve.html +51 -0
- nautobot/dcim/templates/dcim/device/base.html +6 -42
- nautobot/dcim/templates/dcim/device/wireless.html +73 -0
- nautobot/dcim/templates/dcim/device.html +4 -10
- nautobot/dcim/templates/dcim/device_edit.html +36 -37
- nautobot/dcim/templates/dcim/interface.html +1 -0
- nautobot/dcim/templates/dcim/interface_edit.html +1 -0
- nautobot/dcim/templates/dcim/location.html +1 -9
- nautobot/dcim/templates/dcim/location_edit.html +1 -7
- nautobot/dcim/templates/dcim/locationtype.html +0 -107
- nautobot/dcim/templates/dcim/locationtype_retrieve.html +8 -0
- nautobot/dcim/templates/dcim/rack.html +1 -9
- nautobot/dcim/templates/dcim/rack_edit.html +1 -7
- nautobot/dcim/templates/dcim/rackreservation.html +1 -9
- nautobot/dcim/templates/dcim/virtualdevicecontext_retrieve.html +68 -0
- nautobot/dcim/templates/dcim/virtualdevicecontext_update.html +28 -0
- nautobot/dcim/tests/integration/test_controller.py +62 -0
- nautobot/dcim/tests/integration/test_controller_managed_device_group.py +71 -0
- nautobot/dcim/tests/test_api.py +188 -64
- nautobot/dcim/tests/test_filters.py +172 -76
- nautobot/dcim/tests/test_graphql.py +52 -0
- nautobot/dcim/tests/test_jobs.py +118 -0
- nautobot/dcim/tests/test_models.py +159 -5
- nautobot/dcim/tests/test_signals.py +1 -0
- nautobot/dcim/tests/test_views.py +118 -88
- nautobot/dcim/urls.py +72 -27
- nautobot/dcim/utils.py +2 -2
- nautobot/dcim/views.py +357 -62
- nautobot/extras/api/customfields.py +2 -2
- nautobot/extras/api/serializers.py +111 -87
- nautobot/extras/api/urls.py +4 -0
- nautobot/extras/api/views.py +93 -35
- nautobot/extras/choices.py +13 -0
- nautobot/extras/constants.py +2 -1
- nautobot/extras/context_managers.py +23 -6
- nautobot/extras/datasources/git.py +4 -1
- nautobot/extras/factory.py +27 -0
- nautobot/extras/filters/__init__.py +66 -5
- nautobot/extras/forms/base.py +2 -2
- nautobot/extras/forms/forms.py +262 -59
- nautobot/extras/forms/mixins.py +3 -3
- nautobot/extras/graphql/types.py +25 -1
- nautobot/extras/health_checks.py +1 -2
- nautobot/extras/jobs.py +114 -20
- nautobot/extras/management/__init__.py +1 -0
- nautobot/extras/management/commands/runjob.py +7 -79
- nautobot/extras/management/commands/runjob_with_job_result.py +46 -0
- nautobot/extras/management/utils.py +87 -0
- nautobot/extras/managers.py +3 -1
- nautobot/extras/migrations/0018_joblog_data_migration.py +7 -9
- nautobot/extras/migrations/0117_create_job_queue_model.py +129 -0
- nautobot/extras/migrations/0118_task_queue_to_job_queue_migration.py +78 -0
- nautobot/extras/migrations/0119_remove_task_queues_from_job_and_queue_from_scheduled_job.py +28 -0
- nautobot/extras/migrations/0120_job_is_singleton_job_is_singleton_override.py +22 -0
- nautobot/extras/migrations/0121_alter_team_contacts.py +17 -0
- nautobot/extras/models/__init__.py +5 -1
- nautobot/extras/models/change_logging.py +7 -3
- nautobot/extras/models/contacts.py +1 -1
- nautobot/extras/models/customfields.py +12 -11
- nautobot/extras/models/groups.py +11 -9
- nautobot/extras/models/jobs.py +237 -37
- nautobot/extras/models/models.py +2 -2
- nautobot/extras/models/relationships.py +69 -1
- nautobot/extras/models/secrets.py +5 -0
- nautobot/extras/navigation.py +20 -262
- nautobot/extras/plugins/__init__.py +54 -19
- nautobot/extras/plugins/marketplace_manifest.yml +455 -0
- nautobot/extras/plugins/tables.py +16 -14
- nautobot/extras/plugins/urls.py +1 -0
- nautobot/extras/plugins/views.py +104 -61
- nautobot/extras/registry.py +1 -1
- nautobot/extras/secrets/__init__.py +2 -2
- nautobot/extras/signals.py +39 -1
- nautobot/extras/tables.py +42 -6
- nautobot/extras/templates/extras/dynamicgroup.html +1 -9
- nautobot/extras/templates/extras/externalintegration_retrieve.html +0 -47
- nautobot/extras/templates/extras/inc/tags_panel.html +1 -5
- nautobot/extras/templates/extras/job_bulk_edit.html +2 -1
- nautobot/extras/templates/extras/job_detail.html +52 -6
- nautobot/extras/templates/extras/job_edit.html +6 -2
- nautobot/extras/templates/extras/job_list.html +2 -7
- nautobot/extras/templates/extras/jobqueue_retrieve.html +36 -0
- nautobot/extras/templates/extras/marketplace.html +296 -0
- nautobot/extras/templates/extras/plugin_detail.html +32 -15
- nautobot/extras/templates/extras/plugins_list.html +35 -1
- nautobot/extras/templates/extras/plugins_tiles.html +90 -0
- nautobot/extras/templates/extras/role_retrieve.html +16 -0
- nautobot/extras/templates/extras/secret.html +0 -65
- nautobot/extras/templates/extras/secret_check.js +16 -0
- nautobot/extras/templates/extras/secret_create.html +114 -0
- nautobot/extras/templates/extras/secret_edit.html +1 -114
- nautobot/extras/templates/extras/secretsgroup_edit.html +1 -1
- nautobot/extras/templates/extras/templatetags/plugin_object_detail_tabs.html +2 -0
- nautobot/extras/templatetags/job_buttons.py +5 -4
- nautobot/extras/templatetags/plugins.py +69 -6
- 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 +3 -1
- 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/singleton.py +16 -0
- 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 +0 -2
- nautobot/extras/tests/test_api.py +157 -55
- nautobot/extras/tests/test_context_managers.py +4 -1
- nautobot/extras/tests/test_customfields.py +1 -1
- nautobot/extras/tests/test_datasources.py +2 -1
- nautobot/extras/tests/test_dynamicgroups.py +1 -1
- nautobot/extras/tests/test_filters.py +219 -535
- nautobot/extras/tests/test_forms.py +20 -1
- nautobot/extras/tests/test_job_variables.py +73 -152
- nautobot/extras/tests/test_jobs.py +192 -62
- nautobot/extras/tests/test_models.py +71 -16
- nautobot/extras/tests/test_plugins.py +62 -9
- nautobot/extras/tests/test_relationships.py +124 -10
- nautobot/extras/tests/test_utils.py +23 -2
- nautobot/extras/tests/test_views.py +162 -161
- nautobot/extras/tests/test_webhooks.py +2 -1
- nautobot/extras/urls.py +2 -20
- nautobot/extras/utils.py +119 -4
- nautobot/extras/views.py +188 -141
- nautobot/extras/webhooks.py +5 -2
- nautobot/ipam/api/fields.py +3 -3
- nautobot/ipam/api/serializers.py +44 -137
- nautobot/ipam/api/views.py +68 -110
- nautobot/ipam/factory.py +1 -1
- nautobot/ipam/filters.py +3 -2
- nautobot/ipam/models.py +10 -12
- nautobot/ipam/navigation.py +0 -90
- nautobot/ipam/querysets.py +2 -2
- nautobot/ipam/tables.py +3 -1
- nautobot/ipam/templates/ipam/ipaddress.html +1 -9
- nautobot/ipam/templates/ipam/ipaddress_bulk_add.html +1 -7
- nautobot/ipam/templates/ipam/ipaddress_edit.html +1 -7
- nautobot/ipam/templates/ipam/prefix.html +1 -9
- nautobot/ipam/templates/ipam/prefix_edit.html +1 -7
- nautobot/ipam/templates/ipam/routetarget.html +0 -28
- nautobot/ipam/templates/ipam/vlan.html +1 -9
- nautobot/ipam/templates/ipam/vlan_edit.html +1 -7
- nautobot/ipam/templates/ipam/vrf.html +0 -47
- nautobot/ipam/templates/ipam/vrf_edit.html +1 -7
- nautobot/ipam/tests/test_api.py +19 -6
- nautobot/ipam/tests/test_filters.py +39 -119
- nautobot/ipam/tests/test_forms.py +49 -47
- nautobot/ipam/tests/test_migrations.py +30 -30
- nautobot/ipam/tests/test_models.py +56 -36
- nautobot/ipam/tests/test_querysets.py +14 -0
- nautobot/ipam/tests/test_views.py +3 -0
- nautobot/ipam/urls.py +3 -69
- nautobot/ipam/utils/__init__.py +16 -10
- nautobot/ipam/views.py +91 -162
- 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 +40 -2
- 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/css/base.css +38 -3
- nautobot/project-static/docs/404.html +463 -19
- nautobot/project-static/docs/apps/index.html +463 -19
- nautobot/project-static/docs/apps/nautobot-apps.html +464 -21
- nautobot/project-static/docs/assets/_mkdocstrings.css +25 -1
- nautobot/project-static/docs/assets/extra.css +5 -1
- nautobot/project-static/docs/assets/javascripts/{bundle.83f73b43.min.js → bundle.88dd0f4e.min.js} +2 -2
- nautobot/project-static/docs/assets/javascripts/{bundle.83f73b43.min.js.map → bundle.88dd0f4e.min.js.map} +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +479 -25
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +476 -22
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +792 -291
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +507 -33
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +512 -36
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +473 -22
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +469 -20
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +499 -35
- nautobot/project-static/docs/code-reference/nautobot/apps/events.html +9883 -0
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +525 -77
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +548 -53
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +672 -96
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +1033 -180
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +526 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +876 -190
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +957 -237
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +477 -23
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +488 -30
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +663 -101
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +949 -481
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +6427 -1236
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +476 -22
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +879 -346
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +830 -173
- nautobot/project-static/docs/development/apps/api/configuration-view.html +463 -19
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +463 -19
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +463 -19
- nautobot/project-static/docs/development/apps/api/models/global-search.html +463 -19
- nautobot/project-static/docs/development/apps/api/models/graphql.html +463 -19
- nautobot/project-static/docs/development/apps/api/models/index.html +463 -19
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +463 -19
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +463 -19
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +463 -19
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +463 -19
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +463 -19
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +463 -19
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +463 -19
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +463 -19
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +463 -19
- nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +463 -19
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +463 -19
- nautobot/project-static/docs/development/apps/api/prometheus.html +463 -19
- nautobot/project-static/docs/development/apps/api/setup.html +467 -155
- nautobot/project-static/docs/development/apps/api/testing.html +463 -19
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +463 -19
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +463 -19
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +463 -19
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +463 -19
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +743 -130
- nautobot/project-static/docs/development/apps/api/views/base-template.html +463 -19
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +463 -19
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +463 -19
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +463 -19
- nautobot/project-static/docs/development/apps/api/views/index.html +465 -20
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +467 -19
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +493 -19
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +463 -19
- nautobot/project-static/docs/development/apps/api/views/notes.html +463 -19
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +469 -21
- nautobot/project-static/docs/development/apps/api/views/urls.html +463 -19
- nautobot/project-static/docs/development/apps/index.html +463 -19
- nautobot/project-static/docs/development/apps/migration/code-updates.html +464 -52
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +464 -20
- nautobot/project-static/docs/development/apps/migration/from-v1.html +463 -19
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +463 -19
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +463 -19
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +463 -19
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +466 -22
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +9261 -0
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +9375 -0
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +9671 -0
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +9559 -0
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +466 -22
- nautobot/project-static/docs/development/core/application-registry.html +463 -19
- nautobot/project-static/docs/development/core/best-practices.html +463 -19
- nautobot/project-static/docs/development/core/bootstrap-ui.html +463 -19
- nautobot/project-static/docs/development/core/caching.html +463 -19
- nautobot/project-static/docs/development/core/controllers.html +465 -19
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +491 -90
- nautobot/project-static/docs/development/core/generic-views.html +463 -19
- nautobot/project-static/docs/development/core/getting-started.html +541 -129
- nautobot/project-static/docs/development/core/homepage.html +474 -30
- nautobot/project-static/docs/development/core/index.html +463 -19
- nautobot/project-static/docs/development/core/minikube-dev-environment-for-k8s-jobs.html +9754 -0
- nautobot/project-static/docs/development/core/model-checklist.html +473 -27
- nautobot/project-static/docs/development/core/model-features.html +463 -19
- nautobot/project-static/docs/development/core/natural-keys.html +463 -19
- nautobot/project-static/docs/development/core/navigation-menu.html +480 -26
- nautobot/project-static/docs/development/core/release-checklist.html +480 -48
- nautobot/project-static/docs/development/core/role-internals.html +463 -19
- nautobot/project-static/docs/development/core/settings.html +463 -19
- nautobot/project-static/docs/development/core/style-guide.html +466 -22
- nautobot/project-static/docs/development/core/templates.html +473 -22
- nautobot/project-static/docs/development/core/testing.html +463 -19
- nautobot/project-static/docs/development/core/ui-component-framework.html +11116 -0
- nautobot/project-static/docs/development/core/user-preferences.html +466 -22
- nautobot/project-static/docs/development/index.html +463 -19
- nautobot/project-static/docs/development/jobs/index.html +501 -21
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +463 -19
- nautobot/project-static/docs/index.html +471 -38
- 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/basic-panel-layout.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/button-example.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/dropdown-button-example.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/grouped-key-value-table-panel-example-1.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/grouped-key-value-table-panel-example-2.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/object-fields-panel-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/media/development/core/ui-component-framework/stats-panel-example.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/table-panels-family.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/text-panels-family.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/ui-framework-example.png +0 -0
- nautobot/project-static/docs/media/models/virtual_device_context_overview.drawio +73 -0
- nautobot/project-static/docs/media/models/virtual_device_context_overview.png +0 -0
- nautobot/project-static/docs/models/dcim/virtualdevicecontext.html +14 -0
- nautobot/project-static/docs/models/extras/jobqueue.html +14 -0
- nautobot/project-static/docs/models/wireless/radioprofile.html +14 -0
- nautobot/project-static/docs/models/wireless/supporteddatarate.html +14 -0
- nautobot/project-static/docs/models/wireless/wirelessnetwork.html +14 -0
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/overview/application_stack.html +469 -23
- nautobot/project-static/docs/overview/design_philosophy.html +463 -19
- nautobot/project-static/docs/release-notes/index.html +485 -22
- nautobot/project-static/docs/release-notes/version-1.0.html +651 -208
- nautobot/project-static/docs/release-notes/version-1.1.html +648 -205
- nautobot/project-static/docs/release-notes/version-1.2.html +723 -280
- nautobot/project-static/docs/release-notes/version-1.3.html +749 -306
- nautobot/project-static/docs/release-notes/version-1.4.html +834 -392
- nautobot/project-static/docs/release-notes/version-1.5.html +1022 -581
- nautobot/project-static/docs/release-notes/version-1.6.html +942 -518
- nautobot/project-static/docs/release-notes/version-2.0.html +945 -504
- nautobot/project-static/docs/release-notes/version-2.1.html +780 -339
- nautobot/project-static/docs/release-notes/version-2.2.html +773 -332
- nautobot/project-static/docs/release-notes/version-2.3.html +1142 -448
- nautobot/project-static/docs/release-notes/version-2.4.html +10323 -0
- nautobot/project-static/docs/requirements.txt +2 -2
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +342 -270
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +463 -19
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +463 -19
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +463 -19
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +475 -32
- nautobot/project-static/docs/user-guide/administration/configuration/redis.html +463 -19
- nautobot/project-static/docs/user-guide/administration/configuration/settings.html +894 -180
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +463 -19
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +463 -19
- nautobot/project-static/docs/user-guide/administration/guides/docker.html +476 -29
- nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +463 -19
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +463 -19
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +463 -19
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +463 -19
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +463 -19
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +465 -21
- nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +463 -19
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +463 -19
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +463 -19
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +483 -23
- nautobot/project-static/docs/user-guide/administration/installation/index.html +468 -20
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +464 -20
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +463 -19
- nautobot/project-static/docs/user-guide/administration/installation/services.html +463 -19
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +463 -19
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +484 -41
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +477 -66
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +477 -66
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +463 -19
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +463 -19
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +463 -19
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +463 -19
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +463 -19
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +466 -23
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +463 -19
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/tables/v2-code-nautobot-app-location.yaml +0 -16
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +463 -19
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +469 -21
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +499 -20
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +489 -22
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +9375 -0
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +470 -30
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +466 -22
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +463 -19
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +466 -22
- nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +9313 -0
- nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +9217 -0
- nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +9211 -0
- nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +9277 -0
- nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +463 -19
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +463 -19
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +463 -19
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +463 -19
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +463 -19
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +463 -19
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +463 -19
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +463 -19
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +463 -19
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +463 -19
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +463 -19
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +468 -22
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +463 -19
- 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/ip-address-merge-tool.html +463 -19
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +463 -19
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +466 -22
- nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +9444 -0
- nautobot/project-static/docs/user-guide/index.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +466 -22
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +467 -23
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/events.html +9617 -0
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +466 -22
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +472 -23
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +466 -22
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +466 -22
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +9224 -0
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +9722 -0
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +466 -22
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +467 -23
- nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +9292 -0
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +511 -40
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +494 -23
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +466 -22
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +531 -56
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +463 -19
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +463 -19
- nautobot/project-static/img/jinja_logo.svg +97 -0
- nautobot/project-static/js/forms.js +6 -1
- nautobot/project-static/js/nav_menu.js +2 -1
- nautobot/tenancy/api/serializers.py +0 -2
- nautobot/tenancy/api/views.py +9 -13
- nautobot/tenancy/factory.py +1 -1
- nautobot/tenancy/navigation.py +0 -29
- nautobot/tenancy/templates/tenancy/tenant.html +4 -91
- nautobot/tenancy/tests/test_filters.py +29 -134
- nautobot/tenancy/views.py +35 -24
- nautobot/users/admin.py +3 -1
- nautobot/users/api/serializers.py +4 -4
- nautobot/users/api/views.py +3 -3
- nautobot/users/forms.py +19 -0
- nautobot/users/templates/users/preferences.html +22 -0
- nautobot/users/tests/test_filters.py +1 -19
- nautobot/users/tests/test_views.py +57 -0
- nautobot/users/utils.py +8 -0
- nautobot/users/views.py +48 -11
- nautobot/virtualization/api/serializers.py +4 -4
- nautobot/virtualization/api/views.py +5 -24
- nautobot/virtualization/filters.py +1 -2
- nautobot/virtualization/models.py +1 -1
- nautobot/virtualization/navigation.py +0 -48
- nautobot/virtualization/tables.py +2 -2
- nautobot/virtualization/templates/virtualization/cluster_edit.html +1 -7
- nautobot/virtualization/templates/virtualization/clustertype.html +0 -39
- nautobot/virtualization/templates/virtualization/virtualmachine.html +1 -9
- nautobot/virtualization/templates/virtualization/virtualmachine_edit.html +2 -8
- nautobot/virtualization/tests/test_filters.py +57 -166
- nautobot/virtualization/views.py +18 -15
- nautobot/wireless/__init__.py +0 -0
- nautobot/wireless/api/__init__.py +0 -0
- nautobot/wireless/api/serializers.py +44 -0
- nautobot/wireless/api/urls.py +20 -0
- nautobot/wireless/api/views.py +34 -0
- nautobot/wireless/apps.py +8 -0
- nautobot/wireless/choices.py +345 -0
- nautobot/wireless/factory.py +138 -0
- nautobot/wireless/filters.py +167 -0
- nautobot/wireless/forms.py +283 -0
- nautobot/wireless/homepage.py +19 -0
- nautobot/wireless/migrations/0001_initial.py +223 -0
- nautobot/wireless/migrations/__init__.py +0 -0
- nautobot/wireless/models.py +207 -0
- nautobot/wireless/navigation.py +105 -0
- nautobot/wireless/tables.py +244 -0
- nautobot/wireless/templates/wireless/radioprofile_retrieve.html +81 -0
- nautobot/wireless/templates/wireless/supporteddatarate_retrieve.html +26 -0
- nautobot/wireless/templates/wireless/wirelessnetwork_create.html +88 -0
- nautobot/wireless/templates/wireless/wirelessnetwork_retrieve.html +56 -0
- nautobot/wireless/tests/__init__.py +0 -0
- nautobot/wireless/tests/integration/__init__.py +0 -0
- nautobot/wireless/tests/integration/test_radio_profile.py +42 -0
- nautobot/wireless/tests/test_api.py +247 -0
- nautobot/wireless/tests/test_filters.py +82 -0
- nautobot/wireless/tests/test_models.py +22 -0
- nautobot/wireless/tests/test_views.py +378 -0
- nautobot/wireless/urls.py +13 -0
- nautobot/wireless/views.py +119 -0
- {nautobot-2.3.15b1.dist-info → nautobot-2.4.0.dist-info}/METADATA +11 -13
- {nautobot-2.3.15b1.dist-info → nautobot-2.4.0.dist-info}/RECORD +783 -613
- {nautobot-2.3.15b1.dist-info → nautobot-2.4.0.dist-info}/WHEEL +1 -1
- nautobot/core/fixtures/user-data.json +0 -59
- nautobot/core/utils/navigation.py +0 -54
- {nautobot-2.3.15b1.dist-info → nautobot-2.4.0.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.3.15b1.dist-info → nautobot-2.4.0.dist-info}/NOTICE +0 -0
- {nautobot-2.3.15b1.dist-info → nautobot-2.4.0.dist-info}/entry_points.txt +0 -0
nautobot/core/api/serializers.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import contextlib
|
|
2
|
-
from copy import deepcopy
|
|
3
2
|
import logging
|
|
4
3
|
import uuid
|
|
5
4
|
|
|
@@ -18,7 +17,7 @@ from django.db.models.functions import Cast
|
|
|
18
17
|
from django.urls import NoReverseMatch
|
|
19
18
|
from drf_spectacular.types import OpenApiTypes
|
|
20
19
|
from drf_spectacular.utils import extend_schema_field, PolymorphicProxySerializer as _PolymorphicProxySerializer
|
|
21
|
-
from rest_framework import
|
|
20
|
+
from rest_framework import serializers
|
|
22
21
|
from rest_framework.exceptions import PermissionDenied, ValidationError
|
|
23
22
|
from rest_framework.fields import CreateOnlyDefault
|
|
24
23
|
from rest_framework.reverse import reverse
|
|
@@ -31,11 +30,10 @@ from nautobot.core.api.utils import (
|
|
|
31
30
|
dict_to_filter_params,
|
|
32
31
|
nested_serializer_factory,
|
|
33
32
|
)
|
|
34
|
-
from nautobot.core.exceptions import ViewConfigException
|
|
35
33
|
from nautobot.core.models.fields import LaxURLField as LaxURLModelField
|
|
36
34
|
from nautobot.core.models.managers import TagsManager
|
|
37
35
|
from nautobot.core.models.utils import construct_composite_key, construct_natural_slug
|
|
38
|
-
from nautobot.core.
|
|
36
|
+
from nautobot.core.settings_funcs import is_truthy
|
|
39
37
|
from nautobot.core.utils.lookup import get_route_for_model
|
|
40
38
|
from nautobot.core.utils.requests import normalize_querydict
|
|
41
39
|
from nautobot.extras.api.customfields import CustomFieldDefaultValues, CustomFieldsDataField
|
|
@@ -49,8 +47,9 @@ logger = logging.getLogger(__name__)
|
|
|
49
47
|
|
|
50
48
|
class OptInFieldsMixin:
|
|
51
49
|
"""
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
Serializer mixin that adjusts its fields based on the `include` and `exclude_m2m` query parameters in a request.
|
|
51
|
+
|
|
52
|
+
The serializer's `Meta.opt_in_fields` controls which fields are influenced by `include`.
|
|
54
53
|
"""
|
|
55
54
|
|
|
56
55
|
def __init__(self, *args, **kwargs):
|
|
@@ -60,8 +59,11 @@ class OptInFieldsMixin:
|
|
|
60
59
|
@property
|
|
61
60
|
def fields(self):
|
|
62
61
|
"""
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
Dynamically adjust the dictionary of fields attributed to this serializer instance.
|
|
63
|
+
|
|
64
|
+
- Removes all serializer fields specified in `Meta.opt_in_fields` list that aren't specified in the
|
|
65
|
+
`include` query parameter. (applies to GET requests only)
|
|
66
|
+
- If the `exclude_m2m` query parameter is truthy, remove all many-to-many serializer fields for performance.
|
|
65
67
|
|
|
66
68
|
As an example, if the serializer specifies that `opt_in_fields = ["computed_fields"]`
|
|
67
69
|
but `computed_fields` is not specified in the `?include` query parameter, `computed_fields` will be popped
|
|
@@ -69,12 +71,7 @@ class OptInFieldsMixin:
|
|
|
69
71
|
"""
|
|
70
72
|
if self.__pruned_fields is None:
|
|
71
73
|
fields = dict(super().fields)
|
|
72
|
-
serializer_opt_in_fields = getattr(self.Meta, "opt_in_fields",
|
|
73
|
-
|
|
74
|
-
if not serializer_opt_in_fields:
|
|
75
|
-
# This serializer has no defined opt_in_fields, so we never need to go further than this
|
|
76
|
-
self.__pruned_fields = fields
|
|
77
|
-
return self.__pruned_fields
|
|
74
|
+
serializer_opt_in_fields = getattr(self.Meta, "opt_in_fields", [])
|
|
78
75
|
|
|
79
76
|
if not hasattr(self, "_context"):
|
|
80
77
|
# We are being called before a request cycle
|
|
@@ -86,24 +83,29 @@ class OptInFieldsMixin:
|
|
|
86
83
|
# No available request?
|
|
87
84
|
return fields
|
|
88
85
|
|
|
89
|
-
# opt-in fields only applies on GET requests, for other methods we support these fields regardless
|
|
90
|
-
if request is not None and request.method != "GET":
|
|
91
|
-
return fields
|
|
92
|
-
|
|
93
86
|
# NOTE: drf test framework builds a request object where the query
|
|
94
87
|
# parameters are found under the GET attribute.
|
|
95
88
|
params = normalize_querydict(getattr(request, "query_params", getattr(request, "GET", None)))
|
|
96
89
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
90
|
+
# opt-in fields only applies on GET requests, for other methods we support these fields regardless
|
|
91
|
+
if request is None or request.method == "GET":
|
|
92
|
+
try:
|
|
93
|
+
user_opt_in_fields = params.get("include", [])
|
|
94
|
+
except AttributeError:
|
|
95
|
+
# include parameter was not specified
|
|
96
|
+
user_opt_in_fields = []
|
|
97
|
+
|
|
98
|
+
# Drop any fields that are not specified in the users opt in fields
|
|
99
|
+
for field in serializer_opt_in_fields:
|
|
100
|
+
if field not in user_opt_in_fields:
|
|
101
|
+
fields.pop(field, None)
|
|
102
|
+
|
|
103
|
+
# If exclude_m2m is present and truthy, mark any many-to-many fields as write-only so they
|
|
104
|
+
# don't get included in the response.
|
|
105
|
+
if is_truthy(params.get("exclude_m2m", "false")):
|
|
106
|
+
for field_instance in fields.values():
|
|
107
|
+
if isinstance(field_instance, (serializers.ManyRelatedField, serializers.ListSerializer)):
|
|
108
|
+
field_instance.write_only = True
|
|
107
109
|
|
|
108
110
|
self.__pruned_fields = fields
|
|
109
111
|
|
|
@@ -297,21 +299,6 @@ class BaseModelSerializer(OptInFieldsMixin, serializers.HyperlinkedModelSerializ
|
|
|
297
299
|
"""Return whether this is a nested serializer."""
|
|
298
300
|
return getattr(self.Meta, "is_nested", False)
|
|
299
301
|
|
|
300
|
-
@property
|
|
301
|
-
def list_display_fields(self):
|
|
302
|
-
return list(getattr(self.Meta, "list_display_fields", []))
|
|
303
|
-
|
|
304
|
-
@property
|
|
305
|
-
def advanced_tab_fields(self):
|
|
306
|
-
advanced_fields = list(
|
|
307
|
-
getattr(
|
|
308
|
-
self.Meta,
|
|
309
|
-
"advanced_tab_fields",
|
|
310
|
-
["id", "url", "object_type", "created", "last_updated", "natural_slug"],
|
|
311
|
-
)
|
|
312
|
-
)
|
|
313
|
-
return [field for field in advanced_fields if field in self.fields]
|
|
314
|
-
|
|
315
302
|
@extend_schema_field(serializers.CharField)
|
|
316
303
|
def get_display(self, instance):
|
|
317
304
|
"""
|
|
@@ -405,221 +392,6 @@ class BaseModelSerializer(OptInFieldsMixin, serializers.HyperlinkedModelSerializ
|
|
|
405
392
|
fields = [field for field in fields if filter_field(field)]
|
|
406
393
|
return fields
|
|
407
394
|
|
|
408
|
-
def determine_view_options(self, request=None):
|
|
409
|
-
"""
|
|
410
|
-
Determine view options to use for rendering the list and detail views associated with this serializer.
|
|
411
|
-
"""
|
|
412
|
-
list_display = []
|
|
413
|
-
fields = []
|
|
414
|
-
|
|
415
|
-
from nautobot.core.api.metadata import NautobotColumnProcessor # avoid circular import
|
|
416
|
-
|
|
417
|
-
processor = NautobotColumnProcessor(self, request.parser_context if request else {})
|
|
418
|
-
field_map = dict(self.fields)
|
|
419
|
-
all_fields = list(field_map)
|
|
420
|
-
|
|
421
|
-
# Explicitly order the "big ugly" fields to the bottom
|
|
422
|
-
processor.order_fields(all_fields)
|
|
423
|
-
list_display_fields = self.list_display_fields
|
|
424
|
-
|
|
425
|
-
# Process the list_display_fields first.
|
|
426
|
-
for field_name in list_display_fields:
|
|
427
|
-
try:
|
|
428
|
-
field = field_map[field_name]
|
|
429
|
-
except KeyError:
|
|
430
|
-
continue # Ignore unknown fields.
|
|
431
|
-
column_data = processor._get_column_properties(field, field_name)
|
|
432
|
-
list_display.append(column_data)
|
|
433
|
-
fields.append(column_data)
|
|
434
|
-
|
|
435
|
-
# Process the rest of the fields second.
|
|
436
|
-
for field_name in all_fields:
|
|
437
|
-
# Don't process list display fields twice.
|
|
438
|
-
if field_name in list_display_fields:
|
|
439
|
-
continue
|
|
440
|
-
try:
|
|
441
|
-
field = field_map[field_name]
|
|
442
|
-
except KeyError:
|
|
443
|
-
continue # Ignore unknown fields.
|
|
444
|
-
column_data = processor._get_column_properties(field, field_name)
|
|
445
|
-
fields.append(column_data)
|
|
446
|
-
|
|
447
|
-
return {
|
|
448
|
-
"retrieve": {
|
|
449
|
-
"tabs": self._determine_detail_view_tabs(),
|
|
450
|
-
},
|
|
451
|
-
"list": {
|
|
452
|
-
"default_fields": list_display,
|
|
453
|
-
"all_fields": fields,
|
|
454
|
-
},
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
def _determine_detail_view_tabs(self):
|
|
458
|
-
"""Determine the layout for the detail view tabs that are intrinsic to this serializer."""
|
|
459
|
-
tabs = self.get_additional_detail_view_tabs()
|
|
460
|
-
|
|
461
|
-
if hasattr(self.Meta, "detail_view_config"):
|
|
462
|
-
detail_view_config = self._validate_view_config(self.Meta.detail_view_config)
|
|
463
|
-
else:
|
|
464
|
-
detail_view_config = self._get_default_detail_view_config()
|
|
465
|
-
detail_view_config = self._refine_detail_view_config(detail_view_config, tabs)
|
|
466
|
-
|
|
467
|
-
return {
|
|
468
|
-
bettertitle(self.Meta.model._meta.verbose_name): detail_view_config,
|
|
469
|
-
**tabs,
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
def get_additional_detail_view_tabs(self):
|
|
473
|
-
"""
|
|
474
|
-
Retrieve definitions of non-default detail view tabs.
|
|
475
|
-
|
|
476
|
-
By default provides an "Advanced" tab containing `self.advanced_tab_fields`, but subclasses
|
|
477
|
-
can override this to move additional serializer fields to this or other tabs.
|
|
478
|
-
|
|
479
|
-
Returns:
|
|
480
|
-
(dict): `{<tab label>: [{<panel label>: {"fields": [<list of fields>]}, ...}, ...], ...}`
|
|
481
|
-
"""
|
|
482
|
-
return {
|
|
483
|
-
"Advanced": [{"Object Details": {"fields": self.advanced_tab_fields}}],
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
def _get_default_detail_view_config(self):
|
|
487
|
-
"""
|
|
488
|
-
Generate detail view config for the view based on the serializer's fields.
|
|
489
|
-
|
|
490
|
-
Examples:
|
|
491
|
-
>>> DeviceSerializer._get_default_detail_view_config().
|
|
492
|
-
{
|
|
493
|
-
"layout":[
|
|
494
|
-
{
|
|
495
|
-
Device: {
|
|
496
|
-
"fields": ["name", "subdevice_role", "height", "comments"...]
|
|
497
|
-
}
|
|
498
|
-
},
|
|
499
|
-
{
|
|
500
|
-
Tags: {
|
|
501
|
-
"fields": ["tags"]
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
]
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
Returns:
|
|
508
|
-
(list): A list representing the view config.
|
|
509
|
-
"""
|
|
510
|
-
m2m_fields, other_fields = self._get_m2m_and_non_m2m_fields()
|
|
511
|
-
# TODO(timizuo): How do we get verbose_name of not model serializers?
|
|
512
|
-
model_verbose_name = self.Meta.model._meta.verbose_name
|
|
513
|
-
return {
|
|
514
|
-
"layout": [
|
|
515
|
-
{
|
|
516
|
-
bettertitle(model_verbose_name): {
|
|
517
|
-
"fields": [field["name"] for field in other_fields],
|
|
518
|
-
}
|
|
519
|
-
},
|
|
520
|
-
{field["label"]: {"fields": [field["name"]]} for field in m2m_fields},
|
|
521
|
-
]
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
def _get_m2m_and_non_m2m_fields(self):
|
|
525
|
-
"""
|
|
526
|
-
Retrieve the many-to-many (m2m) fields and other non-m2m fields from the serializer.
|
|
527
|
-
|
|
528
|
-
Returns:
|
|
529
|
-
A tuple containing two lists: m2m_fields and non m2m fields.
|
|
530
|
-
- m2m_fields: A list of dictionaries, each containing the name and label of an m2m field.
|
|
531
|
-
- non_m2m_fields: A list of dictionaries, each containing the name and label of a non m2m field.
|
|
532
|
-
"""
|
|
533
|
-
m2m_fields = []
|
|
534
|
-
non_m2m_fields = []
|
|
535
|
-
|
|
536
|
-
for field_name, field in self.fields.items():
|
|
537
|
-
if isinstance(field, drf_relations.ManyRelatedField):
|
|
538
|
-
m2m_fields.append({"name": field_name, "label": field.label or field_name})
|
|
539
|
-
else:
|
|
540
|
-
non_m2m_fields.append({"name": field_name, "label": field.label or field_name})
|
|
541
|
-
|
|
542
|
-
return m2m_fields, non_m2m_fields
|
|
543
|
-
|
|
544
|
-
def _refine_detail_view_config(self, detail_view_config, other_tabs):
|
|
545
|
-
"""
|
|
546
|
-
Refine the detail view config for the default tab (auto-generated, or as defined by Meta.detail_view_config).
|
|
547
|
-
|
|
548
|
-
- Remove fields that should never be present in the detail view config (e.g. `notes_url`).
|
|
549
|
-
- Ensure that fields that are already present in `other_tabs` aren't included in the detail view config.
|
|
550
|
-
- Ensure that certain fields such as `tags` are always included in the detail view config if applicable.
|
|
551
|
-
|
|
552
|
-
Args:
|
|
553
|
-
detail_view_config (dict): `{"layout": [{<left-column>}, {<right-column}], "include_others": False}`
|
|
554
|
-
|
|
555
|
-
Returns:
|
|
556
|
-
(list): `[{"Panel 1 Name": {"fields": ["field1", "field2", ...]}, "Panel 2 Name": ...}, {...}]`
|
|
557
|
-
"""
|
|
558
|
-
fields_to_always_move_to_right_column = [
|
|
559
|
-
"comments",
|
|
560
|
-
"tags",
|
|
561
|
-
]
|
|
562
|
-
fields_to_always_remove = [
|
|
563
|
-
# always handled explicitly by the UI
|
|
564
|
-
"display",
|
|
565
|
-
"status",
|
|
566
|
-
# not yet supported in the UI
|
|
567
|
-
"custom_fields",
|
|
568
|
-
"relationships",
|
|
569
|
-
"computed_fields",
|
|
570
|
-
# irrelevant to the UI
|
|
571
|
-
"notes_url",
|
|
572
|
-
]
|
|
573
|
-
fields_to_remove = fields_to_always_remove + fields_to_always_move_to_right_column
|
|
574
|
-
# Any field that's already present in another tab
|
|
575
|
-
for tab_layout in other_tabs.values():
|
|
576
|
-
for column in tab_layout:
|
|
577
|
-
for grouping in column.values():
|
|
578
|
-
fields_to_remove += grouping["fields"]
|
|
579
|
-
|
|
580
|
-
# Make a deepcopy to avoid altering view_config
|
|
581
|
-
view_config_layout = deepcopy(detail_view_config.get("layout"))
|
|
582
|
-
|
|
583
|
-
# Remove fields_to_remove from the view_config_layout
|
|
584
|
-
for column in view_config_layout:
|
|
585
|
-
for section in column.values():
|
|
586
|
-
for field in fields_to_remove:
|
|
587
|
-
if field in section["fields"]:
|
|
588
|
-
section["fields"].remove(field)
|
|
589
|
-
|
|
590
|
-
serializer_fields = list(self.fields)
|
|
591
|
-
|
|
592
|
-
# Add special-cased fields to right column
|
|
593
|
-
for field in fields_to_always_move_to_right_column:
|
|
594
|
-
if field in serializer_fields:
|
|
595
|
-
if len(view_config_layout) < 2:
|
|
596
|
-
view_config_layout.append({})
|
|
597
|
-
view_config_layout[1].setdefault(bettertitle(field), {}).setdefault("fields", []).append(field)
|
|
598
|
-
|
|
599
|
-
# Add fields not otherwise included in another tab, only if include_others is set to True.
|
|
600
|
-
if detail_view_config.get("include_others", False):
|
|
601
|
-
view_config_fields = [
|
|
602
|
-
field for column in view_config_layout for section in column.values() for field in section["fields"]
|
|
603
|
-
]
|
|
604
|
-
missing_fields = sorted(set(serializer_fields) - set(view_config_fields) - set(fields_to_remove))
|
|
605
|
-
view_config_layout[0]["Other Fields"] = {"fields": missing_fields}
|
|
606
|
-
|
|
607
|
-
return view_config_layout
|
|
608
|
-
|
|
609
|
-
def _validate_view_config(self, view_config):
|
|
610
|
-
"""Validate view config."""
|
|
611
|
-
# 1. Validate key `layout` is in view_config; as this is a required key is creating a view config
|
|
612
|
-
if not view_config["layout"]:
|
|
613
|
-
raise ViewConfigException("`layout` is a required key in creating a custom view_config")
|
|
614
|
-
|
|
615
|
-
# 2. Validate `Other Fields` is not part of a layout group name, as this is a reserved keyword for group names
|
|
616
|
-
for col in view_config["layout"]:
|
|
617
|
-
for group_name in col.keys():
|
|
618
|
-
if group_name in constants.RESERVED_NAMES_FOR_OBJECT_DETAIL_VIEW_SCHEMA:
|
|
619
|
-
raise ViewConfigException(f"`{group_name}` is a reserved group name keyword.")
|
|
620
|
-
|
|
621
|
-
return view_config
|
|
622
|
-
|
|
623
395
|
def build_field(self, field_name, info, model_class, nested_depth):
|
|
624
396
|
"""
|
|
625
397
|
Return a two tuple of (cls, kwargs) to build a serializer field with.
|
|
@@ -759,27 +531,27 @@ class ValidatedModelSerializer(BaseModelSerializer):
|
|
|
759
531
|
validation. (DRF does not do this by default; see https://github.com/encode/django-rest-framework/issues/3144)
|
|
760
532
|
"""
|
|
761
533
|
|
|
762
|
-
def validate(self,
|
|
534
|
+
def validate(self, attrs):
|
|
763
535
|
# Remove custom fields data and tags (if any) prior to model validation
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
536
|
+
local_attrs = attrs.copy()
|
|
537
|
+
local_attrs.pop("custom_fields", None)
|
|
538
|
+
local_attrs.pop("relationships", None)
|
|
539
|
+
local_attrs.pop("tags", None)
|
|
768
540
|
|
|
769
541
|
# Skip ManyToManyFields
|
|
770
542
|
for field in self.Meta.model._meta.get_fields():
|
|
771
543
|
if isinstance(field, models.ManyToManyField):
|
|
772
|
-
|
|
544
|
+
local_attrs.pop(field.name, None)
|
|
773
545
|
|
|
774
546
|
# Run clean() on an instance of the model
|
|
775
547
|
if self.instance is None:
|
|
776
|
-
instance = self.Meta.model(**
|
|
548
|
+
instance = self.Meta.model(**local_attrs)
|
|
777
549
|
else:
|
|
778
550
|
instance = self.instance
|
|
779
|
-
for k, v in
|
|
551
|
+
for k, v in local_attrs.items():
|
|
780
552
|
setattr(instance, k, v)
|
|
781
553
|
instance.full_clean()
|
|
782
|
-
return
|
|
554
|
+
return attrs
|
|
783
555
|
|
|
784
556
|
|
|
785
557
|
class WritableNestedSerializer(BaseModelSerializer):
|
|
@@ -825,7 +597,7 @@ class WritableNestedSerializer(BaseModelSerializer):
|
|
|
825
597
|
pk = None
|
|
826
598
|
|
|
827
599
|
if isinstance(self.Meta.model._meta.pk, models.AutoField):
|
|
828
|
-
# PK is an int for this model. This is usually the
|
|
600
|
+
# PK is an int for this model. This is usually the Group or Content-Type model
|
|
829
601
|
try:
|
|
830
602
|
pk = int(data)
|
|
831
603
|
except (TypeError, ValueError):
|
|
@@ -1106,3 +878,17 @@ class NautobotModelSerializer(
|
|
|
1106
878
|
|
|
1107
879
|
Can also be used for models derived from BaseModel, so long as they support custom fields, notes, and relationships.
|
|
1108
880
|
"""
|
|
881
|
+
|
|
882
|
+
|
|
883
|
+
#
|
|
884
|
+
# Tools
|
|
885
|
+
#
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
class RenderJinjaSerializer(serializers.Serializer): # pylint: disable=abstract-method
|
|
889
|
+
"""Serializer for RenderJinjaView."""
|
|
890
|
+
|
|
891
|
+
template_code = serializers.CharField(required=True)
|
|
892
|
+
context = serializers.DictField(default=dict)
|
|
893
|
+
rendered_template = serializers.CharField(read_only=True)
|
|
894
|
+
rendered_template_lines = serializers.ListField(read_only=True, child=serializers.CharField())
|
nautobot/core/api/urls.py
CHANGED
|
@@ -11,11 +11,10 @@ from nautobot.core.api.views import (
|
|
|
11
11
|
CSVImportFieldsForContentTypeAPIView,
|
|
12
12
|
GetFilterSetFieldDOMElementAPIView,
|
|
13
13
|
GetFilterSetFieldLookupExpressionChoicesAPIView,
|
|
14
|
-
GetMenuAPIView,
|
|
15
|
-
GetObjectCountsView,
|
|
16
14
|
GraphQLDRFAPIView,
|
|
17
15
|
NautobotSpectacularRedocView,
|
|
18
16
|
NautobotSpectacularSwaggerView,
|
|
17
|
+
RenderJinjaView,
|
|
19
18
|
SettingsJSONSchemaView,
|
|
20
19
|
StatusView,
|
|
21
20
|
)
|
|
@@ -33,12 +32,11 @@ core_api_patterns = [
|
|
|
33
32
|
GetFilterSetFieldDOMElementAPIView.as_view(),
|
|
34
33
|
name="filtersetfield-retrieve-lookupvaluedomelement",
|
|
35
34
|
),
|
|
35
|
+
path("render-jinja-template/", RenderJinjaView.as_view(), name="render_jinja_template"),
|
|
36
36
|
]
|
|
37
37
|
ui_api_patterns = [
|
|
38
38
|
# Lookup Expr
|
|
39
39
|
path("core/", include((core_api_patterns, "core-api"))),
|
|
40
|
-
path("get-menu/", GetMenuAPIView.as_view(), name="get-menu"),
|
|
41
|
-
path("get-object-counts/", GetObjectCountsView.as_view(), name="get-object-counts"),
|
|
42
40
|
]
|
|
43
41
|
|
|
44
42
|
urlpatterns = [
|
|
@@ -52,6 +50,7 @@ urlpatterns = [
|
|
|
52
50
|
path("tenancy/", include("nautobot.tenancy.api.urls")),
|
|
53
51
|
path("users/", include("nautobot.users.api.urls")),
|
|
54
52
|
path("virtualization/", include("nautobot.virtualization.api.urls")),
|
|
53
|
+
path("wireless/", include("nautobot.wireless.api.urls")),
|
|
55
54
|
path("status/", StatusView.as_view(), name="api-status"),
|
|
56
55
|
path("docs/", NautobotSpectacularSwaggerView.as_view(url_name="schema"), name="api_docs"),
|
|
57
56
|
path("redoc/", NautobotSpectacularRedocView.as_view(url_name="schema"), name="api_redocs"),
|
nautobot/core/api/utils.py
CHANGED
|
@@ -221,68 +221,6 @@ def rest_api_server_error(request, *args, **kwargs):
|
|
|
221
221
|
return JsonResponse(data, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
|
222
222
|
|
|
223
223
|
|
|
224
|
-
# TODO: This is part of the drf-react-template work towards auto-generating create/edit form UI from the REST API.
|
|
225
|
-
def format_output(field, field_value):
|
|
226
|
-
"""TODO: docstring required."""
|
|
227
|
-
data = {
|
|
228
|
-
"field_name": field, # Form field placeholder
|
|
229
|
-
"type": "others", # Param type e.g select field, char field, datetime field etc.
|
|
230
|
-
"choices": [], # Param choices for select fields
|
|
231
|
-
"help_text": None, # Form field placeholder
|
|
232
|
-
"label": None, # Form field placeholder
|
|
233
|
-
"required": False, # Form field placeholder
|
|
234
|
-
}
|
|
235
|
-
# TODO: fix these local imports if at all possible
|
|
236
|
-
from rest_framework.fields import CharField, IntegerField
|
|
237
|
-
from rest_framework.serializers import ListSerializer
|
|
238
|
-
|
|
239
|
-
from nautobot.core.api import ChoiceField, WritableNestedSerializer
|
|
240
|
-
|
|
241
|
-
kwargs = {}
|
|
242
|
-
if isinstance(field_value, (WritableNestedSerializer, ListSerializer)):
|
|
243
|
-
kwargs = {
|
|
244
|
-
"type": "dynamic-choice-field",
|
|
245
|
-
}
|
|
246
|
-
extra_kwargs = {}
|
|
247
|
-
|
|
248
|
-
if isinstance(field_value, WritableNestedSerializer):
|
|
249
|
-
extra_kwargs = {
|
|
250
|
-
"label": getattr(field_value, "label", None) or field,
|
|
251
|
-
"required": field_value.required,
|
|
252
|
-
"help_text": field_value.help_text,
|
|
253
|
-
}
|
|
254
|
-
elif isinstance(field_value, ListSerializer):
|
|
255
|
-
extra_kwargs = {
|
|
256
|
-
"label": "Tags",
|
|
257
|
-
"required": False,
|
|
258
|
-
}
|
|
259
|
-
kwargs.update(extra_kwargs)
|
|
260
|
-
elif isinstance(field_value, ChoiceField):
|
|
261
|
-
kwargs = {
|
|
262
|
-
"type": "choice-field",
|
|
263
|
-
"label": getattr(field_value, "label", None) or field,
|
|
264
|
-
"required": field_value.required,
|
|
265
|
-
"help_text": field_value.help_text,
|
|
266
|
-
"choices": field_value.choices.items(),
|
|
267
|
-
}
|
|
268
|
-
elif isinstance(field_value, CharField):
|
|
269
|
-
kwargs = {
|
|
270
|
-
"type": "char-field",
|
|
271
|
-
"label": getattr(field_value, "label", None) or field,
|
|
272
|
-
"required": field_value.required,
|
|
273
|
-
"help_text": field_value.help_text,
|
|
274
|
-
}
|
|
275
|
-
elif isinstance(field_value, IntegerField):
|
|
276
|
-
kwargs = {
|
|
277
|
-
"type": "integer-field",
|
|
278
|
-
"label": getattr(field_value, "label", None) or field,
|
|
279
|
-
"required": field_value.required,
|
|
280
|
-
"help_text": field_value.help_text,
|
|
281
|
-
}
|
|
282
|
-
data.update(kwargs)
|
|
283
|
-
return data
|
|
284
|
-
|
|
285
|
-
|
|
286
224
|
def get_relation_info_for_nested_serializers(model_class, related_model, field_name):
|
|
287
225
|
"""Get the DRF RelationInfo object needed for build_nested_field()"""
|
|
288
226
|
relation_info = RelationInfo(
|