Code Updates - Nautobot Documentation

Skip to content

# App Code Updates for Nautobot v2

## Update Code Import Locations

Most changes in code location arise from the merging of the `nautobot.utilities` module into the `nautobot.core` module.

Full table of code location changes

Old Module | Class/Function(s) | New Module
--- | --- | ---
nautobot.core.api.utils | TreeModelSerializerMixin | nautobot.core.api.serializers
nautobot.core.fields | (all) | nautobot.core.models.fields
nautobot.core.forms | SearchForm | nautobot.core.forms.search
nautobot.core.utilities | (all) | nautobot.core.views.utils
nautobot.dcim.fields | MACAddressCharField | nautobot.core.models.fields
nautobot.dcim.forms | MACAddressField | nautobot.core.forms
nautobot.extras.api.customfields | CustomFieldModelSerializerMixin | nautobot.core.api.serializers
nautobot.extras.api.relationships | RelationshipModelSerializerMixin | nautobot.core.api.serializers
nautobot.extras.api.serializers | NautobotModelSerializer | nautobot.core.api.serializers
nautobot.extras.api.serializers | NotesSerializerMixin | nautobot.core.api.serializers
nautobot.extras.api.serializers | TaggedModelSerializerMixin | nautobot.extras.api.mixins
nautobot.extras.utils | is_taggable | nautobot.core.models.utils
nautobot.utilities.api | (all) | nautobot.core.api.utils
nautobot.utilities.apps | (all) | nautobot.core.apps
nautobot.utilities.checks | (all) | nautobot.core.checks
nautobot.utilities.choices | (all) | nautobot.core.choices
nautobot.utilities.config | (all) | nautobot.core.utils.config
nautobot.utilities.constants | (all) | nautobot.core.constants
nautobot.utilities.deprecation | (all) | nautobot.core.utils.deprecation
nautobot.utilities.error_handlers | (all) | nautobot.core.views.utils
nautobot.utilities.exceptions | (all) | nautobot.core.exceptions
nautobot.utilities.factory | (all) | nautobot.core.factory
nautobot.utilities.fields | (all) | nautobot.core.models.fields
nautobot.utilities.filters | (all) | nautobot.core.filters
nautobot.utilities.forms | (all) | nautobot.core.forms
nautobot.utilities.git | (all) | nautobot.core.utils.git
nautobot.utilities.logging | (all) | nautobot.core.utils.logging
nautobot.utilities.management | (all) | nautobot.core.management
nautobot.utilities.ordering | (all) | nautobot.core.utils.ordering
nautobot.utilities.paginator | (all) | nautobot.core.views.paginator
nautobot.utilities.permissions | (all) | nautobot.core.utils.permissions
nautobot.utilities.query_functions | (all) | nautobot.core.models.query_functions
nautobot.utilities.querysets | (all) | nautobot.core.models.querysets
nautobot.utilities.tables | (all) | nautobot.core.tables
nautobot.utilities.tasks | (all) | nautobot.core.tasks
nautobot.utilities.templatetags | (all) | nautobot.core.templatetags
nautobot.utilities.testing | (all) | nautobot.core.testing
nautobot.utilities.tree_queries | (all) | nautobot.core.models.tree_queries
nautobot.utilities.utils | array_to_string | nautobot.core.models.utils
nautobot.utilities.utils | convert_querydict_to_factory_formset_acceptable_querydict | nautobot.core.utils.requests
nautobot.utilities.utils | count_related | nautobot.core.models.querysets
nautobot.utilities.utils | csv_format | nautobot.core.views.utils
nautobot.utilities.utils | deepmerge | nautobot.core.utils.data
nautobot.utilities.utils | dict_to_filter_params | nautobot.core.api.utils
nautobot.utilities.utils | dynamic_import | nautobot.core.api.utils
nautobot.utilities.utils | ensure_content_type_and_field_name_inquery_params | nautobot.core.utils.requests
nautobot.utilities.utils | flatten_dict | nautobot.core.utils.data
nautobot.utilities.utils | flatten_iterable | nautobot.core.utils.data
nautobot.utilities.utils | foreground_color | nautobot.core.utils.color
nautobot.utilities.utils | get_all_lookup_expr_for_field | nautobot.core.utils.filtering
nautobot.utilities.utils | get_api_version_serializer | nautobot.core.api.utils
nautobot.utilities.utils | get_changes_for_model | nautobot.core.utils.lookup
nautobot.utilities.utils | get_filterset_field | nautobot.core.utils.filtering
nautobot.utilities.utils | get_filterset_for_model | nautobot.core.utils.lookup
nautobot.utilities.utils | get_filterable_params_from_filter_params | nautobot.core.utils.requests
nautobot.utilities.utils | get_form_for_model | nautobot.core.utils.lookup
nautobot.utilities.utils | get_model_from_name | nautobot.core.utils.lookup
nautobot.utilities.utils | get_related_class_for_model | nautobot.core.utils.lookup
nautobot.utilities.utils | get_route_for_model | nautobot.core.utils.lookup
nautobot.utilities.utils | get_table_for_model | nautobot.core.utils.lookup
nautobot.utilities.utils | hex_to_rgb | nautobot.core.utils.color
nautobot.utilities.utils | is_taggable | nautobot.core.models.utils
nautobot.utilities.utils | is_uuid | nautobot.core.utils.data
nautobot.utilities.utils | lighten_color | nautobot.core.utils.color
nautobot.utilities.utils | normalize_querydict | nautobot.core.utils.requests
nautobot.utilities.utils | prepare_cloned_fields | nautobot.core.views.utils
nautobot.utilities.utils | pretty_print_query | nautobot.core.models.utils
nautobot.utilities.utils | render_jinja2 | nautobot.core.utils.data
nautobot.utilities.utils | rgb_to_hex | nautobot.core.utils.color
nautobot.utilities.utils | SerializerForAPIVersions | nautobot.core.api.utils
nautobot.utilities.utils | serialize_object | nautobot.core.models.utils
nautobot.utilities.utils | serialize_object_v2 | nautobot.core.models.utils
nautobot.utilities.utils | shallow_compare_dict | nautobot.core.utils.data
nautobot.utilities.utils | slugify_dots_to_dashes | nautobot.core.models.fields
nautobot.utilities.utils | slugify_dashes_to_underscores | nautobot.core.models.fields
nautobot.utilities.utils | to_meters | nautobot.core.utils.data
nautobot.utilities.utils | UtilizationData | nautobot.core.utils.data
nautobot.utilities.utils | versioned_serializer_selector | nautobot.core.api.utils
nautobot.utilities.validators | (all) | nautobot.core.models.validators
nautobot.utilities.views | (all) | nautobot.core.views.mixins

