nautobot 2.3.16__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 +140 -23
- nautobot/cloud/api/views.py +6 -10
- nautobot/cloud/factory.py +4 -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/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 +45 -259
- nautobot/core/api/urls.py +3 -4
- nautobot/core/api/utils.py +0 -62
- nautobot/core/api/views.py +99 -157
- nautobot/core/apps/__init__.py +22 -578
- nautobot/core/celery/__init__.py +13 -0
- nautobot/core/celery/schedulers.py +47 -2
- 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/forms/__init__.py +19 -19
- nautobot/core/forms/fields.py +57 -9
- nautobot/core/forms/forms.py +33 -2
- nautobot/core/forms/utils.py +2 -1
- nautobot/core/graphql/schema.py +3 -1
- nautobot/core/jobs/__init__.py +24 -3
- nautobot/core/jobs/bulk_actions.py +248 -0
- nautobot/core/jobs/cleanup.py +1 -1
- nautobot/core/management/commands/generate_test_data.py +21 -0
- nautobot/core/middleware.py +16 -0
- nautobot/core/models/fields.py +11 -7
- nautobot/core/settings.py +68 -4
- nautobot/core/settings.yaml +99 -0
- nautobot/core/tables.py +10 -46
- 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/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 +13 -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 +41 -35
- nautobot/core/testing/forms.py +2 -0
- nautobot/core/testing/views.py +65 -148
- nautobot/core/tests/integration/test_view_authentication.py +1 -1
- nautobot/core/tests/nautobot_config.py +198 -0
- nautobot/core/tests/runner.py +2 -2
- 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 +124 -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 +6 -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 +37 -140
- nautobot/core/views/mixins.py +82 -32
- 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 +34 -141
- 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 +219 -9
- 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/devices.py +180 -2
- nautobot/dcim/models/racks.py +2 -2
- nautobot/dcim/navigation.py +25 -224
- nautobot/dcim/signals.py +44 -0
- nautobot/dcim/tables/__init__.py +2 -0
- nautobot/dcim/tables/devices.py +103 -7
- 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 +171 -76
- nautobot/dcim/tests/test_jobs.py +118 -0
- nautobot/dcim/tests/test_models.py +157 -6
- 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 +356 -61
- nautobot/extras/api/serializers.py +39 -18
- nautobot/extras/api/urls.py +4 -0
- nautobot/extras/api/views.py +89 -31
- 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 +2 -2
- nautobot/extras/graphql/types.py +25 -1
- nautobot/extras/jobs.py +109 -15
- 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/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/groups.py +0 -2
- nautobot/extras/models/jobs.py +233 -33
- 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 +103 -60
- nautobot/extras/registry.py +1 -1
- nautobot/extras/secrets/__init__.py +2 -2
- nautobot/extras/signals.py +39 -1
- nautobot/extras/tables.py +37 -1
- 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/singleton.py +16 -0
- nautobot/extras/tests/test_api.py +145 -43
- nautobot/extras/tests/test_context_managers.py +4 -1
- nautobot/extras/tests/test_filters.py +213 -529
- nautobot/extras/tests/test_job_variables.py +73 -152
- nautobot/extras/tests/test_jobs.py +181 -51
- nautobot/extras/tests/test_models.py +61 -6
- nautobot/extras/tests/test_plugins.py +62 -9
- nautobot/extras/tests/test_relationships.py +123 -9
- nautobot/extras/tests/test_utils.py +23 -2
- nautobot/extras/tests/test_views.py +146 -145
- nautobot/extras/tests/test_webhooks.py +2 -1
- nautobot/extras/urls.py +2 -20
- nautobot/extras/utils.py +119 -4
- nautobot/extras/views.py +168 -125
- nautobot/extras/webhooks.py +5 -2
- nautobot/ipam/api/serializers.py +10 -103
- nautobot/ipam/api/views.py +31 -49
- 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/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 +7 -5
- nautobot/ipam/tests/test_filters.py +39 -119
- nautobot/ipam/tests/test_forms.py +0 -2
- nautobot/ipam/tests/test_models.py +56 -36
- 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 +461 -17
- nautobot/project-static/docs/apps/index.html +461 -17
- nautobot/project-static/docs/apps/nautobot-apps.html +462 -19
- nautobot/project-static/docs/assets/_mkdocstrings.css +25 -1
- nautobot/project-static/docs/assets/extra.css +5 -1
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +477 -23
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +474 -20
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +790 -289
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +505 -31
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +510 -34
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +471 -20
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +467 -18
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +497 -33
- nautobot/project-static/docs/code-reference/nautobot/apps/events.html +9883 -0
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +523 -75
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +546 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +670 -94
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +1030 -177
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +524 -49
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +874 -188
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +955 -235
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +475 -21
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +486 -28
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +661 -99
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +947 -479
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +6425 -1234
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +474 -20
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +877 -344
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +828 -171
- nautobot/project-static/docs/development/apps/api/configuration-view.html +461 -17
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +461 -17
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +461 -17
- nautobot/project-static/docs/development/apps/api/models/global-search.html +461 -17
- nautobot/project-static/docs/development/apps/api/models/graphql.html +461 -17
- nautobot/project-static/docs/development/apps/api/models/index.html +461 -17
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +461 -17
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +461 -17
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +461 -17
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +461 -17
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +461 -17
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +461 -17
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +461 -17
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +461 -17
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +461 -17
- nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +461 -17
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +461 -17
- nautobot/project-static/docs/development/apps/api/prometheus.html +461 -17
- nautobot/project-static/docs/development/apps/api/setup.html +465 -153
- nautobot/project-static/docs/development/apps/api/testing.html +461 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +461 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +461 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +461 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +461 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +741 -128
- nautobot/project-static/docs/development/apps/api/views/base-template.html +461 -17
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +461 -17
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +461 -17
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +461 -17
- nautobot/project-static/docs/development/apps/api/views/index.html +463 -18
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +465 -17
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +491 -17
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +461 -17
- nautobot/project-static/docs/development/apps/api/views/notes.html +461 -17
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +467 -19
- nautobot/project-static/docs/development/apps/api/views/urls.html +461 -17
- nautobot/project-static/docs/development/apps/index.html +461 -17
- nautobot/project-static/docs/development/apps/migration/code-updates.html +462 -50
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +462 -18
- nautobot/project-static/docs/development/apps/migration/from-v1.html +461 -17
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +461 -17
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +461 -17
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +461 -17
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +464 -20
- 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 +464 -20
- nautobot/project-static/docs/development/core/application-registry.html +461 -17
- nautobot/project-static/docs/development/core/best-practices.html +461 -17
- nautobot/project-static/docs/development/core/bootstrap-ui.html +461 -17
- nautobot/project-static/docs/development/core/caching.html +461 -17
- nautobot/project-static/docs/development/core/controllers.html +463 -17
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +464 -20
- nautobot/project-static/docs/development/core/generic-views.html +461 -17
- nautobot/project-static/docs/development/core/getting-started.html +539 -127
- nautobot/project-static/docs/development/core/homepage.html +472 -28
- nautobot/project-static/docs/development/core/index.html +461 -17
- nautobot/project-static/docs/development/core/minikube-dev-environment-for-k8s-jobs.html +9754 -0
- nautobot/project-static/docs/development/core/model-checklist.html +471 -25
- nautobot/project-static/docs/development/core/model-features.html +461 -17
- nautobot/project-static/docs/development/core/natural-keys.html +461 -17
- nautobot/project-static/docs/development/core/navigation-menu.html +478 -24
- nautobot/project-static/docs/development/core/release-checklist.html +478 -46
- nautobot/project-static/docs/development/core/role-internals.html +461 -17
- nautobot/project-static/docs/development/core/settings.html +461 -17
- nautobot/project-static/docs/development/core/style-guide.html +464 -20
- nautobot/project-static/docs/development/core/templates.html +471 -20
- nautobot/project-static/docs/development/core/testing.html +461 -17
- nautobot/project-static/docs/development/core/ui-component-framework.html +11116 -0
- nautobot/project-static/docs/development/core/user-preferences.html +464 -20
- nautobot/project-static/docs/development/index.html +461 -17
- nautobot/project-static/docs/development/jobs/index.html +499 -19
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +461 -17
- nautobot/project-static/docs/index.html +469 -36
- 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 +467 -21
- nautobot/project-static/docs/overview/design_philosophy.html +461 -17
- nautobot/project-static/docs/release-notes/index.html +483 -20
- nautobot/project-static/docs/release-notes/version-1.0.html +649 -206
- nautobot/project-static/docs/release-notes/version-1.1.html +646 -203
- nautobot/project-static/docs/release-notes/version-1.2.html +721 -278
- nautobot/project-static/docs/release-notes/version-1.3.html +747 -304
- nautobot/project-static/docs/release-notes/version-1.4.html +832 -390
- nautobot/project-static/docs/release-notes/version-1.5.html +1020 -579
- nautobot/project-static/docs/release-notes/version-1.6.html +940 -516
- nautobot/project-static/docs/release-notes/version-2.0.html +943 -502
- nautobot/project-static/docs/release-notes/version-2.1.html +778 -337
- nautobot/project-static/docs/release-notes/version-2.2.html +771 -330
- nautobot/project-static/docs/release-notes/version-2.3.html +914 -471
- nautobot/project-static/docs/release-notes/version-2.4.html +10323 -0
- 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 +461 -17
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +461 -17
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +461 -17
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +473 -30
- nautobot/project-static/docs/user-guide/administration/configuration/redis.html +461 -17
- nautobot/project-static/docs/user-guide/administration/configuration/settings.html +842 -155
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +461 -17
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +461 -17
- nautobot/project-static/docs/user-guide/administration/guides/docker.html +474 -27
- nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +461 -17
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +461 -17
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +461 -17
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +461 -17
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +461 -17
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +463 -19
- nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +461 -17
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +461 -17
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +461 -17
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +481 -21
- nautobot/project-static/docs/user-guide/administration/installation/index.html +466 -18
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +462 -18
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +461 -17
- nautobot/project-static/docs/user-guide/administration/installation/services.html +461 -17
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +461 -17
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +482 -39
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +475 -64
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +475 -64
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +461 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +461 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +461 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +461 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +461 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +464 -21
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +461 -17
- 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 +461 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +467 -19
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +497 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +487 -20
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +461 -17
- 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 +468 -28
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +464 -20
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +464 -20
- 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 +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +466 -20
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +461 -17
- 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 +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +464 -20
- nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +9444 -0
- nautobot/project-static/docs/user-guide/index.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +464 -20
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +465 -21
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/events.html +9617 -0
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +464 -20
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +470 -21
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +464 -20
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +464 -20
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +461 -17
- 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 +464 -20
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +465 -21
- 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 +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +509 -38
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +492 -21
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +464 -20
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +529 -54
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +461 -17
- 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 +2 -0
- nautobot/users/api/views.py +2 -2
- 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/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.16.dist-info → nautobot-2.4.0.dist-info}/METADATA +9 -12
- {nautobot-2.3.16.dist-info → nautobot-2.4.0.dist-info}/RECORD +720 -549
- nautobot/core/utils/navigation.py +0 -54
- {nautobot-2.3.16.dist-info → nautobot-2.4.0.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.3.16.dist-info → nautobot-2.4.0.dist-info}/NOTICE +0 -0
- {nautobot-2.3.16.dist-info → nautobot-2.4.0.dist-info}/WHEEL +0 -0
- {nautobot-2.3.16.dist-info → nautobot-2.4.0.dist-info}/entry_points.txt +0 -0
nautobot/core/api/pagination.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from rest_framework.pagination import LimitOffsetPagination
|
|
2
2
|
|
|
3
|
+
from nautobot.core.constants import MAX_PAGE_SIZE_DEFAULT, PAGINATE_COUNT_DEFAULT
|
|
3
4
|
from nautobot.core.utils.config import get_settings_or_config
|
|
4
5
|
|
|
5
6
|
|
|
@@ -38,7 +39,7 @@ class OptionalLimitOffsetPagination(LimitOffsetPagination):
|
|
|
38
39
|
if limit < 0:
|
|
39
40
|
raise ValueError()
|
|
40
41
|
# Enforce maximum page size, if defined
|
|
41
|
-
max_page_size = get_settings_or_config("MAX_PAGE_SIZE")
|
|
42
|
+
max_page_size = get_settings_or_config("MAX_PAGE_SIZE", fallback=MAX_PAGE_SIZE_DEFAULT)
|
|
42
43
|
if max_page_size:
|
|
43
44
|
if limit == 0:
|
|
44
45
|
return max_page_size
|
|
@@ -48,7 +49,7 @@ class OptionalLimitOffsetPagination(LimitOffsetPagination):
|
|
|
48
49
|
except (KeyError, ValueError):
|
|
49
50
|
pass
|
|
50
51
|
|
|
51
|
-
return get_settings_or_config("PAGINATE_COUNT")
|
|
52
|
+
return get_settings_or_config("PAGINATE_COUNT", fallback=PAGINATE_COUNT_DEFAULT)
|
|
52
53
|
|
|
53
54
|
def get_next_link(self):
|
|
54
55
|
# Pagination has been disabled
|
nautobot/core/api/renderers.py
CHANGED
|
@@ -156,6 +156,9 @@ class NautobotCSVRenderer(BaseRenderer):
|
|
|
156
156
|
# value = [v["composite_key"] for v in value]
|
|
157
157
|
else:
|
|
158
158
|
value = [v["id"] for v in value]
|
|
159
|
+
if value and isinstance(value[0], dict) and ("value" in value[0]) and ("label" in value[0]):
|
|
160
|
+
# Multiple enum types
|
|
161
|
+
value = [v["value"] for v in value]
|
|
159
162
|
# The below makes for better UX than `json.dump()` for most current cases.
|
|
160
163
|
value = ",".join([str(v) if v is not None else "" for v in value])
|
|
161
164
|
elif not isinstance(value, (str, int)):
|
nautobot/core/api/schema.py
CHANGED
|
@@ -112,13 +112,13 @@ class NautobotAutoSchema(AutoSchema):
|
|
|
112
112
|
"required": True,
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
# Inject a custom description for the "id" parameter since ours has custom lookup behavior.
|
|
116
115
|
if operation is not None and "parameters" in operation:
|
|
117
116
|
for param in operation["parameters"]:
|
|
117
|
+
# Inject a custom description for the "id" parameter since ours has custom lookup behavior.
|
|
118
118
|
if param["name"] == "id" and "description" not in param:
|
|
119
119
|
param["description"] = "Unique object identifier, either a UUID primary key or a composite key."
|
|
120
120
|
if self.method == "GET":
|
|
121
|
-
if "depth"
|
|
121
|
+
if not any(param["name"] == "depth" for param in operation["parameters"]):
|
|
122
122
|
operation["parameters"].append(
|
|
123
123
|
{
|
|
124
124
|
"in": "query",
|
|
@@ -128,6 +128,17 @@ class NautobotAutoSchema(AutoSchema):
|
|
|
128
128
|
"schema": {"type": "integer", "minimum": 0, "maximum": 10, "default": 1},
|
|
129
129
|
}
|
|
130
130
|
)
|
|
131
|
+
if not any(param["name"] == "exclude_m2m" for param in operation["parameters"]):
|
|
132
|
+
operation["parameters"].append(
|
|
133
|
+
{
|
|
134
|
+
"in": "query",
|
|
135
|
+
"name": "exclude_m2m",
|
|
136
|
+
"required": False,
|
|
137
|
+
"description": "Exclude many-to-many fields from the response",
|
|
138
|
+
"schema": {"type": "boolean", "default": False},
|
|
139
|
+
}
|
|
140
|
+
)
|
|
141
|
+
# TODO: add "include" parameter to the schema where relevant - nautobot/nautobot#685
|
|
131
142
|
return operation
|
|
132
143
|
|
|
133
144
|
def get_operation_id(self):
|
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.
|
|
@@ -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(
|