nautobot 2.0.4__py3-none-any.whl → 2.1.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of nautobot might be problematic. Click here for more details.
- nautobot/circuits/navigation.py +0 -25
- nautobot/circuits/templates/circuits/circuit_retrieve.html +0 -9
- nautobot/circuits/templates/circuits/providernetwork_retrieve.html +0 -2
- nautobot/circuits/tests/test_api.py +79 -2
- nautobot/circuits/tests/test_filters.py +1 -0
- nautobot/core/api/serializers.py +15 -5
- nautobot/core/api/views.py +18 -19
- nautobot/core/choices.py +1 -1
- nautobot/core/filters.py +12 -4
- nautobot/core/jobs/__init__.py +125 -3
- nautobot/core/management/commands/generate_test_data.py +6 -1
- nautobot/core/middleware.py +12 -4
- nautobot/core/models/fields.py +12 -2
- nautobot/core/settings.py +9 -8
- nautobot/core/tables.py +26 -31
- nautobot/core/templates/base_django.html +2 -2
- nautobot/core/templates/buttons/export.html +57 -30
- nautobot/core/templates/generic/object_list.html +2 -2
- nautobot/core/templates/generic/object_retrieve.html +8 -1
- nautobot/core/templates/home.html +5 -5
- nautobot/core/templates/inc/created_updated.html +2 -2
- nautobot/core/templates/inc/footer.html +2 -2
- nautobot/core/templates/inc/javascript.html +0 -10
- nautobot/core/templates/inc/media.html +2 -0
- nautobot/core/templates/inc/nav_menu.html +66 -68
- nautobot/core/templates/inc/object_details_advanced_panel.html +19 -0
- nautobot/core/templates/nautobot_config.py.j2 +10 -4
- nautobot/core/templates/panel_table.html +1 -1
- nautobot/core/templates/template.css +89 -0
- nautobot/core/templates/utilities/templatetags/table_config_form.html +1 -0
- nautobot/core/templatetags/buttons.py +7 -2
- nautobot/core/templatetags/helpers.py +9 -9
- nautobot/core/testing/views.py +34 -4
- nautobot/core/tests/integration/test_home.py +1 -43
- nautobot/core/tests/integration/test_navbar.py +10 -64
- nautobot/core/tests/integration/test_plugin_home.py +4 -5
- nautobot/core/tests/integration/test_plugin_navbar.py +20 -16
- nautobot/core/tests/integration/test_theme.py +4 -0
- nautobot/core/tests/test_api.py +14 -66
- nautobot/core/tests/test_filters.py +127 -0
- nautobot/core/tests/test_forms.py +4 -4
- nautobot/core/tests/test_graphql.py +165 -2
- nautobot/core/tests/test_jobs.py +112 -0
- nautobot/core/tests/test_openapi.py +6 -0
- nautobot/core/tests/test_utils.py +23 -20
- nautobot/core/tests/test_views.py +11 -85
- nautobot/core/urls.py +6 -1
- nautobot/core/utils/data.py +5 -1
- nautobot/core/utils/filtering.py +6 -4
- nautobot/core/utils/lookup.py +28 -0
- nautobot/core/utils/requests.py +2 -3
- nautobot/core/views/__init__.py +3 -4
- nautobot/core/views/generic.py +15 -11
- nautobot/core/views/mixins.py +9 -8
- nautobot/core/views/renderers.py +5 -0
- nautobot/core/views/utils.py +23 -24
- nautobot/dcim/api/serializers.py +8 -4
- nautobot/dcim/models/device_components.py +1 -0
- nautobot/dcim/models/devices.py +7 -6
- nautobot/dcim/navigation.py +10 -165
- nautobot/dcim/templates/dcim/location.html +1 -1
- nautobot/dcim/tests/features/locations.feature +143 -0
- nautobot/dcim/tests/test_api.py +8 -1
- nautobot/dcim/tests/test_filters.py +11 -3
- nautobot/dcim/views.py +5 -6
- nautobot/extras/admin.py +1 -1
- nautobot/extras/api/serializers.py +33 -0
- nautobot/extras/api/urls.py +6 -0
- nautobot/extras/api/views.py +45 -6
- nautobot/extras/context_managers.py +34 -8
- nautobot/extras/factory.py +28 -2
- nautobot/extras/filters/__init__.py +52 -0
- nautobot/extras/filters/mixins.py +4 -29
- nautobot/extras/forms/forms.py +43 -0
- nautobot/extras/jobs.py +39 -17
- nautobot/extras/migrations/0100_fileproxy_job_result.py +32 -0
- nautobot/extras/migrations/0101_externalintegration.py +61 -0
- nautobot/extras/migrations/0102_set_null_objectchange_contenttype.py +32 -0
- nautobot/extras/models/__init__.py +2 -0
- nautobot/extras/models/change_logging.py +2 -2
- nautobot/extras/models/customfields.py +2 -2
- nautobot/extras/models/models.py +101 -18
- nautobot/extras/models/relationships.py +13 -8
- nautobot/extras/navigation.py +17 -29
- nautobot/extras/signals.py +80 -59
- nautobot/extras/tables.py +28 -2
- nautobot/extras/templates/extras/externalintegration_retrieve.html +37 -0
- nautobot/extras/templates/extras/inc/jobresult.html +24 -0
- nautobot/extras/templates/extras/jobresult.html +24 -0
- nautobot/extras/templatetags/computed_fields.py +6 -13
- nautobot/extras/templatetags/custom_links.py +19 -12
- nautobot/extras/templatetags/job_buttons.py +34 -19
- nautobot/extras/templatetags/plugins.py +1 -1
- nautobot/extras/test_jobs/file_output.py +16 -0
- nautobot/extras/tests/test_api.py +92 -0
- nautobot/extras/tests/test_context_managers.py +94 -4
- nautobot/extras/tests/test_customfields.py +1 -1
- nautobot/extras/tests/test_filters.py +64 -2
- nautobot/extras/tests/test_jobs.py +75 -22
- nautobot/extras/tests/test_models.py +34 -0
- nautobot/extras/tests/test_relationships.py +2 -2
- nautobot/extras/tests/test_views.py +204 -4
- nautobot/extras/tests/test_webhooks.py +61 -25
- nautobot/extras/urls.py +1 -0
- nautobot/extras/views.py +27 -13
- nautobot/extras/webhooks.py +16 -25
- nautobot/ipam/fields.py +5 -0
- nautobot/ipam/forms.py +16 -0
- nautobot/ipam/models.py +13 -2
- nautobot/ipam/navigation.py +2 -59
- nautobot/ipam/tables.py +1 -1
- nautobot/ipam/templates/ipam/ipaddress.html +0 -9
- nautobot/ipam/templates/ipam/prefix.html +0 -9
- nautobot/ipam/tests/features/prefixes.feature +134 -0
- nautobot/ipam/tests/test_filters.py +5 -10
- nautobot/ipam/tests/test_models.py +7 -0
- nautobot/ipam/tests/test_views.py +8 -1
- nautobot/ipam/views.py +99 -58
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css +191 -191
- 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 +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 +874 -881
- 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 +138 -99
- nautobot/project-static/css/dark.css +65 -6
- nautobot/project-static/docs/404.html +45 -17
- nautobot/project-static/docs/apps/index.html +45 -17
- nautobot/project-static/docs/apps/nautobot-apps.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +1598 -1458
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +229 -152
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +46 -18
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +354 -433
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +67 -39
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +2083 -2234
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +1389 -1247
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +129 -111
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +3601 -3457
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +320 -284
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +3863 -3801
- nautobot/project-static/docs/development/apps/api/configuration-view.html +45 -17
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +45 -17
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +45 -17
- nautobot/project-static/docs/development/apps/api/models/global-search.html +45 -17
- nautobot/project-static/docs/development/apps/api/models/graphql.html +45 -17
- nautobot/project-static/docs/development/apps/api/models/index.html +45 -17
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +45 -17
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +45 -17
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +45 -17
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +45 -17
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +45 -17
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +45 -17
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +45 -17
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +45 -17
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +45 -17
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +45 -17
- nautobot/project-static/docs/development/apps/api/prometheus.html +45 -17
- nautobot/project-static/docs/development/apps/api/setup.html +45 -17
- nautobot/project-static/docs/development/apps/api/testing.html +45 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +45 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +45 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +45 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +45 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-detail-views.html +45 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/tabs.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/base-template.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/index.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/notes.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/urls.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/view-overrides.html +45 -17
- nautobot/project-static/docs/development/apps/index.html +45 -17
- nautobot/project-static/docs/development/apps/migration/code-updates.html +45 -17
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +45 -17
- nautobot/project-static/docs/development/apps/migration/from-v1.html +45 -17
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +45 -17
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +45 -17
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +45 -17
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +45 -17
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +45 -17
- nautobot/project-static/docs/development/core/application-registry.html +45 -17
- nautobot/project-static/docs/development/core/best-practices.html +45 -17
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +45 -17
- nautobot/project-static/docs/development/core/extending-models.html +45 -17
- nautobot/project-static/docs/development/core/generic-views.html +45 -17
- nautobot/project-static/docs/development/core/getting-started.html +45 -17
- nautobot/project-static/docs/development/core/homepage.html +45 -17
- nautobot/project-static/docs/development/core/index.html +45 -17
- nautobot/project-static/docs/development/core/model-features.html +45 -17
- nautobot/project-static/docs/development/core/natural-keys.html +45 -17
- nautobot/project-static/docs/development/core/navigation-menu.html +45 -22
- nautobot/project-static/docs/development/core/react-ui.html +45 -17
- nautobot/project-static/docs/development/core/release-checklist.html +46 -18
- nautobot/project-static/docs/development/core/role-internals.html +45 -17
- nautobot/project-static/docs/development/core/style-guide.html +45 -17
- nautobot/project-static/docs/development/core/templates.html +45 -17
- nautobot/project-static/docs/development/core/testing.html +45 -17
- nautobot/project-static/docs/development/core/user-preferences.html +45 -17
- nautobot/project-static/docs/development/index.html +45 -17
- nautobot/project-static/docs/development/jobs/index.html +281 -235
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +45 -17
- nautobot/project-static/docs/index.html +45 -17
- nautobot/project-static/docs/media/nautobot_application_stack_low_level.png +0 -0
- nautobot/project-static/docs/media/nautobot_application_stack_low_level.txt +1 -0
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/release-notes/index.html +48 -20
- nautobot/project-static/docs/release-notes/version-1.0.html +45 -17
- nautobot/project-static/docs/release-notes/version-1.1.html +45 -17
- nautobot/project-static/docs/release-notes/version-1.2.html +45 -17
- nautobot/project-static/docs/release-notes/version-1.3.html +45 -17
- nautobot/project-static/docs/release-notes/version-1.4.html +45 -17
- nautobot/project-static/docs/release-notes/version-1.5.html +45 -17
- nautobot/project-static/docs/release-notes/version-1.6.html +46 -18
- nautobot/project-static/docs/release-notes/version-2.0.html +372 -199
- nautobot/project-static/docs/release-notes/version-2.1.html +5724 -0
- nautobot/project-static/docs/requirements.txt +1 -1
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +247 -237
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +45 -17
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +45 -17
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +45 -17
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +45 -17
- nautobot/project-static/docs/user-guide/administration/configuration/node-configuration.html +45 -17
- nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +110 -44
- nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +45 -17
- nautobot/project-static/docs/user-guide/administration/guides/caching.html +48 -20
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +45 -17
- nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +45 -17
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +45 -17
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +45 -17
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +45 -17
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +49 -20
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +45 -17
- nautobot/project-static/docs/user-guide/administration/installation/docker.html +45 -17
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +45 -17
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +45 -17
- nautobot/project-static/docs/user-guide/administration/installation/index.html +45 -17
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +45 -17
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +45 -17
- nautobot/project-static/docs/user-guide/administration/installation/selinux-troubleshooting.html +45 -17
- nautobot/project-static/docs/user-guide/administration/installation/services.html +45 -17
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +45 -17
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +45 -17
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +45 -17
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +45 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +45 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +45 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +45 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +45 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +45 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +45 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +45 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +45 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +45 -17
- nautobot/project-static/docs/user-guide/index.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +111 -17
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +48 -20
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +5359 -0
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +48 -20
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +114 -45
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +45 -17
- nautobot/project-static/fonts/UFL.txt +96 -0
- nautobot/project-static/fonts/Ubuntu-Bold.woff2 +0 -0
- nautobot/project-static/fonts/Ubuntu-BoldItalic.woff2 +0 -0
- nautobot/project-static/fonts/Ubuntu-Italic.woff2 +0 -0
- nautobot/project-static/fonts/Ubuntu-Medium.woff2 +0 -0
- nautobot/project-static/fonts/Ubuntu-MediumItalic.woff2 +0 -0
- nautobot/project-static/fonts/Ubuntu-Regular.woff2 +0 -0
- nautobot/project-static/fonts/UbuntuMono-Bold.woff2 +0 -0
- nautobot/project-static/fonts/UbuntuMono-BoldItalic.woff2 +0 -0
- nautobot/project-static/fonts/UbuntuMono-Italic.woff2 +0 -0
- nautobot/project-static/fonts/UbuntuMono-Regular.woff2 +0 -0
- nautobot/project-static/img/dark-theme.png +0 -0
- nautobot/project-static/img/light-theme.png +0 -0
- nautobot/project-static/img/nautobot_chevron.svg +5 -0
- nautobot/project-static/img/nautobot_chevron_header.svg +5 -0
- nautobot/project-static/img/system-theme.png +0 -0
- nautobot/tenancy/navigation.py +0 -13
- nautobot/ui/package-lock.json +2 -2
- nautobot/ui/package.json +1 -1
- nautobot/users/admin.py +44 -0
- nautobot/users/migrations/0007_alter_objectpermission_object_types.py +33 -0
- nautobot/users/models.py +3 -2
- nautobot/virtualization/navigation.py +1 -33
- nautobot/virtualization/tests/test_api.py +1 -1
- nautobot/virtualization/tests/test_filters.py +1 -1
- {nautobot-2.0.4.dist-info → nautobot-2.1.0b1.dist-info}/METADATA +2 -2
- {nautobot-2.0.4.dist-info → nautobot-2.1.0b1.dist-info}/RECORD +405 -786
- CHANGELOG.md +0 -3
- CONTRIBUTING.md +0 -3
- NOTICE +0 -8
- nautobot/docs/apps/index.md +0 -22
- nautobot/docs/apps/nautobot-apps.md +0 -10
- nautobot/docs/assets/app-icons/icon-ChatOps.png +0 -0
- nautobot/docs/assets/app-icons/icon-DataValidationEngine.png +0 -0
- nautobot/docs/assets/app-icons/icon-DeviceLifecycle.png +0 -0
- nautobot/docs/assets/app-icons/icon-DeviceOnboarding.png +0 -0
- nautobot/docs/assets/app-icons/icon-FirewallModels.png +0 -0
- nautobot/docs/assets/app-icons/icon-GoldenConfiguration.png +0 -0
- nautobot/docs/assets/app-icons/icon-NautobotPluginNornir.png +0 -0
- nautobot/docs/assets/app-icons/icon-SSoT.png +0 -0
- nautobot/docs/assets/extra.css +0 -139
- nautobot/docs/assets/favicon.ico +0 -0
- nautobot/docs/assets/nautobot_logo.png +0 -0
- nautobot/docs/assets/nautobot_logo.svg +0 -131
- nautobot/docs/assets/networktocode_bw.png +0 -0
- nautobot/docs/assets/overrides/partials/copyright.html +0 -20
- nautobot/docs/development/apps/api/configuration-view.md +0 -35
- nautobot/docs/development/apps/api/database-backend-config.md +0 -26
- nautobot/docs/development/apps/api/models/django-admin.md +0 -20
- nautobot/docs/development/apps/api/models/global-search.md +0 -11
- nautobot/docs/development/apps/api/models/graphql.md +0 -97
- nautobot/docs/development/apps/api/models/index.md +0 -81
- nautobot/docs/development/apps/api/nautobot-app-config.md +0 -84
- nautobot/docs/development/apps/api/platform-features/custom-validators.md +0 -30
- nautobot/docs/development/apps/api/platform-features/filter-extensions.md +0 -49
- nautobot/docs/development/apps/api/platform-features/git-repository-content.md +0 -62
- nautobot/docs/development/apps/api/platform-features/index.md +0 -1
- nautobot/docs/development/apps/api/platform-features/jinja2-filters.md +0 -28
- nautobot/docs/development/apps/api/platform-features/jobs.md +0 -29
- nautobot/docs/development/apps/api/platform-features/populating-extensibility-features.md +0 -58
- nautobot/docs/development/apps/api/platform-features/secrets-providers.md +0 -64
- nautobot/docs/development/apps/api/platform-features/uniquely-identify-objects.md +0 -63
- nautobot/docs/development/apps/api/prometheus.md +0 -25
- nautobot/docs/development/apps/api/setup.md +0 -132
- nautobot/docs/development/apps/api/testing.md +0 -55
- nautobot/docs/development/apps/api/ui-extensions/banners.md +0 -26
- nautobot/docs/development/apps/api/ui-extensions/home-page.md +0 -9
- nautobot/docs/development/apps/api/ui-extensions/index.md +0 -1
- nautobot/docs/development/apps/api/ui-extensions/navigation.md +0 -15
- nautobot/docs/development/apps/api/ui-extensions/object-detail-views.md +0 -74
- nautobot/docs/development/apps/api/ui-extensions/tabs.md +0 -52
- nautobot/docs/development/apps/api/views/base-template.md +0 -38
- nautobot/docs/development/apps/api/views/core-view-overrides.md +0 -26
- nautobot/docs/development/apps/api/views/django-generic-views.md +0 -23
- nautobot/docs/development/apps/api/views/help-documentation.md +0 -16
- nautobot/docs/development/apps/api/views/index.md +0 -3
- nautobot/docs/development/apps/api/views/nautobot-generic-views.md +0 -35
- nautobot/docs/development/apps/api/views/nautobotuiviewset.md +0 -147
- nautobot/docs/development/apps/api/views/nautobotuiviewsetrouter.md +0 -41
- nautobot/docs/development/apps/api/views/notes.md +0 -25
- nautobot/docs/development/apps/api/views/rest-api.md +0 -64
- nautobot/docs/development/apps/api/views/urls.md +0 -26
- nautobot/docs/development/apps/api/views/view-overrides.md +0 -50
- nautobot/docs/development/apps/index.md +0 -75
- nautobot/docs/development/apps/migration/code-updates.md +0 -160
- nautobot/docs/development/apps/migration/dependency-updates.md +0 -13
- nautobot/docs/development/apps/migration/from-v1.md +0 -56
- nautobot/docs/development/apps/migration/model-updates/dcim.md +0 -285
- nautobot/docs/development/apps/migration/model-updates/extras.md +0 -30
- nautobot/docs/development/apps/migration/model-updates/global.md +0 -5
- nautobot/docs/development/apps/migration/model-updates/ipam.md +0 -22
- nautobot/docs/development/apps/porting-from-netbox.md +0 -23
- nautobot/docs/development/core/application-registry.md +0 -216
- nautobot/docs/development/core/best-practices.md +0 -469
- nautobot/docs/development/core/docker-compose-advanced-use-cases.md +0 -228
- nautobot/docs/development/core/extending-models.md +0 -93
- nautobot/docs/development/core/generic-views.md +0 -65
- nautobot/docs/development/core/getting-started.md +0 -859
- nautobot/docs/development/core/homepage.md +0 -63
- nautobot/docs/development/core/index.md +0 -334
- nautobot/docs/development/core/model-features.md +0 -44
- nautobot/docs/development/core/natural-keys.md +0 -121
- nautobot/docs/development/core/navigation-menu.md +0 -142
- nautobot/docs/development/core/react-ui.md +0 -137
- nautobot/docs/development/core/release-checklist.md +0 -312
- nautobot/docs/development/core/role-internals.md +0 -28
- nautobot/docs/development/core/style-guide.md +0 -200
- nautobot/docs/development/core/templates.md +0 -101
- nautobot/docs/development/core/testing.md +0 -238
- nautobot/docs/development/core/user-preferences.md +0 -11
- nautobot/docs/development/index.md +0 -1
- nautobot/docs/development/jobs/index.md +0 -835
- nautobot/docs/development/jobs/migration/from-v1.md +0 -160
- nautobot/docs/generate_code_reference_pages.py +0 -20
- nautobot/docs/img/edge_dev_circuit_relationship.png +0 -0
- nautobot/docs/img/leaf_dev_no_circuit_relationship.png +0 -0
- nautobot/docs/img/relationship_w_json_filter.png +0 -0
- nautobot/docs/index.md +0 -105
- nautobot/docs/media/admin_ui_run_permission.png +0 -0
- nautobot/docs/media/development/homepage_changelog_panel.png +0 -0
- nautobot/docs/media/development/homepage_dcim_panel.png +0 -0
- nautobot/docs/media/development/index_bug_wf.jpg +0 -0
- nautobot/docs/media/development/index_feature_request_wf.jpg +0 -0
- nautobot/docs/media/development/index_release_cadence.drawio +0 -90
- nautobot/docs/media/development/index_release_cadence.jpg +0 -0
- nautobot/docs/media/installation/nautobot_ui_admin.png +0 -0
- nautobot/docs/media/installation/nautobot_ui_guest.png +0 -0
- nautobot/docs/media/models/dcim_cable_trace.png +0 -0
- nautobot/docs/media/models/dcim_cable_trace_circuit.png +0 -0
- nautobot/docs/media/models/dynamicgroup_filtering_01.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_1_01.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_1_02.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_1_03.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_1_04.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_1_05.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_01.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_02.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_03.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_04.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_05.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_06.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_07.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_basic_01.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_basic_02.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_basic_03.png +0 -0
- nautobot/docs/media/models/jobbutton_form.png +0 -0
- nautobot/docs/media/models/site_jobbuttons.png +0 -0
- nautobot/docs/media/nautobot_application_stack_high_level.drawio +0 -1
- nautobot/docs/media/nautobot_application_stack_high_level.png +0 -0
- nautobot/docs/media/nautobot_application_stack_low_level.drawio +0 -1
- nautobot/docs/media/nautobot_application_stack_low_level.png +0 -0
- nautobot/docs/media/nautobot_chatops.gif +0 -0
- nautobot/docs/media/nautobot_config_context.gif +0 -0
- nautobot/docs/media/nautobot_golden_config.gif +0 -0
- nautobot/docs/media/nautobot_graphql.gif +0 -0
- nautobot/docs/media/nautobot_mainpage.gif +0 -0
- nautobot/docs/media/nautobot_prefix_hierarchy.gif +0 -0
- nautobot/docs/media/plugins/plugin_admin_config.png +0 -0
- nautobot/docs/media/plugins/plugin_admin_ui.png +0 -0
- nautobot/docs/media/plugins/plugin_rest_api_endpoint.png +0 -0
- nautobot/docs/media/power_distribution.png +0 -0
- nautobot/docs/media/ss_config_contexts.png +0 -0
- nautobot/docs/media/ss_graphiql.png +0 -0
- nautobot/docs/media/ss_main_page.png +0 -0
- nautobot/docs/media/ss_plugin_chatops.png +0 -0
- nautobot/docs/media/ss_plugin_golden_config.png +0 -0
- nautobot/docs/media/ss_prefix_hierarchy.png +0 -0
- nautobot/docs/media/user-guide/administration/guides/s3-django-storage/user-guide-s3-1.png +0 -0
- nautobot/docs/media/user-guide/administration/guides/s3-django-storage/user-guide-s3-2.png +0 -0
- nautobot/docs/media/user-guide/administration/upgrading/from-v1/ipam/tenant-affinity.png +0 -0
- nautobot/docs/nautobot_logo.png +0 -0
- nautobot/docs/nautobot_logo.svg +0 -131
- nautobot/docs/release-notes/index.md +0 -3
- nautobot/docs/release-notes/version-1.0.md +0 -530
- nautobot/docs/release-notes/version-1.1.md +0 -337
- nautobot/docs/release-notes/version-1.2.md +0 -509
- nautobot/docs/release-notes/version-1.3.md +0 -554
- nautobot/docs/release-notes/version-1.4.md +0 -677
- nautobot/docs/release-notes/version-1.5.md +0 -840
- nautobot/docs/release-notes/version-1.6.md +0 -290
- nautobot/docs/release-notes/version-2.0.md +0 -1359
- nautobot/docs/requirements.txt +0 -12
- nautobot/docs/user-guide/administration/configuration/authentication/ldap.md +0 -286
- nautobot/docs/user-guide/administration/configuration/authentication/remote.md +0 -46
- nautobot/docs/user-guide/administration/configuration/authentication/sso.md +0 -528
- nautobot/docs/user-guide/administration/configuration/index.md +0 -190
- nautobot/docs/user-guide/administration/configuration/node-configuration.md +0 -31
- nautobot/docs/user-guide/administration/configuration/optional-settings.md +0 -1302
- nautobot/docs/user-guide/administration/configuration/required-settings.md +0 -244
- nautobot/docs/user-guide/administration/guides/caching.md +0 -108
- nautobot/docs/user-guide/administration/guides/celery-queues.md +0 -42
- nautobot/docs/user-guide/administration/guides/healthcheck.md +0 -11
- nautobot/docs/user-guide/administration/guides/permissions.md +0 -98
- nautobot/docs/user-guide/administration/guides/prometheus-metrics.md +0 -55
- nautobot/docs/user-guide/administration/guides/replicating-nautobot.md +0 -70
- nautobot/docs/user-guide/administration/guides/s3-django-storage.md +0 -145
- nautobot/docs/user-guide/administration/installation/app-install.md +0 -94
- nautobot/docs/user-guide/administration/installation/docker.md +0 -286
- nautobot/docs/user-guide/administration/installation/external-authentication.md +0 -9
- nautobot/docs/user-guide/administration/installation/http-server.md +0 -279
- nautobot/docs/user-guide/administration/installation/index.md +0 -101
- nautobot/docs/user-guide/administration/installation/install_system.md +0 -493
- nautobot/docs/user-guide/administration/installation/nautobot.md +0 -367
- nautobot/docs/user-guide/administration/installation/selinux-troubleshooting.md +0 -194
- nautobot/docs/user-guide/administration/installation/services.md +0 -340
- nautobot/docs/user-guide/administration/migration/migrating-from-netbox.md +0 -336
- nautobot/docs/user-guide/administration/migration/migrating-from-postgresql.md +0 -122
- nautobot/docs/user-guide/administration/tools/nautobot-server.md +0 -858
- nautobot/docs/user-guide/administration/tools/nautobot-shell.md +0 -263
- nautobot/docs/user-guide/administration/upgrading/database-backup.md +0 -11
- nautobot/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.md +0 -55
- nautobot/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.md +0 -73
- nautobot/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.md +0 -211
- nautobot/docs/user-guide/administration/upgrading/from-v1/ipam/index.md +0 -16
- nautobot/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.md +0 -157
- nautobot/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.md +0 -153
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-api-behavior-changes.yaml +0 -82
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-api-removed-fields.yaml +0 -175
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-api-renamed-fields.yaml +0 -124
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-code-location-changes.yaml +0 -241
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-code-removals.yaml +0 -57
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-code-renames.yaml +0 -5
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-database-behavior-changes.yaml +0 -76
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-database-removed-fields.yaml +0 -202
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-database-renamed-fields.yaml +0 -343
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-filters-corrected-fields.yaml +0 -31
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-filters-enhanced-fields.yaml +0 -244
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-filters-removed-fields.yaml +0 -595
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-filters-renamed-fields.yaml +0 -253
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-logging-renamed-loggers.yaml +0 -23
- nautobot/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.md +0 -574
- nautobot/docs/user-guide/administration/upgrading/upgrading.md +0 -127
- nautobot/docs/user-guide/core-data-model/circuits/circuit.md +0 -19
- nautobot/docs/user-guide/core-data-model/circuits/circuittermination.md +0 -10
- nautobot/docs/user-guide/core-data-model/circuits/circuittype.md +0 -8
- nautobot/docs/user-guide/core-data-model/circuits/provider.md +0 -5
- nautobot/docs/user-guide/core-data-model/circuits/providernetwork.md +0 -7
- nautobot/docs/user-guide/core-data-model/dcim/cable.md +0 -43
- nautobot/docs/user-guide/core-data-model/dcim/consoleport.md +0 -8
- nautobot/docs/user-guide/core-data-model/dcim/consoleporttemplate.md +0 -6
- nautobot/docs/user-guide/core-data-model/dcim/consoleserverport.md +0 -8
- nautobot/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.md +0 -6
- nautobot/docs/user-guide/core-data-model/dcim/device.md +0 -29
- nautobot/docs/user-guide/core-data-model/dcim/devicebay.md +0 -11
- nautobot/docs/user-guide/core-data-model/dcim/devicebaytemplate.md +0 -6
- nautobot/docs/user-guide/core-data-model/dcim/deviceredundancygroup.md +0 -279
- nautobot/docs/user-guide/core-data-model/dcim/devicetype.md +0 -44
- nautobot/docs/user-guide/core-data-model/dcim/frontport.md +0 -6
- nautobot/docs/user-guide/core-data-model/dcim/frontporttemplate.md +0 -6
- nautobot/docs/user-guide/core-data-model/dcim/interface.md +0 -34
- nautobot/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.md +0 -24
- nautobot/docs/user-guide/core-data-model/dcim/interfacetemplate.md +0 -6
- nautobot/docs/user-guide/core-data-model/dcim/inventoryitem.md +0 -10
- nautobot/docs/user-guide/core-data-model/dcim/location.md +0 -15
- nautobot/docs/user-guide/core-data-model/dcim/locationtype.md +0 -43
- nautobot/docs/user-guide/core-data-model/dcim/manufacturer.md +0 -3
- nautobot/docs/user-guide/core-data-model/dcim/platform.md +0 -19
- nautobot/docs/user-guide/core-data-model/dcim/powerfeed.md +0 -25
- nautobot/docs/user-guide/core-data-model/dcim/poweroutlet.md +0 -14
- nautobot/docs/user-guide/core-data-model/dcim/poweroutlettemplate.md +0 -6
- nautobot/docs/user-guide/core-data-model/dcim/powerpanel.md +0 -12
- nautobot/docs/user-guide/core-data-model/dcim/powerport.md +0 -15
- nautobot/docs/user-guide/core-data-model/dcim/powerporttemplate.md +0 -6
- nautobot/docs/user-guide/core-data-model/dcim/rack.md +0 -41
- nautobot/docs/user-guide/core-data-model/dcim/rackgroup.md +0 -7
- nautobot/docs/user-guide/core-data-model/dcim/rackreservation.md +0 -3
- nautobot/docs/user-guide/core-data-model/dcim/rearport.md +0 -9
- nautobot/docs/user-guide/core-data-model/dcim/rearporttemplate.md +0 -6
- nautobot/docs/user-guide/core-data-model/dcim/virtualchassis.md +0 -8
- nautobot/docs/user-guide/core-data-model/extras/configcontext.md +0 -78
- nautobot/docs/user-guide/core-data-model/extras/configcontextschema.md +0 -73
- nautobot/docs/user-guide/core-data-model/ipam/ipaddress.md +0 -69
- nautobot/docs/user-guide/core-data-model/ipam/media/ipam_namespace_documentation.drawio +0 -1
- nautobot/docs/user-guide/core-data-model/ipam/media/ipam_namespace_documentation.drawio.svg +0 -4
- nautobot/docs/user-guide/core-data-model/ipam/namespace.md +0 -18
- nautobot/docs/user-guide/core-data-model/ipam/prefix.md +0 -65
- nautobot/docs/user-guide/core-data-model/ipam/rir.md +0 -10
- nautobot/docs/user-guide/core-data-model/ipam/routetarget.md +0 -5
- nautobot/docs/user-guide/core-data-model/ipam/service.md +0 -8
- nautobot/docs/user-guide/core-data-model/ipam/vlan.md +0 -17
- nautobot/docs/user-guide/core-data-model/ipam/vlangroup.md +0 -5
- nautobot/docs/user-guide/core-data-model/ipam/vrf.md +0 -15
- nautobot/docs/user-guide/core-data-model/tenancy/tenant.md +0 -20
- nautobot/docs/user-guide/core-data-model/tenancy/tenantgroup.md +0 -5
- nautobot/docs/user-guide/core-data-model/virtualization/cluster.md +0 -5
- nautobot/docs/user-guide/core-data-model/virtualization/clustergroup.md +0 -3
- nautobot/docs/user-guide/core-data-model/virtualization/clustertype.md +0 -3
- nautobot/docs/user-guide/core-data-model/virtualization/virtualmachine.md +0 -17
- nautobot/docs/user-guide/core-data-model/virtualization/vminterface.md +0 -19
- nautobot/docs/user-guide/feature-guides/custom-fields.md +0 -350
- nautobot/docs/user-guide/feature-guides/getting-started/creating-devices.md +0 -130
- nautobot/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.md +0 -113
- nautobot/docs/user-guide/feature-guides/getting-started/index.md +0 -29
- nautobot/docs/user-guide/feature-guides/getting-started/interfaces.md +0 -100
- nautobot/docs/user-guide/feature-guides/getting-started/ipam.md +0 -104
- nautobot/docs/user-guide/feature-guides/getting-started/platforms.md +0 -78
- nautobot/docs/user-guide/feature-guides/getting-started/search-bar.md +0 -40
- nautobot/docs/user-guide/feature-guides/getting-started/tenants.md +0 -40
- nautobot/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.md +0 -87
- nautobot/docs/user-guide/feature-guides/git-data-source.md +0 -307
- nautobot/docs/user-guide/feature-guides/graphql.md +0 -342
- nautobot/docs/user-guide/feature-guides/images/custom-fields/custom_field_choices.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/custom-fields/custom_field_detail_grouped.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/custom-fields/custom_field_detail_label.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/custom-fields/custom_field_edit.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/custom-fields/custom_field_select.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/1-create-location-type.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/10-add-platform.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/11-platforms-page.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/12-add-tenant.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/13-assign-tenant-to-device.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/14-assign-tenant-to-device-2.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/15-create-device-type.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/16-interface-templates.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/17-templated-interfaces.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/18-assign-device-type.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/19-edit-ints-for-lag.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/2-create-manufacturer.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/20-ints-int-lag.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/21-device-type.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/22-create-vlans.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/23-create-vlans-2.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/24-vlan-main-page.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/25-add-vlan-to-interface.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/26-add-vlan-to-interface-2.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/27-add-rir.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/3-create-role.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/30-add-prefix.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/32-add-ip-addr.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/33-assign-address.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/34-assign-address-2.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/35-assign-address-3.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/36-verify-address.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/37-verify-prefix.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/38-verify-prefix2.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/39-address-search.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/4-create-device-type.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/40-addr-main-page.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/41-device-search-results.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/42-address-search-v2.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/43-get-to-device-main-page.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/44-add-platform.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/5-create-device.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/6-create-location.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/7-location-type-page.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/8-location-page.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/01-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/02-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/03-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/04-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/05-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/06-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/07-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/08-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/09-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/10-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/11-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/12-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/13-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/14-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/15-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/16-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/17-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/18-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/00-graphiql.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/01-graphiql-explorer.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/02-graphiql-explorer-device-query.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/03-graphiql-explorer-device-attributes.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/04-graphql-query-01.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/05-graphiql-autocomplete.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/06-graphql-query-02.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/07-graphql-query-03.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/08-graphql-query-04.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/09-graphql-query-05.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/10-graphql-swagger.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/11-graphql-query-06.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/ip_merge_button.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/merge_button.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/merge_view.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/no_more_dup_ips.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/skip_button.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/unselect_ips.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/01-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/02-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/03-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/04-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/05-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/06-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/07-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/08-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/09-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/10-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/11-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/ip-address-merge-tool.md +0 -63
- nautobot/docs/user-guide/feature-guides/relationships.md +0 -125
- nautobot/docs/user-guide/index.md +0 -1
- nautobot/docs/user-guide/platform-functionality/change-logging.md +0 -21
- nautobot/docs/user-guide/platform-functionality/computedfield.md +0 -89
- nautobot/docs/user-guide/platform-functionality/customfield.md +0 -123
- nautobot/docs/user-guide/platform-functionality/customlink.md +0 -59
- nautobot/docs/user-guide/platform-functionality/dynamicgroup.md +0 -660
- nautobot/docs/user-guide/platform-functionality/exporttemplate.md +0 -55
- nautobot/docs/user-guide/platform-functionality/gitrepository.md +0 -353
- nautobot/docs/user-guide/platform-functionality/graphql.md +0 -259
- nautobot/docs/user-guide/platform-functionality/graphqlquery.md +0 -28
- nautobot/docs/user-guide/platform-functionality/imageattachment.md +0 -10
- nautobot/docs/user-guide/platform-functionality/jobs/index.md +0 -193
- nautobot/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.md +0 -78
- nautobot/docs/user-guide/platform-functionality/jobs/jobbutton.md +0 -79
- nautobot/docs/user-guide/platform-functionality/jobs/jobhook.md +0 -15
- nautobot/docs/user-guide/platform-functionality/jobs/models.md +0 -65
- nautobot/docs/user-guide/platform-functionality/napalm.md +0 -85
- nautobot/docs/user-guide/platform-functionality/note.md +0 -7
- nautobot/docs/user-guide/platform-functionality/relationship.md +0 -158
- nautobot/docs/user-guide/platform-functionality/rest-api/authentication.md +0 -67
- nautobot/docs/user-guide/platform-functionality/rest-api/filtering.md +0 -142
- nautobot/docs/user-guide/platform-functionality/rest-api/overview.md +0 -1045
- nautobot/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.md +0 -9
- nautobot/docs/user-guide/platform-functionality/role.md +0 -17
- nautobot/docs/user-guide/platform-functionality/secret.md +0 -136
- nautobot/docs/user-guide/platform-functionality/status.md +0 -92
- nautobot/docs/user-guide/platform-functionality/tag.md +0 -62
- nautobot/docs/user-guide/platform-functionality/template-filters.md +0 -306
- nautobot/docs/user-guide/platform-functionality/users/objectpermission.md +0 -56
- nautobot/docs/user-guide/platform-functionality/users/token.md +0 -21
- nautobot/docs/user-guide/platform-functionality/webhook.md +0 -137
- nautobot/project-static/docs/media/nautobot_application_stack_low_level.drawio +0 -1
- nautobot/project-static/docs/media/nautobot_chatops.gif +0 -0
- nautobot/project-static/docs/media/nautobot_config_context.gif +0 -0
- nautobot/project-static/docs/media/nautobot_golden_config.gif +0 -0
- nautobot/project-static/docs/media/nautobot_graphql.gif +0 -0
- nautobot/project-static/docs/media/nautobot_mainpage.gif +0 -0
- nautobot/project-static/docs/media/nautobot_prefix_hierarchy.gif +0 -0
- nautobot-2.0.4.dist-info/LICENSE.txt +0 -177
- /LICENSE.txt → /nautobot-2.1.0b1.dist-info/LICENSE.txt +0 -0
- {nautobot-2.0.4.dist-info → nautobot-2.1.0b1.dist-info}/WHEEL +0 -0
- {nautobot-2.0.4.dist-info → nautobot-2.1.0b1.dist-info}/entry_points.txt +0 -0
|
@@ -1,469 +0,0 @@
|
|
|
1
|
-
# Best Practices
|
|
2
|
-
|
|
3
|
-
While there are many different development interfaces in Nautobot that each expose unique functionality, there are a common set of a best practices that have broad applicability to users and developers alike. This includes elements of writing Jobs, Plugins, and scripts for execution through `nautobot-server nbshell`.
|
|
4
|
-
|
|
5
|
-
The below best practices apply to test code as well as feature code, and there are additional [test-specific best practices](testing.md) to be aware of as well.
|
|
6
|
-
|
|
7
|
-
## Base Classes
|
|
8
|
-
|
|
9
|
-
For models that support change-logging, custom fields, and relationships (which includes all subclasses of `OrganizationalModel` and `PrimaryModel`), the "Full-featured models" base classes below should always be used. For less full-featured models, refer to the "Minimal models" column instead.
|
|
10
|
-
|
|
11
|
-
| Feature | Full-featured models | Minimal models |
|
|
12
|
-
| ------------------------ | -------------------------- | -------------------------- |
|
|
13
|
-
| FilterSets | `NautobotFilterSet` | `BaseFilterSet` |
|
|
14
|
-
| Object create/edit forms | `NautobotModelForm` | `BootstrapMixin` |
|
|
15
|
-
| Object bulk-edit forms | `NautobotBulkEditForm` | `BootstrapMixin` |
|
|
16
|
-
| Table filter forms | `NautobotFilterForm` | `BootstrapMixin` |
|
|
17
|
-
| Read-only serializers | `BaseModelSerializer` | `BaseModelSerializer` |
|
|
18
|
-
| Nested serializers | `WritableNestedSerializer` | `WritableNestedSerializer` |
|
|
19
|
-
| All other serializers | `NautobotModelSerializer` | `ValidatedModelSerializer` |
|
|
20
|
-
| API View Sets | `NautobotModelViewSet` | `ModelViewSet` |
|
|
21
|
-
|
|
22
|
-
## Data Model Best Practices
|
|
23
|
-
|
|
24
|
-
### Model Existence in the Database
|
|
25
|
-
|
|
26
|
-
A common Django pattern is to check whether a model instance's primary key (`pk`) field is set as a proxy for whether the instance has been written to the database or whether it exists only in memory.
|
|
27
|
-
Because of the way Nautobot's UUID primary keys are implemented, **this check will not work as expected** because model instances are assigned a UUID in memory _at instance creation time_, not at the time they are written to the database (when the model's `save()` method is called).
|
|
28
|
-
Instead, for any model which inherits from `nautobot.core.models.BaseModel`, you should check an instance's `present_in_database` property which will be either `True` or `False`.
|
|
29
|
-
|
|
30
|
-
Instead of:
|
|
31
|
-
|
|
32
|
-
```python
|
|
33
|
-
if instance.pk:
|
|
34
|
-
# Are we working with an existing instance in the database?
|
|
35
|
-
# Actually, the above check doesn't tell us one way or the other!
|
|
36
|
-
...
|
|
37
|
-
else:
|
|
38
|
-
# Will never be reached!
|
|
39
|
-
...
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
Use:
|
|
43
|
-
|
|
44
|
-
```python
|
|
45
|
-
if instance.present_in_database:
|
|
46
|
-
# We're working with an existing instance in the database!
|
|
47
|
-
...
|
|
48
|
-
else:
|
|
49
|
-
# We're working with a newly created instance not yet written to the database!
|
|
50
|
-
...
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
!!! note
|
|
54
|
-
There is one case where a model instance _will_ have a null primary key, and that is the case where it has been removed from the database and is in the process of being deleted.
|
|
55
|
-
For most purposes, this is not the case you are intending to check!
|
|
56
|
-
|
|
57
|
-
### Model Validation
|
|
58
|
-
|
|
59
|
-
Django offers several places and mechanism in which to exert data and model validation. All model specific validation should occur within the model's `clean()` method or field specific validators. This ensures the validation logic runs and is consistent through the various Nautobot interfaces (Web UI, REST API, ORM, etc).
|
|
60
|
-
|
|
61
|
-
#### Consuming Model Validation
|
|
62
|
-
|
|
63
|
-
Django places specific separation between validation and the saving of an instance and this means it is a common Django pattern to make explicit calls first to a model instance's `clean()`/`full_clean()` methods and then the `save()` method. Calling only the `save()` method **does not** automatically enforce validation and may lead to data integrity issues.
|
|
64
|
-
|
|
65
|
-
Nautobot provides a convenience method that both enforces model validation and saves the instance in a single call to `validated_save()`. Any model which inherits from `nautobot.core.models.BaseModel` has this method available. This includes all core models and it is recommended that all new Nautobot models and plugin-provided models also inherit from `BaseModel` or one of its descendants such as `nautobot.core.models.generics.OrganizationalModel` or `nautobot.core.models.generics.PrimaryModel`.
|
|
66
|
-
|
|
67
|
-
The intended audience for the `validated_save()` convenience method is Job authors and anyone writing scripts for, or interacting with the ORM directly through the `nautobot-server nbshell` command. It is generally not recommended however, to use `validated_save()` as a blanket replacement for the `save()` method in the core of Nautobot.
|
|
68
|
-
|
|
69
|
-
During execution, should model validation fail, `validated_save()` will raise `django.core.exceptions.ValidationError` in the normal Django fashion.
|
|
70
|
-
|
|
71
|
-
### Field Naming in Data Models
|
|
72
|
-
|
|
73
|
-
Model field names **must** always follow the following conventions:
|
|
74
|
-
|
|
75
|
-
- Use lowercase letters, numbers, and underscores only
|
|
76
|
-
- Separate words with underscores for readability/clarity
|
|
77
|
-
- For foreign keys and their corresponding reverse-relations, match the `verbose_name` or `verbose_name_plural` of the related model
|
|
78
|
-
|
|
79
|
-
Instead of:
|
|
80
|
-
|
|
81
|
-
```python
|
|
82
|
-
Rack.group
|
|
83
|
-
DeviceType.consoleserverporttemplates
|
|
84
|
-
Device.ipaddress_set
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
Use:
|
|
88
|
-
|
|
89
|
-
```python
|
|
90
|
-
Rack.rack_group
|
|
91
|
-
DeviceType.console_server_port_templates
|
|
92
|
-
Device.ip_addresses
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
#### Foreign Key `related_name` for Abstract Model Classes
|
|
96
|
-
|
|
97
|
-
+/- 2.0.0
|
|
98
|
-
|
|
99
|
-
If an abstract model class defines a foreign key to a concrete model class, Django's default `related_name` functionality doesn't provide great options - the best you could normally do for a `related_name` on a `ForeignKey` from an abstract base class, for example, would be `"%(class)ss"` (potentially resulting in related names like `"devices"` or, less optimally, `"ipaddresss"`) or `"%(app_label)s_%(class)s_related"` (resulting in related names like `"dcim_device_related"` or `"ipam_ipaddress_related"`, which while at least consistent, are rather clunky).
|
|
100
|
-
|
|
101
|
-
Fortunately, Nautobot provides a `ForeignKeyWithAutoRelatedName` model field class that solves this problem. On any concrete subclass of an abstract base class that uses `ForeignKeyWithAutoRelatedName` instead of `ForeignKey`, the `related_name` will be automatically set based on the concrete subclass's `verbose_name_plural` value (which in many cases Django is clever enough to automatically derive from the class name, but can also be specified directly on your `Meta` class if needed). Thus, if your model's `verbose_name_plural` is "IP addresses", the `related_name` for the `ForeignKeyWithAutoRelatedName` will automatically be `ip_addresses`.
|
|
102
|
-
|
|
103
|
-
!!! note
|
|
104
|
-
At this time we _only_ recommend using `ForeignKeyWithAutoRelatedName` for this abstract model case; for foreign keys between concrete models, it's still best to use a regular `ForeignKey` with an explicitly specified `related_name` string.
|
|
105
|
-
|
|
106
|
-
Nautobot doesn't currently have a similar class provided for `ManyToManyField`; in this case you'll probably be best, for now, to just use `related_name="%(app_label)s_%(class)s_related"` for any abstract base class's ManyToManyField if a reverse relation is desired.
|
|
107
|
-
|
|
108
|
-
### Slug Field
|
|
109
|
-
|
|
110
|
-
+/- 2.0.0
|
|
111
|
-
Models should generally **not** have a `slug` field, and should use the model's primary key (UUID) in URL patterns for both the UI and the REST API. All models should have a human-friendly natural key, either a single unique field (typically `name`) or a minimally complex unique-together set of fields (such as `DeviceType`'s `(manufacturer, model)`).
|
|
112
|
-
|
|
113
|
-
For models that have a strong use case for a `slug` or similar field (such as `GitRepository.slug`, which defines a module name for Python imports from the repository, or `CustomField.key`, which defines the key used to access this field in the REST API and GraphQL), Nautobot provides the `AutoSlugField` to handle automatically populating the `slug` field from another field(s). Generally speaking model slugs should be populated from the `name` field. Below is an example on defining the `slug` field.
|
|
114
|
-
|
|
115
|
-
```python
|
|
116
|
-
from django.db import models
|
|
117
|
-
|
|
118
|
-
from nautobot.core.models.fields import AutoSlugField
|
|
119
|
-
from nautobot.core.models.generics import PrimaryModel
|
|
120
|
-
|
|
121
|
-
class ExampleModel(PrimaryModel):
|
|
122
|
-
name = models.CharField(max_length=100, unique=True)
|
|
123
|
-
slug = AutoSlugField(populate_from='name')
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
## Getting URL Routes
|
|
127
|
-
|
|
128
|
-
When developing new models a need often arises to retrieve a reversible route for a model to access it in either the web UI or the REST API. When this time comes, you **must** use `nautobot.core.utils.lookup.get_route_for_model`. You **must not** write your own logic to construct route names.
|
|
129
|
-
|
|
130
|
-
+/- 2.0.0
|
|
131
|
-
`get_route_for_model` was moved from the `nautobot.utilities.utils` module to `nautobot.core.utils.lookup`.
|
|
132
|
-
|
|
133
|
-
```python
|
|
134
|
-
from nautobot.core.utils.lookup import get_route_for_model
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
This utility function supports both UI and API views for both Nautobot core apps and Nautobot plugins.
|
|
138
|
-
|
|
139
|
-
+++ 1.4.3
|
|
140
|
-
Support for generating API routes was added to `get_route_for_model()` by passing the argument `api=True`.
|
|
141
|
-
|
|
142
|
-
### UI Routes
|
|
143
|
-
|
|
144
|
-
Instead of:
|
|
145
|
-
|
|
146
|
-
```python
|
|
147
|
-
route = f"{model._meta.app_label}:{model._meta.model_name}_list"
|
|
148
|
-
if model._meta.app_label in settings.PLUGINS:
|
|
149
|
-
route = f"plugins:{route}"
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
Use:
|
|
153
|
-
|
|
154
|
-
```python
|
|
155
|
-
route = get_route_for_model(model, "list")
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
### REST API Routes
|
|
159
|
-
|
|
160
|
-
Instead of:
|
|
161
|
-
|
|
162
|
-
```python
|
|
163
|
-
api_route = f"{model._meta.app_label}-api:{model._meta.model_name}-list"
|
|
164
|
-
if model._meta.app_label in settings.PLUGINS:
|
|
165
|
-
api_route = f"plugins-api:{api_route}"
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
Use:
|
|
169
|
-
|
|
170
|
-
```python
|
|
171
|
-
api_route = get_route_for_model(model, "list", api=True)
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
### Examples
|
|
175
|
-
|
|
176
|
-
Core models:
|
|
177
|
-
|
|
178
|
-
```python
|
|
179
|
-
>>> get_route_for_model(Device, "list")
|
|
180
|
-
"dcim:device_list"
|
|
181
|
-
>>> get_route_for_model(Device, "list", api=True)
|
|
182
|
-
"dcim-api:device-list"
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
Plugin models:
|
|
186
|
-
|
|
187
|
-
```python
|
|
188
|
-
>>> get_route_for_model(ExampleModel, "list")
|
|
189
|
-
"plugins:example_plugin:examplemodel_list"
|
|
190
|
-
>>> get_route_for_model(ExampleModel, "list", api=True)
|
|
191
|
-
"plugins-api:example_plugin-api:examplemodel-list"
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
!!! tip
|
|
195
|
-
The first argument may also optionally be an instance of a model, or a string using the dotted notation of `{app_label}.{model}` (e.g. `dcim.device`).
|
|
196
|
-
|
|
197
|
-
Using an instance:
|
|
198
|
-
|
|
199
|
-
```python
|
|
200
|
-
>>> instance = Device.objects.first()
|
|
201
|
-
>>> get_route_for_model(instance, "list")
|
|
202
|
-
"dcim:device_list"
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
Using dotted notation:
|
|
206
|
-
|
|
207
|
-
```python
|
|
208
|
-
>>> get_route_for_model("dcim.device", "list")
|
|
209
|
-
"dcim:device_list"
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
## REST API Best Practices
|
|
213
|
-
|
|
214
|
-
- Generally the field names on a REST API serializer should correspond directly to the field names on the model, subject to the best practices described above.
|
|
215
|
-
- For related count fields, use the related model name suffixed with `_count`.
|
|
216
|
-
|
|
217
|
-
Instead of:
|
|
218
|
-
|
|
219
|
-
```python
|
|
220
|
-
Interface.count_ipaddresses
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
Use:
|
|
224
|
-
|
|
225
|
-
```python
|
|
226
|
-
Interface.ip_address_count
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
## Filtering Models with FilterSets
|
|
230
|
-
|
|
231
|
-
The following best practices must be considered when establishing new `FilterSet` classes for model classes.
|
|
232
|
-
|
|
233
|
-
### Mapping Model Fields to Filters
|
|
234
|
-
|
|
235
|
-
- FilterSets **must** inherit from `nautobot.extras.filters.NautobotFilterSet` (which inherits from `nautobot.core.filters.BaseFilterSet`)
|
|
236
|
-
- This affords that automatically generated lookup expressions (`ic`, `nic`, `iew`, `niew`, etc.) are always included
|
|
237
|
-
- This also asserts that the correct underlying `Form` class that maps the generated form field types and widgets will be included
|
|
238
|
-
|
|
239
|
-
- FilterSets **must** publish all model fields from a model, including related fields.
|
|
240
|
-
- All fields should be provided using `Meta.fields = "__all__"` and this would be preferable for the first and common case as it requires the least maintenance and overhead and asserts parity between the model fields and the filterset filters.
|
|
241
|
-
- In some cases simply excluding certain fields would be the next most preferable e.g. `Meta.exclude = ["unwanted_field", "other_unwanted_field"]`
|
|
242
|
-
- Finally, the last resort should be explicitly declaring the desired fields using `Meta.fields =`. This should be avoided because it incurs the highest technical debt in maintaining alignment between model fields and filters.
|
|
243
|
-
- In the event that fields do need to be customized to extend lookup expressions, a [dictionary of field names mapped to a list of lookups](https://django-filter.readthedocs.io/en/stable/ref/filterset.html#declaring-filterable-fields) **may** be used, however, this pattern is only compatible with explicitly declaring all fields, which should also be avoided for the common case. For example:
|
|
244
|
-
|
|
245
|
-
```python
|
|
246
|
-
class UserFilter(NautobotFilterSet):
|
|
247
|
-
class Meta:
|
|
248
|
-
model = User
|
|
249
|
-
fields = {
|
|
250
|
-
'username': ['exact', 'contains'],
|
|
251
|
-
'last_login': ['exact', 'year__gt'],
|
|
252
|
-
}
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
- It is acceptable that default filter mappings **may** need to be overridden with custom filter declarations, but [`filter_overrides`](https://django-filter.readthedocs.io/en/stable/ref/filterset.html#customise-filter-generation-with-filter-overrides) (see below) should be used as a first resort.
|
|
256
|
-
|
|
257
|
-
### Filter Naming and Definition
|
|
258
|
-
|
|
259
|
-
- Custom filter definitions **must not** shadow the name of an existing model field if it is also changing the type.
|
|
260
|
-
- For example (before Nautobot 2.0.0), `DeviceFilterSet.interfaces` was a `BooleanFilter` that was shadowing the `Device.interfaces` related manager. This caused problems with automatic introspection of the filterset and was fixed in 2.0 by introducing a separate `has_interfaces` filter and changing the `interfaces` filter to show the correct behavior. Shadowing database fields with a filter field of a different type **must** be avoided in all new filters.
|
|
261
|
-
|
|
262
|
-
- In Nautobot 2.0 and later, for all foreign-key related fields and their corresponding reverse-relations:
|
|
263
|
-
- If there is no appropriate single field that could be used as a natural key (e.g. a globally-unique `name` or `slug`), then the default filtering behavior for this field (using `django_filters.ModelMultipleChoiceFilter`) can be used for now, until [issue 2875](https://github.com/nautobot/nautobot/issues/2875) is implemented to allow for the use of multiple fields with `NaturalKeyOrPKMultipleChoiceFilter`.
|
|
264
|
-
- Otherwise, the field **must** be shadowed with a Nautobot `NaturalKeyOrPKMultipleChoiceFilter` which will automatically try to lookup by UUID or `name` depending on the value of the incoming argument (e.g. UUID string vs. name string).
|
|
265
|
-
- This provides an advantage over the default `django_filters.ModelMultipleChoiceFilter` which only supports a UUID (`pk`) value as an input.
|
|
266
|
-
- Fields that use `slug` or some other natural key field instead of `name` can set the `to_field_name` argument on `NaturalKeyOrPKMultipleChoiceFilter` accordingly.
|
|
267
|
-
|
|
268
|
-
```python
|
|
269
|
-
# Typical usage
|
|
270
|
-
from nautobot.core.filters import NaturalKeyOrPKMultipleChoiceFilter
|
|
271
|
-
|
|
272
|
-
provider = NaturalKeyOrPKMultipleChoiceFilter(
|
|
273
|
-
queryset=Provider.objects.all(),
|
|
274
|
-
to_field_name="name",
|
|
275
|
-
label="Provider (name or ID)",
|
|
276
|
-
)
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
```python
|
|
280
|
-
# Optionally, using the to_field_name argument to look up by "slug" instead of by "name"
|
|
281
|
-
from nautobot.core.filters import NaturalKeyOrPKMultipleChoiceFilter
|
|
282
|
-
|
|
283
|
-
git_repository = NaturalKeyOrPKMultipleChoiceFilter(
|
|
284
|
-
to_field_name="slug",
|
|
285
|
-
queryset=GitRepository.objects.all(),
|
|
286
|
-
label="Git repository (slug or ID)",
|
|
287
|
-
)
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
- Boolean filters for membership **must** be named with `has_{related_name}` (e.g. `has_interfaces`) and should use the `RelatedMembershipBooleanFilter` filter class.
|
|
291
|
-
- One exception to this naming convention may be made for Boolean filters for identity, which **may** be named `is_{name}` instead (e.g. `is_virtual_chassis_member` versus `has_virtual_chassis`). Although this is semantically identical to `has_` filters, there may be occasions where naming the filter `is_` would be more intuitive.
|
|
292
|
-
|
|
293
|
-
```python
|
|
294
|
-
from nautobot.core.filters import RelatedMembershipBooleanFilter
|
|
295
|
-
|
|
296
|
-
has_interfaces = RelatedMembershipBooleanFilter(
|
|
297
|
-
field_name="interfaces",
|
|
298
|
-
label="Has interfaces",
|
|
299
|
-
)
|
|
300
|
-
|
|
301
|
-
is_virtual_chassis_member = RelatedMembershipBooleanFilter(
|
|
302
|
-
field_name="virtual_chassis",
|
|
303
|
-
label="Is a virtual chassis member",
|
|
304
|
-
)
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
- Whenever possible otherwise, filter names **must** correspond exactly to the underlying model field they are referencing.
|
|
308
|
-
|
|
309
|
-
- If there's necessarily a mismatch between the filter name and the model field name (such as in the `has_*` and `is_*` cases described above):
|
|
310
|
-
1. The suffix component of the filter name **must** correspond exactly to the underlying model field name (for example, for a field of `console_port_templates`, the filter must be `has_console_port_templates`, **not** `has_consoleporttemplates` or `has_console_ports`).
|
|
311
|
-
2. The filter itself **must** declare [`field_name`](https://django-filter.readthedocs.io/en/stable/ref/filters.html#field-name) to identify unambiguously the underlying model field.
|
|
312
|
-
|
|
313
|
-
- Filters **must** be declared using the appropriate lookup expression (`lookup_expr`) if any other expression than `exact` (the default) is required.
|
|
314
|
-
|
|
315
|
-
- Filters **must** be declared using [`exclude=True`](https://django-filter.readthedocs.io/en/stable/ref/filters.html#exclude) if a queryset `.exclude()` is required to be called vs. queryset `.filter()` which is the default when the filter default `exclude=False` is passed through. If you require `Foo.objects.exclude()`, you must pass `exclude=True` instead of defining a filterset method to explicitly hard-code such a query.
|
|
316
|
-
|
|
317
|
-
For example, for a boolean filter that checks to see whether the `console_ports` field is null if False and not null if True, you would need to combine all of the above rules, resulting in:
|
|
318
|
-
|
|
319
|
-
```python
|
|
320
|
-
has_console_ports = BooleanFilter(field_name="console_ports", lookup_expr="isnull", exclude=True)
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
!!! tip
|
|
324
|
-
For boolean filters on related memberships (`has_*`/`is_*`), you should always use `RelatedMembershipBooleanFilter`, which is a `BooleanFilter` subclass that defaults to the correct `lookup_expr` and `exclude` values for this common case.
|
|
325
|
-
|
|
326
|
-
- Filters **must** be declared using [`distinct=True`](https://django-filter.readthedocs.io/en/stable/ref/filters.html#distinct) if a queryset `.distinct()`is required to be called on the queryset.
|
|
327
|
-
|
|
328
|
-
- Filters **must not** be set to be required using `required=True`
|
|
329
|
-
|
|
330
|
-
- Filter methods defined using the [`method=`](https://django-filter.readthedocs.io/en/stable/ref/filters.html#method) keyword argument **may only be used as a last resort** (see below) when correct usage of `field_name`, `lookup_expr`, `exclude`, or other filter keyword arguments do not suffice. In other words: filter methods should used as the exception and not the rule.
|
|
331
|
-
|
|
332
|
-
- Use of [`filter_overrides`](https://django-filter.readthedocs.io/en/stable/ref/filterset.html#filter-overrides) **must be considered** in cases where more-specific class-local overrides. The need may occasionally arise to change certain filter-level arguments used for filter generation, such such as changing a filter class, or customizing a UI widget. Any `extra` arguments are sent to the filter as keyword arguments at instance creation time. (Hint: `extra` must be a callable)
|
|
333
|
-
|
|
334
|
-
For example:
|
|
335
|
-
|
|
336
|
-
```python
|
|
337
|
-
class ProductFilter(NautobotFilterSet):
|
|
338
|
-
|
|
339
|
-
class Meta:
|
|
340
|
-
model = Interface
|
|
341
|
-
fields = "__all__"
|
|
342
|
-
filter_overrides = {
|
|
343
|
-
# This would change the default to all CharFields to use lookup_expr="icontains". It
|
|
344
|
-
# would also pass in the custom `choices` generated by the `generate_choices()`
|
|
345
|
-
# function.
|
|
346
|
-
models.CharField: {
|
|
347
|
-
"filter_class": filters.MultiValueCharFilter,
|
|
348
|
-
"extra": lambda f: {
|
|
349
|
-
"lookup_expr": "icontains",
|
|
350
|
-
"choices": generate_choices(),
|
|
351
|
-
},
|
|
352
|
-
},
|
|
353
|
-
# This would make BooleanFields use a radio select widget vs. the default of checkbox
|
|
354
|
-
models.BooleanField: {
|
|
355
|
-
"extra": lambda f: {
|
|
356
|
-
"widget": forms.RadioSelect,
|
|
357
|
-
},
|
|
358
|
-
},
|
|
359
|
-
}
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
!!!warning
|
|
363
|
-
Existing features of filtersets and filters **must** be exhausted first using keyword arguments before resorting to customizing, re-declaring/overloading, or defining filter methods.
|
|
364
|
-
|
|
365
|
-
### Filter Methods
|
|
366
|
-
|
|
367
|
-
Filters on a filterset can reference a `method` (either a callable, or the name of a method on the filterset) to perform custom business logic for that filter field. However, many uses of filter methods in Nautobot are problematic because they break the ability for such filter fields to be properly reversible.
|
|
368
|
-
|
|
369
|
-
Consider this example from `nautobot.dcim.filters.DeviceFilterSet.pass_through_ports`:
|
|
370
|
-
|
|
371
|
-
```python
|
|
372
|
-
# Filter field definition is a BooleanFilter, for which an "isnull" lookup_expr
|
|
373
|
-
# is the only valid filter expression
|
|
374
|
-
pass_through_ports = django_filters.BooleanFilter(
|
|
375
|
-
method="_pass_through_ports",
|
|
376
|
-
label="Has pass-through ports",
|
|
377
|
-
)
|
|
378
|
-
|
|
379
|
-
# Method definition loses context and further the field's lookup_expr
|
|
380
|
-
# falls back to the default of "exact" and the `name` value is irrelevant here.
|
|
381
|
-
def _pass_through_ports(self, queryset, name, value):
|
|
382
|
-
breakpoint() # This was added to illustrate debugging with pdb below
|
|
383
|
-
return queryset.exclude(frontports__isnull=value, rearports__isnull=value)
|
|
384
|
-
```
|
|
385
|
-
|
|
386
|
-
The default `lookup_expr` unless otherwise specified is “exact”, as seen in [django_filters.conf](https://github.com/carltongibson/django-filter/blob/main/django_filters/conf.py#L10):
|
|
387
|
-
|
|
388
|
-
```python
|
|
389
|
-
'DEFAULT_LOOKUP_EXPR': 'exact',
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
When this method is called, the internal state is default, making reverse introspection impossible, because the `lookup_expr` is defaulting to “exact”:
|
|
393
|
-
|
|
394
|
-
```python
|
|
395
|
-
(Pdb) field = self.filters[name]
|
|
396
|
-
(Pdb) field.exclude
|
|
397
|
-
False
|
|
398
|
-
(Pdb) field.lookup_expr
|
|
399
|
-
'exact'
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
This means that the arguments for the field are being completely ignored and the hard-coded queryset `queryset.exclude(frontports__isnull=value, rearports__isnull=value)` is all that is being run when this method is called.
|
|
403
|
-
|
|
404
|
-
Additionally, `name` variable that gets passed to the method cannot be used here because there are two field names at play (`frontports` and `rearports`). This hard-coding is impossible to introspect and therefore impossible to reverse.
|
|
405
|
-
|
|
406
|
-
So while this filter definition could be improved like so, there is still no way to know what is going on in the method body:
|
|
407
|
-
|
|
408
|
-
```python
|
|
409
|
-
pass_through_ports = django_filters.BooleanFilter(
|
|
410
|
-
method="_pass_through_ports", # The method that is called
|
|
411
|
-
exclude=True, # Perform an `.exclude()` vs. `.filter()``
|
|
412
|
-
lookup_expr="isnull", # Perform `isnull` vs. `exact``
|
|
413
|
-
label="Has pass-through ports",
|
|
414
|
-
)
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
For illustration, if we use another breakpoint, you can see that the filter field now has the correct attributes that can be used to help reverse this query:
|
|
418
|
-
|
|
419
|
-
```python
|
|
420
|
-
(Pdb) field = self.filters[name]
|
|
421
|
-
(Pdb) field.exclude
|
|
422
|
-
True
|
|
423
|
-
(Pdb) field.lookup_expr
|
|
424
|
-
'isnull'
|
|
425
|
-
```
|
|
426
|
-
|
|
427
|
-
Except that it stops there because of the method body. Here are the problems:
|
|
428
|
-
|
|
429
|
-
- There's no way to identify either of the field names required here
|
|
430
|
-
- The `name` that is incoming to the method is the filter name as defined (`pass_through_ports` in this case) does not map to an actual model field
|
|
431
|
-
- So the filter can be introspected for `lookup_expr` value using `self.filters[name].lookup_expr`, but it would have to be assumed that applies to both fields.
|
|
432
|
-
- Same with `exclude` (`self.filters[name].exclude`)
|
|
433
|
-
|
|
434
|
-
It would be better to just eliminate `pass_through_ports=True` entirely in exchange for `front_ports=True&rear_ports=True` (current) or `has_frontports=True&has_rearports=True` (future).
|
|
435
|
-
|
|
436
|
-
#### Generating Reversible Q Objects
|
|
437
|
-
|
|
438
|
-
With consistent and proper use of filter field arguments when defining them on a filterset, a query could be constructed using the `field_name` and `lookup_expr` values. For example:
|
|
439
|
-
|
|
440
|
-
```python
|
|
441
|
-
def generate_query(self, field, value):
|
|
442
|
-
query = Q()
|
|
443
|
-
predicate = {f"{field.field_name}__{field.lookup_expr}": value}
|
|
444
|
-
if field.exclude:
|
|
445
|
-
query |= ~Q(**predicate)
|
|
446
|
-
else:
|
|
447
|
-
query |= Q(**predicate)
|
|
448
|
-
return query
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
## Somewhere else in business logic:
|
|
452
|
-
field = filterset.filters[name]
|
|
453
|
-
value = filterset.data[name]
|
|
454
|
-
query = generate_query(field, value)
|
|
455
|
-
filterset.qs.filter(query).count() # 339
|
|
456
|
-
```
|
|
457
|
-
|
|
458
|
-
### Summary
|
|
459
|
-
|
|
460
|
-
- For the vast majority of cases where we have method filters, it’s for Boolean filters
|
|
461
|
-
- For the common case **method filters are unnecessary technical debt and should be eliminated where better suited by proper use of filter field arguments**
|
|
462
|
-
- Reversibility may not always necessarily be required, but by properly defining `field_name`, `lookup_expr`, and `exclude` on filter fields, **introspection becomes deterministic and reversible queries can be reliably generated as needed.**
|
|
463
|
-
- For exceptions such as `DeviceFilterSet.has_primary_ip` where it checks for both `Device.primary_ip4` OR `Device.primary_ip6`, method filters may still be necessary, however, they would be **the exception and not the norm.**
|
|
464
|
-
- The good news is that in the core there are not that many of these filter methods defined, but we also don’t want to see them continue to proliferate.
|
|
465
|
-
|
|
466
|
-
## Using NautobotUIViewSet for Plugin Development
|
|
467
|
-
|
|
468
|
-
+++ 1.4.0
|
|
469
|
-
Using `NautobotUIViewSet` for [plugin development](../apps/api/views/nautobotuiviewset.md) is strongly recommended.
|