Skip to content

# Upgrading from Nautobot v1.X

## Pre-migration validation

In Nautobot 1.x, starting with 1.5.22, there is a `nautobot-server pre_migrate` command that can be run to check your existing data for compatibility with the data model changes introduced in Nautobot 2.0. You are highly encouraged to run this command before beginning to migrate to Nautobot 2.x as it will catch and report certain data-sanitization issues that cannot be remediated automatically during the migration and will need to be manually corrected before you upgrade.

For example, if any of the pre-migration checks fail, you may see an error message like this:

    $ nautobot-server pre_migrate
    >>> Running check: check_configcontext_uniqueness...
    >>> Running check: check_exporttemplate_uniqueness...
    >>> Running check: check_virtualchassis_uniqueness...
    CommandError: One or more pre-migration checks failed:
        You cannot migrate ConfigContext or ConfigContextSchema objects that have non-unique names:
        - ConfigContext: [{'name': 'cc1', 'count': 2}]
        - ConfigContextSchema: [{'name': 'ccs1', 'count': 2}]

        You cannot migrate VirtualChassis objects with non-unique names:
         - [{'name': 'vc1', 'count': 2}]

Otherwise, a clean exit displays "All pre-migration checks passed." indicating that your Nautobot instance is ready to be upgraded to Nautobot 2.0:

    $ nautobot-server pre_migrate
    >>> Running check: check_configcontext_uniqueness...
    >>> Running check: check_exporttemplate_uniqueness...
    >>> Running check: check_virtualchassis_uniqueness...
    All pre-migration checks passed.

### Permission Constraint Migration

Permission constraints that contain references to fields or models that were changed or removed in Nautobot 2.0 will have to be updated manually after the upgrade. For example, any permission constraints that reference a `Site` will need to be updated to reference the `Location` model instead. The `nautobot-server pre_migrate` command will output a list of all permission constraints that need to be updated after the upgrade.

    >>> Running permission constraint checks...

    One or more permission constraints may be affected by the Nautobot 2.0 migration.
    These permission constraints will have to be updated manually after upgrading to
    Nautobot 2.0 to reference new models and/or values. Please review the following
    warnings and make sure to document the objects referenced by these constraints
    before upgrading:

    ObjectPermission 'backbone devices' (id: ced686c3-2b34-4612-974a-bad766512661) has a constraint that references a model (nautobot.dcim.models.devices.DeviceRole) that will be migrated to a new model by the Nautobot 2.0 migration.
    {
        "device_role": "e99adc77-40ef-4a0f-b2c1-26dbf6648ef1"
    }

    ObjectPermission 'example job run' (id: 41c6d03e-6388-47eb-b575-1c7a21725bc3) has a constraint that references a model field (nautobot.extras.models.jobs.Job.name) that may be changed by the Nautobot 2.0 migration.
    {
        "name": "Example job, does nothing"
    }

    ObjectPermission 'emea' (id: 2d3b7aae-98ab-44ec-af89-43d3002a1b7d) has a constraint that references a model (nautobot.dcim.models.sites.Region) that will be migrated to a new model by the Nautobot 2.0 migration.
    [
        {
            "site__region__slug": "emea"
        },
        {
            "id": "4c9f3e5c-2dc6-46f6-95ac-ac778369edfc"
        }
    ]

We recommend taking inventory of any objects referenced by primary key in permission constraints for the following models:

- `dcim.DeviceRole`
- `dcim.RackRole`
- `extras.TaggedItem`
- `ipam.Aggregate`
- `ipam.IPAddress`
- `ipam.Prefix`
- `ipam.Role`

This is because the primary key for these objects may be changed during the migration. You will not be able to use the primary key value from the old object in the constraint to find the new object.

Note

This pre-migration check only checks the last model referenced in a constraint filter. If you have nested filters (`device_role__devices`) they may not be reported by this check. You should review all of your permission constraints after the upgrade to ensure that they are still valid.

#### Examples

Primary keys for the migrated `Site` and `Region` objects were retained in the `Location` model, so you do not need to update the primary key value in any `Site` or `Region` constraints:

Old Constraint

    {
        "site": "4c9f3e5c-2dc6-46f6-95ac-ac778369edfc"
    }

New Constraint

    {
        "location": "4c9f3e5c-2dc6-46f6-95ac-ac778369edfc"
    }

Other models such as the `DeviceRole` that was migrated to `Role` did not retain the original primary key. In this case you will need to find the new object's primary key and update the constraint to reference the new model and new primary key value:

Old Constraint

    {
        "device_role": "00000000-0000-0000-0000-000000000000"
    }

New Constraint

    {
        "role": "11111111-1111-1111-1111-111111111111"
    }

You may also need to update field names in your permission constraints. For example, if you have a permission constraint that references the `slug` field on a model that was removed in Nautobot 2.0, you will need to update the constraint to reference a different field instead:

Old Constraint

    {
        "slug": "router-01"
    }

New Constraint

    {
        "id": "5f96ac85-32d4-435d-84e4-66e631ae133f"
    }

Some fields were only renamed without making any changes to the data so the constraint update will be a simple matter of updating the field name:

Old Constraint

    {
        "circuit__type__name": "metro-ethernet-1000mb"
    }

New Constraint

    {
        "circuit__circuit_type__name": "metro-ethernet-1000mb"
    }

## Dependency Changes

- Nautobot no longer uses or supports the use of `django-cryptography`.
- Nautobot no longer uses or supports the use of `django-mptt`.
- Nautobot no longer uses or supports the use of `django-rq`.

## App Developer Interface

All imports for app developers should now be sourced from `nautobot.apps.*` or provided models, as this is the supported public interface. This will help ensure proper SemVer is kept intact and provide a place to add new features without breaking existing integrations.

## Database (ORM) Changes

Warning

Changes were made to model and related model fields. In some cases this may invalidate or make subtle changes to existing Permission Constraint filter data. Please review the Permission Constraint Migration section above for more information. These changes might also affect Filter Extensions you have written in your apps.

### Database Field Behavior Changes

Most of the database field behavior changes in Nautobot 2.0 fall into the following general categories:

1. The `created` field on models has changed from a date only ("2023-04-06") to being a date/time ("2023-04-06T19:57:45.320232Z")
2. Various models that had a required `site` field and an optional `location` field now have a required `location` field.

Full table of database field behavior changes

Model | Field | Changes
--- | --- | ---
(all) | created | Changed from `DateField` to `DateTimeField`
ConfigContext | name | Now must be globally unique
ConfigContextSchema | name | Now must be globally unique
Device | location | No longer optional/nullable, must now be set
Device | primary_ip4 | No longer one-to-one, now one-to-many (`ForeignKey`)
Device | primary_ip6 | No longer one-to-one, now one-to-many (`ForeignKey`)
IPAddress | role | Changed from `CharField` to a `ForeignKey` to the new `Role` model.
IPAddress | primary_ip4_for | Now a list as the reverse relation for the `Device.primary_ip4` foreign key
IPAddress | primary_ip6_for | Now a list as the reverse relation for the `Device.primary_ip6` foreign key
JobLogEntry | absolute_url | No longer accepts `null` values, use `""` instead
JobLogEntry | log_object | No longer accepts `null` values, use `""` instead
ObjectPermission | name | Now must be globally unique
PowerPanel | location | No longer optional/nullable, must now be set
Prefix | is_pool | Replaced by new field `type`, valid choices are "Container", "Network" and "Pool"
Prefix | namespace | New required foreign key to Namespace, defaulting to 'Global'
Prefix | status | "Container" status has been replaced by new field `type`
Rack | location | No longer optional/nullable, must now be set
RackGroup | location | No longer optional/nullable, must now be set
ScheduledJob | name | Now must be globally unique
ScheduledJob | queue | No longer accepts `null` values, use `""` instead
VirtualChassis | name | Now must be globally unique
VirtualMachine | primary_ip4 | No longer one-to-one, now one-to-many (`ForeignKey`). Remote side is now a list.
VirtualMachine | primary_ip6 | No longer one-to-one, now one-to-many (`ForeignKey`). Remote side is now a list.
VRF | namespace | New required foreign key to Namespace, defaulting to 'Global'
Webhook | ca_file_path | No longer accepts `null` values, use `""` instead