## Replace PluginMenuItem with NavMenuItem

In your app's `navigation.py` file. If you are still using `PluginMenuItem` from `nautobot.extras.plugin`, you should replace those code with `NavMenuGroup`, `NavMenuItem`, and `NavMenuTab` from `nautobot.apps.ui`.

For example:

Before:

        from nautobot.extras.plugins import PluginMenuItem

        menu_items = (
            PluginMenuItem(
                link="plugins:your_app:dashboard",
                link_text="Dashboard",
                permissions=["your_app.view_sync"],
            ),
            PluginMenuItem(
                link="plugins:your_app:sync_list",
                link_text="History",
                permissions=["your_app.view_sync"],
            ),
            PluginMenuItem(
                link="plugins:your_app:synclogentry_list",
                link_text="Logs",
                permissions=["your_app.view_synclogentry"],
            ),
        )

After:

    from nautobot.apps.ui import NavMenuGroup, NavMenuItem, NavMenuTab

    items = [
        NavMenuItem(
            link="plugins:your_app:dashboard",
            name="Dashboard",
            permissions=["your_app.view_sync"],
        ),
        NavMenuItem(
            link="plugins:your_app:sync_list",
            name="History",
            permissions=["your_app.view_sync"],
        ),
        NavMenuItem(
            link="plugins:your_app:synclogentry_list",
            name="Logs",
            permissions=["your_app.view_synclogentry"],
        ),
    ]

    menu_items = (
        NavMenuTab(
            name="Plugins",
            groups=(NavMenuGroup(name="Your App", weight=1000, items=tuple(items)),),
        ),
    )

