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.