### Renamed Database Fields

Most renamed database fields in Nautobot 2.0 fall into the following general categories:

1. Renaming of foreign keys and reverse relations to more consistently and specifically match the related model name or plural name (for example, `Circuit.terminations` to `Circuit.circuit_terminations`, `Rack.group` to `Rack.rack_group`)
2. Renaming of tree model fields for consistency and due to the change from `django-mptt` to `django-tree-queries` (for example, `InventoryItem.child_items` to `InventoryItem.children` and `InventoryItem.level` to `InventoryItem.tree_depth`)

Full table of renamed database fields

Model | Renamed Field | New Name
--- | --- | ---
CablePath | circuittermination | circuit_terminations
CablePath | consoleport | console_ports
CablePath | consoleserverport | console_server_ports
CablePath | interface | interfaces
CablePath | powerfeed | power_feeds
CablePath | poweroutlet | power_outlets
CablePath | powerport | power_ports
Circuit | termination_a | circuit_termination_a
Circuit | termination_z | circuit_termination_z
Circuit | terminations | circuit_terminations
Circuit | type | circuit_type
Cluster | group | cluster_group
Cluster | type | cluster_type
ComputedField | slug | key
ConfigContext | schema | config_context_schema
ConfigContextSchema | device_set | devices
ConfigContextSchema | virtualmachine_set | virtual_machines
ContentType | computedfield_set | computed_fields
ContentType | configcontext_set | config_contexts
ContentType | configcontextschema_set | config_context_schemas
ContentType | customlink_set | custom_links
ContentType | dcim_device_related | devices
ContentType | dynamicgroup_set | dynamic_groups
ContentType | exporttemplate_set | export_templates
ContentType | imageattachment_set | image_attachments
ContentType | note_set | notes
ContentType | virtualization_virtualmachine_related | virtual_machines
CustomFieldChoice | field | custom_field
CustomField | choices | custom_field_choices
CustomField | slug | key
Device | consoleports | console_ports
Device | consoleserverports | console_server_ports
Device | devicebays | device_bays
Device | device_role | role
Device | frontports | front_ports
Device | inventoryitems | inventory_items
Device | local_context_data | local_config_context_data
Device | local_context_data_owner_content_type | local_config_context_data_owner_content_type
Device | local_context_data_owner_object_id | local_config_context_data_owner_object_id
Device | local_context_schema | local_config_context_schema
Device | poweroutlets | power_outlets
Device | powerports | power_ports
Device | rearports | rear_ports
DeviceRedundancyGroup | members | devices
DeviceType | consoleporttemplates | console_port_templates
DeviceType | consoleserverporttemplates | console_server_port_templates
DeviceType | devicebaytemplates | device_bay_templates
DeviceType | frontporttemplates | front_port_templates
DeviceType | interfacetemplates | interface_templates
DeviceType | instances | devices
DeviceType | poweroutlettemplates | power_outlet_templates
DeviceType | powerporttemplates | power_port_templates
DeviceType | rearporttemplates | rear_port_templates
FrontPortTemplate | rear_port | rear_port_template
InventoryItem | child_items | children
InventoryItem | level | tree_depth
IPAddress | family | ip_version
IPAddress | prefix_length | mask_length
Job | job_hook | job_hooks
Job | result | job_results
JobResult | created | date_created
JobResult | completed | date_done
JobResult | job_kwargs | task_kwargs
JobResult | logs | job_log_entries
JobResult | schedule | scheduled_job
Location | powerpanels | power_panels
PowerOutletTemplate | power_port | power_port_template
PowerPanel | powerfeeds | power_feeds
PowerPort | poweroutlets | power_outlets
PowerPortTemplate | poweroutlet_templates | power_outlet_templates
Prefix | family | ip_version
Rack | group | rack_group
Rack | powerfeed_set | power_feeds
Rack | reservations | rack_reservations
RackGroup | level | tree_depth
RackGroup | powerpanel_set | power_panels
RearPort | frontports | front_ports
RearPortTemplate | frontport_templates | front_port_templates
Relationship | associations | relationship_associations
Relationship | name | label
Relationship | slug | key
RIR | aggregates | prefixes
Secret | groups | secrets_groups
Secret | secretsgroupassociation_set | secrets_group_associations
SecretsGroup | device_set | devices
SecretsGroup | deviceredundancygroup_set | device_redundancy_groups
SecretsGroup | gitrepository_set | git_repositories
SecretsGroup | secretsgroupassociation_set | secrets_group_associations
SecretsGroupAssociation | group | secrets_group
Service | ipaddresses | ip_addresses
Status | circuits_circuit_related | circuits
Status | dcim_cable_related | cables
Status | dcim_device_related | devices
Status | dcim_deviceredundancygroup_related | device_redundancy_groups
Status | dcim_interface_related | interfaces
Status | dcim_location_related | locations
Status | dcim_powerfeed_related | power_feeds
Status | dcim_rack_related | racks
Status | ipam_ipaddress_related | ip_addresses
Status | ipam_prefix_related | prefixes
Status | ipam_vlan_related | vlans
Status | virtualization_virtualmachine_related | virtual_machines
Status | virtualization_vminterface_related | vm_interfaces
Tenant | group | tenant_group
Tenant | rackreservations | rack_reservations
TenantGroup | level | tree_depth
User | changes | object_changes
User | note | notes
User | rackreservation_set | rack_reservations
VirtualMachine | local_context_data | local_config_context_data
VirtualMachine | local_context_data_owner_content_type | local_config_context_data_owner_content_type
VirtualMachine | local_context_data_owner_object_id | local_config_context_data_owner_object_id
VirtualMachine | local_context_schema | local_config_context_schema
VLAN | group | vlan_group

### Removed Database Fields

Most removed database fields in Nautobot 2.0 fall into the following general categories:

1. Removal of references to removed models such as `Site` and `Region`
2. Removal of `slug` fields in preference to the use of natural keys.
3. Removal of `django-mptt` internal fields (`lft`, `rght`, `tree_id`)

Full table of removed database fields