### Remove Tag/Tags Filter from FilterSet Definitions

In Nautobot 2.0, you can safely remove `tag = TagFilter(...)` from your filter set definitions as long as your filter sets inherit from `NautobotFilterSet` class and `tags` is added to the filter set class `Meta.fields`.

For example, before the filter set could look like this:

    class AppModelFilterSet(BaseFilterSet):

        name = MultiValueCharFilter(...)
        number = MultiValueNumberFilter(...)
        tag = TagFilter(...)

        class Meta:
            fields = ["name", "number"]

After changing the base class to `NautobotFilterSet` the `tag` filter should be removed:

    class AppModelFilterSet(NautobotFilterSet):

        name = MultiValueCharFilter(...)
        number = MultiValueNumberFilter(...)

        class Meta:
            fields = ["name", "number", "tags"]

## Replace DjangoFilterBackend with NautobotFilterBackend

If your REST API has any `FilterBackend` classes derived from `DjangoFilterBackend`, you should replace `DjangoFilterBackend` with `NautobotFilterBackend`.

## App Model Serializer Inheritance

App Model Serializers for any models that could have a Generic Foreign Key or a Many to Many relationship from a Nautobot Core model must inherit from BaseModelSerializer at a minimum so that they have a properly generated `object_type` field. This also applies to the case where your model is a subclass of `ChangeLoggedModel` and you will have a Generic Foreign Key from `ObjectChange`'s `changed_object` field. Otherwise drf-spectacular schema generation will throw an error:

    (drf_spectacular.E001) Schema generation threw exception "Field name `object_type` is not valid for model `YourAppModel`.

## Revamp Rest API Serializers

`NestedSerializer` classes are no longer needed in Nautobot 2.0. If any `NestedSerializers` exist for your models, you should just remove their class definitions and references.

After removing existing `NestedSerializers`, you can change the `fields` attribute in your serializers' `class Meta` to `__all__` and that will automatically include all the model's fields in the serializer, including related-model fields that would previously have required a reference to a `NestedSerializer`. If you want to exclude certain fields of the model, you can specify a list of fields you want to display in the `fields` attribute instead.

Warning

Use caution around `fields = "__all__"` -- if your model has any fields that should not be exposed in the REST API, you should avoid using `"__all__"` and instead use an explicit `fields` list to ensure that such fields are not exposed. In some cases, it may be appropriate to use `"__all__"` in combination with flags such as `write_only=True` on specific fields, but proceed with caution and examine the REST API data carefully to ensure that its contents are as expected.

Include all model attributes:

    class ExampleModelSerializer(NautobotModelSerializer):
        """Used for normal CRUD operations."""

        url = serializers.HyperlinkedIdentityField(view_name="plugins-api:example_plugin-api:anotherexamplemodel-detail")

        class Meta:
            model = AnotherExampleModel
            fields = "__all__"

Include only specified model attributes:

    class ExampleModelSerializer(NautobotModelSerializer):
        """Used for normal CRUD operations."""

        url = serializers.HyperlinkedIdentityField(view_name="plugins-api:example_plugin-api:anotherexamplemodel-detail")

        class Meta:
            model = AnotherExampleModel
            # example_attribute_4 is not included in the serializer
            fields = ["url", "example_attribute_1", "example_attribute_2", "example_attribute_3"]

In addition, the `?brief=` API query parameter is replaced by `?depth=<0-10>`. As a result, the ability to specify `brief_mode` in `DynamicModelChoiceField`, `DynamicModelMultipleChoiceField`, and `MultiMatchModelMultipleChoiceField` has also been removed. For every occurrence of the aforementioned fields where you have `brief_mode` set to `True/False` (e.g. `brief_mode=True`), please remove the statement, leaving other occurrences of the fields where you do not have `brief_mode` specified as they are. Check out our API documentation for this change.

## Revamp CSV Import and Export

CSV Import for models are now done automatically via the Rest API. As a result of this change, `CSVForm` classes are no longer needed and should be deleted. In addition, the Model `csv_headers` attribute and `to_csv` method are no longer needed or used in CSV generation, and should be removed from your model definitions. Check out our release notes for this specific change.