diff --git a/docs/plugins/development/migration-v4.md b/docs/plugins/development/migration-v4.md new file mode 100644 index 000000000..8dbf7d21b --- /dev/null +++ b/docs/plugins/development/migration-v4.md @@ -0,0 +1,222 @@ +# Migrating Your Plugin to NetBox v4.0 + +This document serves as a handbook for maintainers of plugins that were written prior to the release of NetBox v4.0. It serves to capture all the changes recommended to ensure a plugin is compatible with NetBox v4.0 and later releases. + +## General + +### Python 3.10+ required + +NetBox v4.0 drops support for Python 3.8 and 3.9. You may need to update your CI/CD processes to reflect this. + +### Plugin resources relocated + +All plugin Python resources were moved from `extras.plugins` to `netbox.plugins` in NetBox v3.7 (see [#14036](https://github.com/netbox-community/netbox/issues/14036)), and support for importing these resources from their old locations has been removed. + +```python title="Old" +from extras.plugins import PluginConfig +``` + +```python title="New" +from netbox.plugins import PluginConfig +``` + +### ContentType renamed to ObjectType + +NetBox's proxy model for Django's [ContentType model](https://docs.djangoproject.com/en/5.0/ref/contrib/contenttypes/#the-contenttype-model) has been renamed to ObjectType for clarity. In general, plugins should use the ObjectType proxy when referencing content types, as it includes several custom manager methods. The one exception to this is when defining [generic foreign keys](https://docs.djangoproject.com/en/5.0/ref/contrib/contenttypes/#generic-relations): The ForeignKey field used for a GFK should point to Django's native ContentType. + +Additionally, plugin maintainers are strongly encouraged to adopt the "object type" terminology for field and filter names wherever feasible to be consistent with NetBox core (however this is not required for compatibility). + +```python title="Old" +content_types = models.ManyToManyField( + to='contenttypes.ContentType', + related_name='event_rules' +) +``` + +```python title="New" +object_types = models.ManyToManyField( + to='core.ObjectType', + related_name='event_rules' +) +``` + +## Views + +### View actions must be dictionaries + +The format for declaring view actions & permissions was updated in NetBox v3.7 (see [#13550](https://github.com/netbox-community/netbox/issues/13550)), and NetBox v4.0 drops support for the old format. Views which inherit `ActionsMixin` must declare a single `actions` map. + +```python title="Old" +actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete') +action_perms = defaultdict(set, **{ + 'add': {'add'}, + 'import': {'add'}, + 'bulk_edit': {'change'}, + 'bulk_delete': {'delete'}, +}) +``` + +```python title="New" +actions = { + 'add': {'add'}, + 'import': {'add'}, + 'export': set(), + 'bulk_edit': {'change'}, + 'bulk_delete': {'delete'}, +} +``` + +## Forms + +### Remove `BootstrapMixin` + +The `BootstrapMixin` class is no longer available or needed and can be removed from all forms. + +```python title="Old" +from django import forms +from utilities.forms import BootstrapMixin + +class MyForm(BootstrapMixin, forms.Form): +``` + +```python title="New" +from django import forms + +class MyForm(forms.Form): +``` + +## Navigation + +### Remove button colors + +NetBox no longer applies color to buttons within navigation menu items. Although this functionality is still supported, you might want to remove color from any buttons to ensure consistency with the updated design. + +```python title="Old" +PluginMenuButton( + link='myplugin:foo_add', + title='Add a new Foo', + icon_class='mdi mdi-plus-thick', + color=ButtonColorChoices.GREEN +) +``` + +```python title="New" +PluginMenuButton( + link='myplugin:foo_add', + title='Add a new Foo', + icon_class='mdi mdi-plus-thick' +) +``` + +## UI Layout + +### Renamed template blocks + +The following template blocks have been renamed or removed: + +| Template | Old name | New name | +|---------------------|-------------------|---------------------------| +| generic/object.html | `header` | `page-header` | +| generic/object.html | `controls` | `control-buttons` | +| base/layout.html | `content-wrapper` | _Removed_ (use `content`) | + +### Utilize flex controls + +Ditch any legacy "float" controls (e.g. `float-end`) in favor of Bootstrap's new [flex behaviors](https://getbootstrap.com/docs/5.3/utilities/flex/) for controlling the layout and sizing of elements horizontally. For example, the following will align two items against the left and right sides of the parent element: + +```html +