Model | Removed Field | Comments
--- | --- | ---
CircuitTermination | site | Use `location` instead
CircuitType | slug |
Cluster | site | Use `location` instead
ClusterGroup | slug |
ClusterType | slug |
ConfigContext | regions | Use `locations` instead
ConfigContext | sites | Use `locations` instead
ConfigContextSchema | slug |
CustomField | name | Use `label` or `key` as appropriate
CustomLink | slug |
Device | site | Use `location` instead
DeviceRedundancyGroup | slug |
DeviceType | slug |
DynamicGroup | slug |
GitRepository | _token | Use Secrets feature instead
GitRepository | username | Use Secrets feature instead
GraphQLQuery | slug |
InventoryItem | lft | Made irrelevant by `django-tree-queries`
InventoryItem | rght | Made irrelevant by `django-tree-queries`
InventoryItem | tree_id | Made irrelevant by `django-tree-queries`
IPAddress | assigned_object | Replaced by `interfaces` and `vm_interfaces` many-to-many relations
IPAddress | broadcast | Use parent Prefix's broadcast instead
IPAddress | vrf | VRF is now related to the assigned Interface(s), as well as the parent Prefix
Job | git_repository | Can be retrieved from the instance if desired, but is no longer a database field.
Job | slug |
Job | source | Now implied by the Job's `module_name` field.
JobHook | slug |
JobResult | job_id |
JobResult | obj_type |
Location | site |
Location | slug |
LocationType | slug |
Manufacturer | slug |
Note | slug |
Platform | slug |
Provider | slug |
ProviderNetwork | slug |
PowerFeed | site | Use `location` instead
PowerPanel | site | Use `location` instead
Prefix | is_pool | Replaced by new `type` field
Prefix | site | Use `location` instead
Prefix | vrf | Replaced by `vrf_assignments` many-to-many relation
Rack | site | Use `location` instead
RackGroup | lft | Made irrelevant by `django-tree-queries`
RackGroup | rght | Made irrelevant by `django-tree-queries`
RackGroup | site | Use `location` instead
RackGroup | slug |
RackGroup | tree_id | Made irrelevant by `django-tree-queries`
RIR | slug |
RelationshipAssociation | slug |
RouteTarget | slug |
ScheduledJob | job_class | Use `task` instead
Secret | slug |
SecretsGroup | slug |
SecretsGroupAssociation | slug |
Status | slug |
Tag | slug |
Tenant | slug |
TenantGroup | lft | Made irrelevant by `django-tree-queries`
TenantGroup | rght | Made irrelevant by `django-tree-queries`
TenantGroup | slug |
TenantGroup | tree_id | Made irrelevant by `django-tree-queries`
VLAN | site | Use `location` instead
VLANGroup | site | Use `location` instead
VLANGroup | slug |
VRF | enforce_unique | Uniqueness of Prefixes and IPAddresses is now enforced by the database
Webhook | slug |

Info

For more information on how to update your integrations after the removal of `slug` fields, see Uniquely Identifying a Nautobot Object.

### Replaced Models

#### Generic Role Model

The `ipam.Role`, `dcim.RackRole`, and `dcim.DeviceRole` models have been removed and replaced by a single `extras.Role` model. This means that any references to the removed models in the code now use the `extras.Role` model instead.

Removed Model | Replaced With
--- | ---
`dcim.DeviceRole` | `extras.Role`
`dcim.RackRole` | `extras.Role`
`ipam.Role` | `extras.Role`

#### Site and Region Models

The `dcim.Region` and `dcim.Site` models have been removed and replaced by `dcim.Location` model. This means that any references to the removed models in the code now use the `dcim.Location` model instead with `LocationType` "Site" and "Region".

Important

If you are a Nautobot App developer, or have any Apps installed that include data models that reference `Site` or `Region`, please review the Region and Site Related Data Model Migration Guide to learn how to migrate your apps and models from `Site` and `Region` to `Location`.

Removed Model | Replaced With
--- | ---
`dcim.Region` | `dcim.Location`
`dcim.Site` | `dcim.Location`

#### Aggregate Migrated to Prefix

The `ipam.Aggregate` model has been removed and all existing Aggregates will be migrated to `ipam.Prefix` records with their `type` set to "Container". The `Aggregate.date_added` field will be migrated to `Prefix.date_allocated` and changed from a Date field to a DateTime field with the time set to `00:00` UTC. `Aggregate.tenant`, `Aggregate.rir` and `Aggregate.description` will be migrated over to the equivalent fields on the new `Prefix`. ObjectChanges, Tags, Notes, Permissions, Custom Fields, Custom Links, Computed Fields and Relationships will be migrated to relate to the new `Prefix` as well.

If a `Prefix` already exists with the same network and prefix length as a previous `Aggregate`, the `rir` and `date_added` fields will be copied to the `rir` and `date_allocated` fields on the existing Prefix object. Messages will be output during migration (`nautobot-server migrate` or `nautobot-server post_upgrade`) if the `tenant`, `description` or `type` fields need to be manually migrated.

Aggregate | Prefix
--- | ---
`broadcast` | `broadcast`
`date_added` | `date_allocated`
`description` | `description`
`network` | `network`
`prefix_length` | `prefix_length`
`rir` | `rir`
`tenant` | `tenant`

### Prefix Parenting Concrete Relationship

The `ipam.Prefix` model has been modified to have a self-referencing foreign key as the `parent` field. Parenting of prefixes is now automatically managed at the database level to greatly improve performance especially when calculating tree hierarchy and utilization.

As a result of this change, it is no longer necessary nor possible to disable tree hierarchy using `settings.DISABLE_PREFIX_LIST_HIERARCHY` as this setting has been removed. Additionally it is no longer possible to disable global uniqueness using `settings.ENFORCE_GLOBAL_UNIQUE` as this setting has been removed.

The following changes have been made to the `Prefix` model.

Removed | Replaced With
--- | ---
`get_child_prefixes()` | `descendants()`

#### Prefix Parenting Guidance

The following guidance has been added for the `Prefix` model in order to ensure more accurate network modeling:

- A `Prefix` of type `Container` should only have a parent (if any) of type `Container`
- A `Prefix` of type `Network` should only have a parent (if any) of type `Container`
- A `Prefix` of type `Pool` should only have a parent (if any) of type `Network`
- Any `Prefix` can be a root prefix (i.e. have no parent)

In Nautobot 2.0, creating or updating prefixes that violate this guidance will result in a warning; in a future Nautobot release this will be changed to an enforced data constraint.

### IPAddress Parenting Concrete Relationship

The `ipam.IPAddress` model has been modified to have a foreign key to `ipam.Prefix` as the `parent` field. Parenting of IP addresses is now automatically managed at the database level to greatly improve performance especially when calculating tree hierarchy and utilization.

#### IPAddress Parenting Guidance

The following guidance has been added to the `IPAddress` model:

- An `IPAddress` should have a parent `Prefix` of type `Network`
- An `IPAddress` should not be created if a suitable parent `Prefix` of type `Network` does not exist
- An `IPAddress` can be a member of a `Pool` but only if the `Pool` is a child of a `Network`

As with the `Prefix` parenting guidance above, violating this guidance in Nautobot 2.0 will result in a warning; in a future Nautobot release this will be changed to an enforced data constraint.

### Prefix get_utilization Method

The `get_utilization` method on the `ipam.Prefix` model has been updated in 2.0 to account for the `Prefix.type` field. The behavior is now as follows:

- If the `Prefix.type` is `Container`, the utilization is calculated as the sum of the total address space of all child prefixes.
- If the `Prefix.type` is `Pool`, the utilization is calculated as the sum of the total number of IP addresses within the pool's range.
- If the `Prefix.type` is `Network`:
  - The utilization is calculated as the sum of the total address space of all child `Pool` prefixes plus the total number of child IP addresses.
  - For IPv4 networks larger than /31, if neither the first or last address is occupied by either a pool or an IP address, they are subtracted from the total size of the prefix.

#### Example

- 192.168.0.0/16 `Container - 1024/65536 utilization`
  - 192.168.1.0/24 `Network - 1/254 utilization`
    - 192.168.1.1 `IP Address`
  - 192.168.2.0/24 `Network - 4/256 utilization`
    - 192.168.2.0/30 `Pool - 1/4 utilization`
      - 192.168.2.1 `IP Address`
  - 192.168.3.0/24 `Network - 5/254 utilization`
    - 192.168.3.1 `IP Address`
    - 192.168.3.64/30 `Pool - 0/4 utilization`
  - 192.168.4.0/24 `Network - 1/256 utilization`
    - 192.168.4.255 `IP Address`

## GraphQL and REST API Changes

### API Behavior Changes

Most of the API behavior changes in Nautobot 2.0 fall into the following general categories:

1. The `created` field on most models has changed from a date only ("2023-04-06") to being a date/time ("2023-04-06T19:57:45.320232Z")
2. The `status` fields on various models has changed from a pseudo-enum value (containing a "value" and a "label") to referencing the related Status object in full, similar to other foreign-key fields.
3. Various models that had a required `site` field and an optional `location` field now have a required `location` field.

Full table of API behavior changes

Model | Field | Changes
--- | --- | ---
(all) | created | Now is a date/time rather than only a date
Cable | status | Now is a foreign-key rather than a pseudo-enum
Circuit | status | Now is a foreign-key rather than a pseudo-enum
Device | config_context | Now is only included when specifically requested with `?include=config_context` query parameter
Device | location | Now required, no longer optional
Device | status | Now is a foreign-key rather than a pseudo-enum
DeviceRedundancyGroup | status | Now is a foreign-key rather than a pseudo-enum
Interface | status | Now is a foreign-key rather than a pseudo-enum
IPAddress | namespace | A derived field. Required on creation, if `parent` isn't provided, to find a correct parent Prefix
IPAddress | parent | A new foreign-key to `Prefix`. Required on creation, if `namespace` isn't provided, to find a correct parent Prefix
IPAddress | role | Now is a foreign-key to `Role` rather than a string
IPAddress | status | Now is a foreign-key rather than a pseudo-enum
JobLogEntry | display | Now contains the message text rather than the message timestamp
Location | status | Now is a foreign-key rather than a pseudo-enum
PowerFeed | status | Now is a foreign-key rather than a pseudo-enum
PowerPanel | location | Now required, no longer optional
Prefix | namespace | New required foreign key to Namespace, defaulting to 'Global'
Prefix | status | Now is a foreign-key rather than a pseudo-enum
Rack | location | Now required, no longer optional
Rack | status | Now is a foreign-key rather than a pseudo-enum
RackGroup | location | Now required, no longer optional
RackGroup | rack_count | Now only counts Racks directly belonging to this RackGroup, not those belonging to its descendants
TenantGroup | tenant_count | Now only counts Tenants directly belonging to this TenantGroup, not those belonging to its descendants
VirtualMachine | status | Now is a foreign-key rather than a pseudo-enum
VLAN | status | Now is a foreign-key rather than a pseudo-enum
VMInterface | status | Now is a foreign-key rather than a pseudo-enum
VRF | namespace | New required foreign key to Namespace, defaulting to 'Global'

### Renamed Serializer Fields

Most renamed API fields in Nautobot 2.0 fall into the following general categories:

1. Renaming of foreign keys and reverse relations to more consistently and specifically match the related model name or plural name (for example, `Circuit.type` to `Circuit.circuit_type`, `Interface.count_ipaddresses` to `Interface.ip_address_count`)
2. Renaming of tree model fields for consistency and due to the change from `django-mptt` to `django-tree-queries` (for example, `InventoryItem._depth` to `InventoryItem.tree_depth`)

Full table of renamed API fields

Model | Renamed Field | New Name
--- | --- | ---
Circuit | termination_a | circuit_termination_a
Circuit | termination_z | circuit_termination_z
Circuit | type | circuit_type
ConfigContext | schema | config_context_schema
Cluster | group | cluster_group
Cluster | type | cluster_type
ComputedField | slug | key
CustomField | slug | key
CustomFieldChoice | field | custom_field
Device | device_role | role
Device | local_context_data | local_config_context_data
Device | local_context_schema | local_config_context_schema
Device | parent_device | parent_bay
FrontPortTemplate | rear_port | rear_port_template
Interface | count_ipaddresses | ip_address_count
InventoryItem | _depth | tree_depth
IPAddress | family | ip_version
IPAddress | prefix_length | mask_length
JobResult | created | date_created
JobResult | completed | date_done
JobResult | job_kwargs | task_kwargs
JobResult | schedule | scheduled_job
Location | virtualmachine_count | virtual_machine_count
Manufacturer | devicetype_count | device_type_count
Manufacturer | inventoryitem_count | inventory_item_count
Platform | virtualmachine_count | virtual_machine_count
PowerOutletTemplate | power_port | power_port_template
PowerPanel | powerfeed_count | power_feed_count
Prefix | family | ip_version
Rack | group | rack_group
Rack | powerfeed_count | power_feed_count
RackGroup | _depth | tree_depth
Relationship | name | label
Relationship | slug | key
SecretsGroupAssociation | group | secrets_group
Service | ipaddresses | ip_addresses
Tenant | group | tenant_group
TenantGroup | _depth | tree_depth
VirtualMachine | local_context_data | local_config_context_data
VirtualMachine | local_context_schema | local_config_context_schema
VLAN | group | vlan_group

### Removed Serializer Fields

Most removed database fields in Nautobot 2.0 fall into the following general categories:

1. Removal of references to removed models such as `Site` and `Region`
2. Removal of `slug` fields in preference to the use of natural keys.

Full table of removed API fields

Model/Endpoint | Removed Field | Comments
--- | --- | ---
/api/plugins/installed-plugins | verison | Use `version` instead
/api/status/ | rq-workers-running | Django-RQ is no longer supported
CircuitTermination | site | Use `location` instead
CircuitType | slug |
Cluster | site | Use `location` instead
ClusterGroup | slug |
ClusterType | slug |
ConfigContext | regions | Use `locations` instead
ConfigContext | sites | Use `locations` instead
ConfigContextSchema | slug |
CustomLink | slug |
Device | primary_ip | Use `primary_ip4` or `primary_ip6`instead
Device | site | Use `location` instead
DeviceRedundancyGroup | slug |
DeviceType | slug |
DynamicGroup | slug |
GitRepository | token | Use Secrets instead
GitRepository | username | Use Secrets instead
GraphQLQuery | slug |
IPAddress | assigned_object | Changed to many-to-many field. Use the REST API view for `IPAddressToInterface`(/api/ipam/ip-address-to-interface/) to create/modify/delete associations or `interfaces`/`vm_interfaces` on this model to retrieve a list of associated interfaces.
IPAddress | broadcast | Use parent Prefix's broadcast instead
IPAddress | vrf | VRF is now related to the assigned Interface(s), as well as the parent Prefix
JobHook | slug |
JobResult | job_id |
JobResult | obj_type |
Location | site | Use `parent` instead
Location | slug |
LocationType | slug |
Manufacturer | slug |
Note | slug |
Platform | slug |
PowerFeed | site | Use `location` instead
PowerPanel | site | Use `location` instead
Prefix | is_pool | Use `type` instead
Prefix | vrf | Prefixes are now assigned to a VRF in the same Namespace via a many-to-many relationship
Prefix | site | Use `location` instead
Provider | slug |
ProviderNetwork | slug |
Rack | site | Use `location` instead
RackGroup | site | Use `location` instead
RackGroup | slug |
RelationshipAssociation | slug |
RIR | slug |
Role | slug |
RouteTarget | slug |
Secret | slug |
SecretsGroup | slug |
SecretsGroupAssociation | slug |
Status | slug |
Tag | slug |
Tenant | slug |
TenantGroup | slug |
VirtualMachine | primary_ip | Use `primary_ip4` or `primary_ip6`instead
VLAN | site | Use `location` instead
VLANGroup | site | Use `location` instead
VLANGroup | slug |
VRF | enforce_unique | Uniqueness of Prefixes and IPAddresses is now enforced at the database level
Webhook | slug |

### Removed 1.X Version Endpoints and Serializer Representations

Nautobot 2.0 removes support for 1.X versioned REST APIs and their Serializers. Requesting older API versions will result in a `400 Bad Request` error.

Please ensure you are using the latest representations of request/response representations as seen in the API docs or Swagger.

### Replaced Endpoints

These endpoints `/ipam/roles/`, `/dcim/rack-roles/` and `/dcim/device-roles/` are no longer available. Instead, use the `/extras/roles/` endpoint to retrieve and manipulate `role` data.

Removed Endpoints | Replaced With
--- | ---
`/dcim/device-roles/` | `/extras/roles/`
`/dcim/rack-roles/` | `/extras/roles/`
`/ipam/roles/` | `/extras/roles/`

### New Interface to IP Address Relationship Endpoint

The through table (`ipam.IPAddressToInterface`) for the `IPAddress` to `Interface`/`VMInterface` many-to-many relationship has been exposed through the REST API at `/api/ipam/ip-address-to-interface/`. This endpoint must be used to create, retrieve, update, and delete relationships between IP addresses and interfaces through the REST API. Each `ipam.IPAddressToInterface` object maps a single `ipam.IPAddress` object to a single `dcim.Interface` or `virtualization.VMInterface` object. When creating relationships through this endpoint, the `ip_address` field is required and one of `interface` or `vm_interface` is required. There are additional boolean fields (`is_primary`, `is_default`, etc.) exposed through the REST API that may be used if desired but are not currently implemented in the Nautobot UI.

### API Query Parameters Changes

Nautobot 2.0 removes the `?brief` query parameter and adds support for the `?depth` query parameter. 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. Please see the documentation on the `?depth` query parameter for more information.

## UI, GraphQL, and REST API Filter Changes

Warning

Sweeping changes were made to model filter fields. In some cases this may invalidate or make subtle changes to existing `DynamicGroup`, `GraphQLQuery` or `Relationship` instances' filter data. Please utilize the `nautobot-server audit_dynamic_groups` and `nautobot-server audit_graphql_queries` helper commands when you are cleaning up `DynamicGroup` and `GraphQLQuery` filter data. You should run this command after your Nautobot instance is upgraded to v2.x successfully. The helper commands will not catch all possible issues, but they will catch some common ones. You should review all of your `DynamicGroup` filter data and `GraphQLQuery` query data after the upgrade to ensure that they are still valid. At the time of this writing, an audit helper command for `Relationship` filter data is not yet available.

### Removed Changelog URL from View Context

`changelog_url` is no longer provided in the `ObjectView` context. To get a model instance's changelog URL, you can retrieve it from the instance itself if it supports it: `model_instance.get_changelog_url()`.

### Renamed Filter Fields

Most renamed filter fields in Nautobot 2.0 fall into the following general categories:

1. The `tag` filter is renamed to `tags` on all models supporting Tags.
2. Renames to match renamed model/serializer fields as described earlier in this document.
3. Related membership filters are renamed to `has_<related>` throughout, for example `ConsolePort.cabled` is renamed to `ConsolePort.has_cable`.
4. Most `<related>_id` filters have been merged into the corresponding `<related>` filter (see "Enhanced Filter Fields" below).

Full table of renamed filter fields

Model | Renamed Filter | New Name
--- | --- | ---
Cable | tag | tags
Circuit | tag | tags
Circuit | type | circuit_type
Cluster | tag | tags
ComputedField | slug | key
ConsolePort | cabled | has_cable
ConsoleServerPort | cabled | has_cable
CustomFieldChoice | field | custom_field
Device | cluster_id | cluster
Device | device_type_id | device_type
Device | local_context_data | local_config_context_data
Device | local_context_schema_id | local_config_context_schema_id
Device | local_context_schema | local_config_context_schema
Device | rack_group_id | rack_group
Device | rack_id | rack
Device | tag | tags
Device | virtual_chassis_id | virtual_chassis
DeviceBay | tag | tags
DeviceRedundancyGroup | tag | tags
DeviceType | has_instances | has_devices
DeviceType | instances | devices
DeviceType | tag | tags
FrontPort | cabled | has_cable
FrontPort | tag | tags
GitRepository | tag | tags
Interface | cabled | has_cable
Interface | tag | tags
InventoryItem | child_items | children
InventoryItem | has_child_items | has_children
InventoryItem | tag | tags
IPAddress | assigned_to_interface | has_interface_assignments
IPAddress | family | ip_version
IPAddress | parent | prefix
IPAddress | tag | tags
IPAddress | vrf | vrfs
Job | tag | tags
Location | tag | tags
ObjectPermission | group | groups
ObjectPermission | group_id | groups_id
ObjectPermission | user | users
PowerFeed | cabled | has_cable
PowerFeed | tag | tags
PowerOutlet | cabled | has_cable
PowerPanel | tag | tags
PowerPort | cabled | has_cable
Prefix | family | ip_version
Prefix | is_pool | type
Prefix | mask_length | prefix_length
Prefix | tag | tags
Prefix | vrf | vrfs
Provider | tag | tags
ProviderNetwork | tag | tags
Rack | group | rack_group
Rack | has_reservations | has_rack_reservations
Rack | reservations | rack_reservations
Rack | tag | tags
RackReservation | group | rack_group
RackReservation | tag | tags
RearPort | cabled | has_cable
RearPort | tag | tags
Relationship | name | label
Relationship | slug | key
RouteTarget | exporting_vrf | exporting_vrfs
RouteTarget | importing_vrf | importing_vrfs
RouteTarget | tag | tags
SecretsGroupAssociation | group | secrets_group
Service | port | ports
Service | tag | tags
Tenant | group | tenant_group
Tenant | tag | tags
User | changes | object_changes
User | has_changes | has_object_changes
User | group | groups
User | group_id | groups_id
VirtualMachine | local_context_data | local_config_context_data
VirtualMachine | local_context_schema_id | local_config_context_schema_id
VirtualMachine | local_context_schema | local_config_context_schema
VirtualMachine | tag | tags
VLAN | group | vlan_group
VLAN | tag | tags
VMInterface | tag | tags
VRF | export_target | export_targets
VRF | import_target | import_targets
VRF | tag | tags

### Enhanced Filter Fields

Below is a table documenting enhanced filter field changes in Nautobot 2.0. These enhancements mostly fall into the following general categories:

1. Many filters are enhanced to permit filtering by UUID or by name.
2. Filters that previously only supported a single filter value can now filter on multiple values.

Full table of enhanced filter fields

Model | Filter | Enhancements
--- | --- | ---
(all) | created[__(gte/lte)] | Filtering on multiple values, supports date-times
Cable | tenant | Filter by UUID or by name
Circuit | circuit_type | Filter by UUID or by name
Circuit | provider | Filter by UUID or by name
Circuit | tenant | Filter by UUID or by name
Circuit | tenant_group | Filter by UUID or by name
Cluster | cluster_group | Filter by UUID or by name
Cluster | cluster_type | Filter by UUID or by name
Cluster | tenant | Filter by UUID or by name
Cluster | tenant_group | Filter by UUID or by name
ConfigContext | cluster_group | Filter by UUID or by name
ConfigContext | device_redundancy_group | Filter by UUID or by name
ConfigContext | dynamic_groups | Filter by UUID or by name
ConfigContext | platform | Filter by UUID or by name
ConfigContext | tenant | Filter by UUID or by name
ConfigContext | tenant_group | Filter by UUID or by name
ConsolePort | device | Filter by UUID or by name
ConsoleServerPort | device | Filter by UUID or by name
Device | cluster (formerly cluster_id) | Filter by UUID or by name
Device | device_redundancy_group | Filter by UUID or by name
Device | device_type (formerly device_type_id) | Filter by UUID or by model
Device | manufacturer | Filter by UUID or by name
Device | platform | Filter by UUID or by name
Device | role | Filter by UUID or by name
Device | rack | Filter by UUID or by name
Device | rack_group | Filter by UUID or by name
Device | serial | Filtering on multiple values
Device | secrets_group | Filter by UUID or by name
Device | virtual_chassis | Filter by UUID or by name
DeviceBay | device | Filter by UUID or by name
DeviceType | manufacturer | Filter by UUID or by name
DeviceRedundancyGroup | secrets_group | Filter by UUID or by name
DynamicGroupMembership | group | Filter by UUID or by name
DynamicGroupMembership | parent_group | Filter by UUID or by name
FrontPort | device | Filter by UUID or by name
GitRepository | secrets_group | Filter by UUID or by name
Interface | device | Filter by UUID or by name
InventoryItem | device | Filter by UUID or by name
InventoryItem | manufacturer | Filter by UUID or by name
InventoryItem | serial | Filtering on multiple values
IPAddress | mask_length | Filtering on multiple integer values
IPAddress | rir | Filter by UUID or by name
IPAddress | tenant | Filter by UUID or by name
IPAddress | tenant_group | Filter by UUID or by name
Manufacturer | platforms | Filter by UUID or by name
Platform | manufacturer | Filter by UUID or by name
PowerOutlet | device | Filter by UUID or by name
PowerPort | device | Filter by UUID or by name
Prefix | rir | Filter by UUID or by name
Prefix | tenant | Filter by UUID or by name
Prefix | tenant_group | Filter by UUID or by name
Prefix | vlan_vid | Filtering on multiple values
ProviderNetwork | provider | Filter by UUID or by name
Rack | role | Filter by UUID or by name
Rack | serial | Filtering on multiple values
RackGroup | parent | Filter by UUID or by name
RackReservation | tenant | Filter by UUID or by name
RackReservation | tenant_group | Filter by UUID or by name
RackReservation | user | Filter by UUID or by username
RearPort | device | Filter by UUID or by name
RouteTarget | tenant | Filter by UUID or by name
RouteTarget | tenant_group | Filter by UUID or by name
SecretsGroupAssociation | secret | Filter by UUID or by name
SecretsGroupAssociation | secrets_group | Filter by UUID or by name
Tenant | tenant_group | Filter by UUID or by name
TenantGroup | parent | Filter by UUID or by name
TenantGroup | children | Filter by UUID or by name
TenantGroup | tenants | Filter by UUID or by name
VirtualChassis | master | Filter by UUID or by name
VirtualChassis | tenant | Filter by UUID or by name
VirtualMachine | cluster_group | Filter by UUID or by name
VirtualMachine | cluster_type | Filter by UUID or by name
VirtualMachine | platform | Filter by UUID or by name
VirtualMachine | tenant | Filter by UUID or by name
VirtualMachine | tenant_group | Filter by UUID or by name
VLAN | available_on_device | Filtering on multiple values
VLAN | tenant | Filter by UUID or by name
VLAN | tenant_group | Filter by UUID or by name
VLAN | vlan_group | Filter by UUID or by name
VRF | tenant | Filter by UUID or by name
VRF | tenant_group | Filter by UUID or by name

### Corrected Filter Fields

Below is a table documenting corrected filter field changes in Nautobot 2.0. These corrections mostly involve filters that previously permitted filtering on related membership only (`/api/dcim/devices/?console_ports=True`) and have now been corrected into filters for related membership (`/api/dcim/devices/?has_console_ports=True`) as well as by actual related objects (`/api/dcim/devices/?console_ports=<UUID>`).

Full table of corrected filter fields

Model | Filter | Correction
--- | --- | ---
CustomFieldChoice | custom_field | Filter by UUID or key
Device | console_ports | Split into `has_console_ports` and `console_ports` filters
Device | console_server_ports | Split into `has_console_server_ports` and `console_server_ports` filters
Device | device_bays | Split into `has_device_bays` and `device_bays` filters
Device | front_ports | Split into `has_front_ports` and `front_ports` filters
Device | interfaces | Split into `has_interfaces` and `interfaces` filters
Device | power_outlets | Split into `has_power_outlets` and `power_outlets` filters
Device | power_ports | Split into `has_power_ports` and `power_ports` filters
Device | rear_ports | Split into `has_rear_ports` and `rear_ports` filters
IPAddress | parent | The `parent` filter now checks for an exact match of the parent Prefix; for legacy `net_host_contained` behavior now use the new `prefix` filter instead

### Removed Filter Fields

Below is a table documenting removed filter field changes in v2.x. Most removed database fields in Nautobot 2.0 fall into the following general categories:

1. Removal of `*_id=<uuid>` filters as they have have been merged into filters that support both uuid and name/slug (for example, instead of `/api/circuits/circuits/?provider_id=<UUID>`, use `/api/circuits/circuits/?provider=<uuid>`).
2. Removal of filtering on removed models such as `Region` and `Site`. (Use `location` filters instead.)
3. Removal of `slug` filters from models that no longer have a `slug` field.

Full table of removed filter fields

Model | Removed Filter | Comments
--- | --- | ---
Circuit | provider_id |
Circuit | provider_network_id |
Circuit | region |
Circuit | region_id |
Circuit | site |
Circuit | site_id |
Circuit | tenant_group_id |
Circuit | type_id |
CircuitTermination | circuit_id |
CircuitTermination | provider_network_id |
CircuitTermination | region_id |
CircuitTermination | region |
CircuitTermination | site_id |
CircuitTermination | site |
CircuitType | slug |
Cluster | region |
Cluster | region_id |
Cluster | site |
Cluster | site_id |
Cluster | tenant_group_id |
ClusterGroup | slug |
ClusterType | slug |
ConfigContext | region |
ConfigContext | region_id |
ConfigContext | role_id |
ConfigContext | site |
ConfigContext | site_id |
ConsolePort | device_id |
ConsolePort | region |
ConsolePort | region_id |
ConsolePort | site |
ConsolePort | site_id |
ConsoleServerPort | device_id |
ConsoleServerPort | region |
ConsoleServerPort | region_id |
ConsoleServerPort | site |
ConsoleServerPort | site_id |
CustomFieldChoice | field_id | Use `custom_field` filter
CustomLink | slug |
Device | manufacturer_id |
Device | model | Use `device_type` filter
Device | pass_through_ports | Use `has_front_ports` or `has_rear_ports` filters
Device | platform_id |
Device | region |
Device | region_id |
Device | role_id |
Device | secrets_group_id |
Device | site |
Device | site_id |
Device | tenant_group_id |
DeviceBay | device_id |
DeviceBay | region |
DeviceBay | region_id |
DeviceBay | site |
DeviceBay | site_id |
DeviceRedundancyGroup | slug |
DeviceType | manufacturer_id |
DeviceType | slug |
DynamicGroup | slug |
FrontPort | device_id |
FrontPort | region |
FrontPort | region_id |
FrontPort | site |
FrontPort | site_id |
GraphQLQuery | slug |
Interface | bridge_id |
Interface | device_id |
Interface | lag_id |
Interface | parent_interface_id |
Interface | region |
Interface | region_id |
Interface | site |
Interface | site_id |
InventoryItem | device_id |
InventoryItem | manufacturer_id |
InventoryItem | parent_id |
InventoryItem | region |
InventoryItem | region_id |
InventoryItem | site |
InventoryItem | site_id |
IPAddress | tenant_group_id |
Job | slug |
Job | source |
JobHook | slug |
Location | region |
Location | region_id |
Location | site |
Location | site_id |
Location | slug |
Location | tenant_group_id |
LocationType | slug |
Manufacturer | slug |
ObjectPermission | user_id | Use `users` filter
Platform | manufacturer_id |
Platform | slug |
PowerFeed | power_panel_id |
PowerFeed | rack_id |
PowerFeed | region |
PowerFeed | region_id |
PowerFeed | site |
PowerFeed | site_id |
PowerOutlet | device_id |
PowerOutlet | region |
PowerOutlet | region_id |
PowerOutlet | site |
PowerOutlet | site_id |
PowerPanel | rack_group_id |
PowerPanel | region |
PowerPanel | region_id |
PowerPanel | site |
PowerPanel | site_id |
PowerPort | device_id |
PowerPort | region |
PowerPort | region_id |
PowerPort | site |
PowerPort | site_id |
Prefix | region |
Prefix | region_id |
Prefix | site |
Prefix | site_id |
Prefix | vrf_id | Use vrf filter instead
Provider | region |
Provider | region_id |
Provider | site |
Provider | site_id |
Provider | slug |
ProviderNetwork | provider_id |
ProviderNetwork | slug |
Rack | group_id | Use `rack_group` filter
Rack | region |
Rack | region_id |
Rack | role_id |
Rack | site |
Rack | site_id |
Rack | tenant_group_id |
RackGroup | parent_id |
RackGroup | region |
RackGroup | region_id |
RackGroup | site |
RackGroup | site_id |
RackGroup | slug |
RackReservation | group_id | Use `rack_group` filter
RackReservation | rack_id |
RackReservation | site |
RackReservation | site_id |
RackReservation | tenant_group_id |
RackReservation | user_id |
RearPort | device_id |
RearPort | region |
RearPort | region_id |
RearPort | site |
RearPort | site_id |
RelationshipAssociation | slug |
RIR | slug |
RouteTarget | exporting_vrf_id | Use `exporting_vrfs` filter
RouteTarget | importing_vrf_id | Use `importing_vrfs` filter
RouteTarget | slug |
RouteTarget | tenant_group_id |
Secret | slug |
SecretsGroup | slug |
SecretsGroupAssociation | group_id | Use `secrets_group` filter
SecretsGroupAssociation | slug |
Service | device_id |
Service | virtual_machine_id |
Status | slug |
Tag | slug |
Tenant | aggregates | Use `prefixes` filter
Tenant | group_id | Use `tenant_group` filter
Tenant | has_aggregates | Use `has_prefixes` filter
Tenant | has_sites |
Tenant | sites |
Tenant | slug |
TenantGroup | parent_id |
TenantGroup | slug |
VirtualChassis | master_id |
VirtualChassis | region |
VirtualChassis | region_id |
VirtualChassis | site |
VirtualChassis | site_id |
VirtualChassis | tenant_id |
VirtualMachine | tenant_group_id |
VLAN | group_id | Use `vlan_group` filter
VLAN | region |
VLAN | region_id |
VLAN | site |
VLAN | site_id |
VLAN | tenant_group_id |
VLANGroup | region |
VLANGroup | region_id |
VLANGroup | site |
VLANGroup | site_id |
VLANGroup | slug |
VMInterface | bridge_id |
VMInterface | parent_interface_id |
VRF | tenant_group_id |
VRF | export_target_id | Use `export_targets` filter
VRF | import_target_id | Use `import_targets` filter
Webhook | slug |

## Python Code Location Changes

The below is mostly relevant only to authors of Jobs and Nautobot Apps. End users should not be impacted by the changes in this section. 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.models.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_in_query_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

## Removed Python Code

- Because of the replacement of the `?brief` REST API query parameter with `?depth` and the removal of all `Nested*Serializers`, some of the classes and mixins are removed because they are no longer needed.
- With the reimplementation of CSV import and export, `CSVForm` classes are generally no longer needed, and so a number of related mixin classes have been removed.

Full table of code removals

Module | Class/Function(s)
--- | ---
nautobot.apps.forms | StatusModelCSVFormMixin
nautobot.core.filters | NameSlugSearchFilterSet
nautobot.core.forms.utils | parse_csv
nautobot.core.forms.utils | validate_csv
nautobot.circuits.api.nested_serializers | (all)
nautobot.dcim.api.nested_serializers | (all)
nautobot.dcim.form_mixins | LocatableModelCSVFormMixin
nautobot.extras.api.customfields | CustomFieldModelSerializer
nautobot.extras.api.fields | RoleSerializerField
nautobot.extras.api.fields | StatusSerializerField
nautobot.extras.api.nested_serializers | (all)
nautobot.extras.api.serializers | RoleModelSerializerMixin
nautobot.extras.api.serializers | RoleRequiredRoleModelSerializerMixin
nautobot.extras.api.serializers | StatusModelSerializerMixin
nautobot.extras.api.serializers | TagSerializerField
nautobot.extras.api.serializers | TaggedObjectSerializer
nautobot.extras.constants | JOB_MAX_SOURCE_LENGTH
nautobot.extras.forms.mixins | RoleModelCSVFormMixin
nautobot.extras.forms.mixins | RoleRequiredRoleModelCSVFormMixin
nautobot.extras.forms.mixins | StatusModelCSVFormMixin
nautobot.extras.jobs | get_jobs
nautobot.extras.jobs | get_job_classpaths
nautobot.extras.plugins | PluginMenuButton
nautobot.extras.plugins | PluginMenuItem
nautobot.ipam.api.nested_serializers | (all)
nautobot.tenancy.api.nested_serializers | (all)
nautobot.users.api.nested_serializers | (all)
nautobot.virtualization.api.nested_serializers | (all)

## Renamed Python Code

The below is mostly relevant only to authors of Jobs and Nautobot Apps. End users should not be impacted by the changes in this section. Most of the code renames are only relevant to Job related classes.

Full table of code renames

Old Name | New Name
--- | ---
nautobot.extras.views.JobDetailView | nautobot.extras.views.JobView
nautobot.extras.views.JobView | nautobot.extras.views.JobRunView

## Git Data Source Changes

The Configuration Contexts Metadata key `schema` has been replaced with `config_context_schema`. This means that any `schema` references in your git repository's data must be updated to reflect this change.

`GitRepository` sync operations are now Jobs. As a result, when creating a new `GitRepository` it is not automatically synchronized. A `GitRepository.sync()` method has been implemented that will execute the sync job on a worker and return the `JobResult` for the operation. This method takes `dry_run` and `user` arguments. The `dry_run` argument defaults to `False`; if set to `True` will cause the sync to dry-run. The `user` argument is required if a sync is performed.

Additionally, the `GitRepository.save()` method no longer takes a `trigger_resync=<True|False>` argument as it is no longer required. The act of creating a new `GitRepository` no longer has side effects.

Below is a table documenting changes in names for Git-related Jobs. There should NOT be a need to ever manually execute the jobs due to the addition of `GitRepository.sync()`, but this is being provided for clarity.

Old Job Location | New Job Location
--- | ---
`nautobot.extras.datasources.git.pull_git_repository_and_refresh_data` | `nautobot.core.jobs.GitRepositorySync`
`nautobot.extras.datasources.git.git_repository_diff_origin_and_local` | `nautobot.core.jobs.GitRepositoryDryRun`

## Logging Changes

Where applicable, `logging.getLogger("some_arbitrary_name")` is replaced with `logging.getLogger(__name__)` or `logging.getLogger(__name__ + ".SpecificFeature")`.

Below is a table documenting changes in logger names that could potentially affect existing deployments with expectations around specific logger names used for specific purposes.

Full table of logger name changes

Old Name | New Name
--- | ---
nautobot.authentication | nautobot.core.authentication
nautobot.datasources.git | nautobot.extras.datasources.git
nautobot.datasources.utils | nautobot.extras.datasources.utils
nautobot.dcim.cable | nautobot.dcim.signals.cable
nautobot.graphql.generators | nautobot.core.graphql.generators
nautobot.graphql.schema | nautobot.core.graphql.schema
nautobot.jobs | nautobot.extras.jobs
nautobot.jobs.* | nautobot.extras.jobs.*
nautobot.releases | nautobot.core.releases, nautobot.utilities.tasks
nautobot.plugins | nautobot.extras.templatetags.plugins, nautobot.extras.plugins.utils
nautobot.views.* | nautobot.core.views.generic.*

## Job Database Model Changes

The Job `name` field has been changed to a unique field and the `name` + `grouping` uniqueness constraint has been removed. The processes that refresh jobs (`nautobot-server post_upgrade` and `nautobot-server migrate`) have been updated to gracefully handle duplicate job names.

Example

    class NautobotJob1(Job):
        class Meta:
            name = "Sample job"

    class NautobotJob2(Job):
        class Meta:
            name = "Sample job"

These jobs would be named `Sample job` and `Sample job (2)`

The Job `slug`, `source` and `git_repository` fields have been removed. The Job `module_name` field will automatically be updated, for Jobs derived from a Git repository, from `<submodule_name>` to `<git_repository_slug>.jobs.<submodule_name>`. This also changes the secondary uniqueness constraint for Jobs to simply `[module_name, job_class_name]`.

The Job `class_path` attribute has been simplified correspondingly, to simply `<module>.<ClassName>` instead of the former `<source>/<module>/<ClassName>`. For example, the Nautobot Golden Config backup job's `class_path` will change from `plugins/nautobot_golden_config.jobs/BackupJob` to `nautobot_golden_config.jobs.BackupJob`.

The Job `commit_default` field has been renamed to `dryrun_default` and the default value has been changed from `True` to `False`. This change is a result of the fundamental job changes mentioned in the Job Changes section below.

## JobResult Database Model Changes

The `JobResult` objects for which results from Job executions are stored are now automatically managed. Therefore job authors must never manipulate or `save()` these objects as they are now used internally for all state transitions and saving the objects yourself could interfere with and cause Job execution to fail or cause data loss.

Therefore all code that is calling `JobResult.set_status()` (which has been removed) or `JobResult.save()` must be removed.

## Job Changes

### Migrating Jobs From v1 to v2

Changed in version 2.0.0

See Migrating Jobs From Nautobot v1 for more information on how to migrate your existing jobs to Nautobot v2.

### Fundamental Changes

Changed in version 2.2.3

In Nautobot 2.0.0 through 2.2.2, Nautobot's `BaseJob` class was made to be a subclass of Celery's `Task` class. The implications of this change are outside the scope of this document, but this change has been reverted in Nautobot 2.2.3 and later.

- The `test_*` and `post_run` methods for backwards compatibility to NetBox scripts and reports were removed. In their place, Nautobot Jobs now have `before_start`, `on_success`, `on_failure`, and `after_return` methods that can be used by job authors to perform similar functions.

Important

Be sure to call the `super()` method when overloading any of the job's `before_start`, `on_success`, `on_retry`, `on_failure`, or `after_return` methods

- The `run` method signature now includes each of the input variables defined on the Job. This means that the `data` and `commit` arguments are no longer passed to the job by default and the job's run method signature should match the the job's input variables.

Example

    class ExampleJob(Job):
        var1 = StringVar()
        var2 = IntegerVar(required=True)
        var3 = BooleanVar()
        var4 = ObjectVar(model=Role)

        def run(self, *, var1, var2, var3, var4):
            ...

### Database Transactions

Nautobot no longer wraps the job `run` method in an atomic database transaction. As a result, jobs that need to roll back database changes will have to decorate the run method with `@transaction.atomic` or use the `with transaction.atomic()` context manager in the job code.

With the removal of the atomic transaction, the `commit` flag has been removed. The ability to bypass job approval on dryrun can be achieved by using an optional `dryrun` argument. Job authors who wish to allow users to bypass approval when the `dryrun` flag is set should set a `dryrun` attribute with a value of `DryRunVar()` on their job class. `DryRunVar` can be imported from `nautobot.extras.jobs`.

Example

    ```py
    from nautobot.extras.jobs import DryRunVar, Job

    class ExampleJob(Job):
        dryrun = DryRunVar()

        def run(self, dryrun):
            ...
    ```

A new `supports_dryrun` field has been added to the `Job` model and `Job` class that returns true if the `Job` class implements the `dryrun = DryRunVar()` attribute. This is used to determine if jobs that require approval can be dry run without prior approval.

The `commit_default` job field has been renamed to `dryrun_default` and the default value has been changed from `True` to `False`.

Important

The `read_only` job field no longer changes the behavior of Nautobot core and is left to the job author to decide whether their job is read only.

Important

Nautobot no longer enforces any job behavior when dryrun is set. It is now the job author's responsibility to define and enforce the execution of a "dry run".

### Request Property

The `request` property has been changed to a Celery request instead of a Django web request and no longer includes the information from the web request that initiated the Job. The `user` object is now available as `self.user` instead of `self.request.user`.

### URL Changes

The Job URL path `jobs/results/<uuid:pk>/` and URL pattern name `job_jobresult` are removed. Use URL path `job-results/<uuid:pk>/` and URL pattern name `jobresult` instead. Any `extras:job_jobresult` references should be removed and be replaced by `extras:jobresult`.

The Job URL path `/extras/jobs/<str:class_path>/` and associated URL pattern name `extras:job` are changed to URL path `/extras/jobs/<str:class_path>/run/` and the URL pattern is renamed to `extras:job_run_by_class_path`. Conversely, the Job detail view URL pattern name `extras:job_detail` has been renamed to `extras:job` for consistency with other object detail view URL patterns.

### Function Changes

Changed `as_form_class`, `as_form` and `validate_data` functions on `BaseJob` Model to `classmethods` so that they can be called directly from the class without needing to instantiate the Job in order to access them.

### Function Renames

`JobDetailView` is renamed to `JobView`.

`JobView` is renamed to `JobRunView`.

## Settings Changes

### Added Settings

These settings are new in Nautobot 2.0 and can be changed in your `nautobot_config.py` file or via environment variables if desired:

- `CELERY_WORKER_REDIRECT_STDOUTS` (env: `NAUTOBOT_CELERY_WORKER_REDIRECT_STDOUTS`)
- `CELERY_WORKER_REDIRECT_STDOUTS_LEVEL` (env: `NAUTOBOT_CELERY_WORKER_REDIRECT_STDOUTS_LEVEL`)

### Removed Settings

These settings are no longer in use and should be removed from your `nautobot_config.py` file and environment variables if present:

- `CACHEOPS_DEFAULTS` (env: `NAUTOBOT_CACHEOPS_TIMEOUT`)
- `CACHEOPS_ENABLED` (env: `NAUTOBOT_CACHEOPS_ENABLED`)
- `CACHEOPS_HEALTH_CHECK_ENABLED`
- `CACHEOPS_REDIS` (env: `NAUTOBOT_CACHEOPS_REDIS`)
- `CACHEOPS_SENTINEL`
- `DISABLE_PREFIX_LIST_HIERARCHY`
- `ENFORCE_GLOBAL_UNIQUE` (env: `NAUTOBOT_ENFORCE_GLOBAL_UNIQUE`)
- `RQ_QUEUES`

### Changed Settings

These settings are no longer user servicable and should be removed from your `nautobot_config.py` file and environment variables if present:

- `CELERY_RESULT_BACKEND` (env: `NAUTOBOT_CELERY_RESULT_BACKEND`)
- `CELERY_RESULT_BACKEND_TRANSPORT_OPTIONS`