Compare commits

...

3 Commits

Author SHA1 Message Date
Jeremy Stretch
5bf34b0c32 Reorder import statements 2025-12-05 14:28:13 -05:00
Jeremy Stretch
0319fd599a Add register_filterset() to plugins documentation for filtersets 2025-12-05 14:22:45 -05:00
Jeremy Stretch
6c94d8d49b Move register_filterset() back to utilities.filtersets 2025-12-05 14:15:52 -05:00
14 changed files with 42 additions and 28 deletions

View File

@@ -6,12 +6,17 @@ Filter sets define the mechanisms available for filtering or searching through a
To support additional functionality standard to NetBox models, such as tag assignment and custom field support, the `NetBoxModelFilterSet` class is available for use by plugins. This should be used as the base filter set class for plugin models which inherit from `NetBoxModel`. Within this class, individual filters can be declared as directed by the `django-filters` documentation. An example is provided below.
!!! info "New in NetBox v4.5: FilterSet Registration"
NetBox v4.5 introduced the `register_filterset()` utility function. This enables plugins to register their filtersets to receive advanced functionality, such as the automatic attachment of field-specific lookup modifiers on the filter form. Registration is optional: Unregistered filtersets will continue to work as before, but will not receive the enhanced functionality.
```python
# filtersets.py
import django_filters
from netbox.filtersets import NetBoxModelFilterSet
from utilities.filtersets import register_filterset
from .models import MyModel
@register_filterset
class MyFilterSet(NetBoxModelFilterSet):
status = django_filters.MultipleChoiceFilter(
choices=(
@@ -42,7 +47,7 @@ class MyModelListView(ObjectListView):
filterset = MyModelFilterSet
```
To enable a filter set on a REST API endpoint, set the `filterset_class` attribute on the API view:
To enable a filter set on a REST API endpoint, set the `filterset_class` attribute on the API view:
```python
# api/views.py
@@ -62,7 +67,9 @@ The `ObjectListView` has a field called Quick Search. For Quick Search to work t
```python
from django.db.models import Q
from netbox.filtersets import NetBoxModelFilterSet
from utilities.filtersets import register_filterset
@register_filterset
class MyFilterSet(NetBoxModelFilterSet):
...
def search(self, queryset, name, value):
@@ -90,7 +97,9 @@ This class filters `tags` using the `slug` field. For example:
```python
from django_filters import FilterSet
from extras.filters import TagFilter
from utilities.filtersets import register_filterset
@register_filterset
class MyModelFilterSet(FilterSet):
tag = TagFilter()
```
@@ -106,7 +115,9 @@ This class filters `tags` using the `id` field. For example:
```python
from django_filters import FilterSet
from extras.filters import TagIDFilter
from utilities.filtersets import register_filterset
@register_filterset
class MyModelFilterSet(FilterSet):
tag_id = TagIDFilter()
```

View File

@@ -7,11 +7,11 @@ from dcim.filtersets import CabledObjectFilterSet
from dcim.models import Interface, Location, Region, Site, SiteGroup
from ipam.models import ASN
from netbox.filtersets import NetBoxModelFilterSet, OrganizationalModelFilterSet, PrimaryModelFilterSet
from netbox.plugins.registration import register_filterset
from tenancy.filtersets import ContactModelFilterSet, TenancyFilterSet
from utilities.filters import (
ContentTypeFilter, MultiValueCharFilter, MultiValueNumberFilter, TreeNodeMultipleChoiceFilter,
)
from utilities.filtersets import register_filterset
from .choices import *
from .models import *

View File

@@ -4,10 +4,10 @@ from django.db.models import Q
from django.utils.translation import gettext as _
from netbox.filtersets import BaseFilterSet, ChangeLoggedModelFilterSet, PrimaryModelFilterSet
from netbox.plugins.registration import register_filterset
from netbox.utils import get_data_backend_choices
from users.models import User
from utilities.filters import ContentTypeFilter
from utilities.filtersets import register_filterset
from .choices import *
from .models import *

View File

@@ -14,7 +14,6 @@ from netbox.filtersets import (
AttributeFiltersMixin, BaseFilterSet, ChangeLoggedModelFilterSet, NestedGroupModelFilterSet,
OrganizationalModelFilterSet, PrimaryModelFilterSet, NetBoxModelFilterSet,
)
from netbox.plugins.registration import register_filterset
from tenancy.filtersets import ContactModelFilterSet, TenancyFilterSet
from tenancy.models import *
from users.filterset_mixins import OwnerFilterMixin
@@ -23,6 +22,7 @@ from utilities.filters import (
ContentTypeFilter, MultiValueCharFilter, MultiValueMACAddressFilter, MultiValueNumberFilter, MultiValueWWNFilter,
NumericArrayFilter, TreeNodeMultipleChoiceFilter,
)
from utilities.filtersets import register_filterset
from virtualization.models import Cluster, ClusterGroup, VirtualMachine, VMInterface
from vpn.models import L2VPN
from wireless.choices import WirelessChannelChoices, WirelessRoleChoices

View File

@@ -6,13 +6,13 @@ from django.utils.translation import gettext as _
from core.models import DataSource, ObjectType
from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site, SiteGroup
from netbox.filtersets import BaseFilterSet, ChangeLoggedModelFilterSet, NetBoxModelFilterSet, PrimaryModelFilterSet
from netbox.plugins.registration import register_filterset
from tenancy.models import Tenant, TenantGroup
from users.filterset_mixins import OwnerFilterMixin
from users.models import Group, User
from utilities.filters import (
ContentTypeFilter, MultiValueCharFilter, MultiValueNumberFilter
)
from utilities.filtersets import register_filterset
from virtualization.models import Cluster, ClusterGroup, ClusterType
from .choices import *
from .filters import TagFilter, TagIDFilter

View File

@@ -1,6 +1,5 @@
import django_filters
import netaddr
from dcim.base_filtersets import ScopedFilterSet
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.db.models import Q
@@ -10,15 +9,16 @@ from drf_spectacular.utils import extend_schema_field
from netaddr.core import AddrFormatError
from circuits.models import Provider
from dcim.base_filtersets import ScopedFilterSet
from dcim.models import Device, Interface, Region, Site, SiteGroup
from netbox.filtersets import (
ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, NetBoxModelFilterSet, PrimaryModelFilterSet,
)
from netbox.plugins.registration import register_filterset
from tenancy.filtersets import ContactModelFilterSet, TenancyFilterSet
from utilities.filters import (
ContentTypeFilter, MultiValueCharFilter, MultiValueNumberFilter, NumericArrayFilter, TreeNodeMultipleChoiceFilter,
)
from utilities.filtersets import register_filterset
from virtualization.models import VirtualMachine, VMInterface
from vpn.models import L2VPN
from .choices import *

View File

@@ -7,7 +7,6 @@ from .navigation import PluginMenu, PluginMenuButton, PluginMenuItem
from .templates import PluginTemplateExtension
__all__ = (
'register_filterset',
'register_graphql_schema',
'register_menu',
'register_menu_items',
@@ -45,18 +44,6 @@ def register_template_extensions(class_list):
registry['plugins']['template_extensions'][model].append(template_extension)
def register_filterset(filterset_class):
"""
Decorator for registering a FilterSet with the application registry.
Uses model identifier as key to match search index pattern.
"""
model = filterset_class._meta.model
label = f'{model._meta.app_label}.{model._meta.model_name}'
registry['filtersets'][label] = filterset_class
return filterset_class
def register_menu(menu):
if not isinstance(menu, PluginMenu):
raise TypeError(_("{item} must be an instance of netbox.plugins.PluginMenuItem").format(item=menu))

View File

@@ -5,8 +5,8 @@ from django.utils.translation import gettext as _
from netbox.filtersets import (
NestedGroupModelFilterSet, NetBoxModelFilterSet, OrganizationalModelFilterSet, PrimaryModelFilterSet,
)
from netbox.plugins.registration import register_filterset
from utilities.filters import ContentTypeFilter, TreeNodeMultipleChoiceFilter
from utilities.filtersets import register_filterset
from .models import *
__all__ = (

View File

@@ -1,14 +1,13 @@
import django_filters
from django.db.models import Q
from django.utils.translation import gettext as _
from core.models import ObjectType
from extras.models import NotificationGroup
from netbox.filtersets import BaseFilterSet
from netbox.plugins.registration import register_filterset
from users.models import Group, ObjectPermission, Owner, OwnerGroup, Token, User
from utilities.filters import ContentTypeFilter
from utilities.filtersets import register_filterset
__all__ = (
'GroupFilterSet',

View File

@@ -0,0 +1,17 @@
from netbox.registry import registry
__all__ = (
'register_filterset',
)
def register_filterset(filterset_class):
"""
Decorator for registering a FilterSet with the application registry.
Uses model identifier as key to match search index pattern.
"""
model = filterset_class._meta.model
label = f'{model._meta.app_label}.{model._meta.model_name}'
registry['filtersets'][label] = filterset_class
return filterset_class

View File

@@ -8,7 +8,7 @@ import dcim.filtersets # noqa: F401 - Import to register Device filterset
from dcim.forms.filtersets import DeviceFilterForm
from dcim.models import Device
from netbox.filtersets import BaseFilterSet
from netbox.plugins.registration import register_filterset
from utilities.filtersets import register_filterset
from users.models import User
from utilities.forms.fields import TagFilterField
from utilities.forms.mixins import FilterModifierMixin

View File

@@ -10,10 +10,10 @@ from extras.filtersets import LocalConfigContextFilterSet
from extras.models import ConfigTemplate
from ipam.filtersets import PrimaryIPFilterSet
from netbox.filtersets import NetBoxModelFilterSet, OrganizationalModelFilterSet, PrimaryModelFilterSet
from netbox.plugins.registration import register_filterset
from tenancy.filtersets import TenancyFilterSet, ContactModelFilterSet
from users.filterset_mixins import OwnerFilterMixin
from utilities.filters import MultiValueCharFilter, MultiValueMACAddressFilter, TreeNodeMultipleChoiceFilter
from utilities.filtersets import register_filterset
from .choices import *
from .models import *

View File

@@ -6,9 +6,9 @@ from core.models import ObjectType
from dcim.models import Device, Interface
from ipam.models import IPAddress, RouteTarget, VLAN
from netbox.filtersets import NetBoxModelFilterSet, OrganizationalModelFilterSet, PrimaryModelFilterSet
from netbox.plugins.registration import register_filterset
from tenancy.filtersets import ContactModelFilterSet, TenancyFilterSet
from utilities.filters import ContentTypeFilter, MultiValueCharFilter, MultiValueNumberFilter
from utilities.filtersets import register_filterset
from virtualization.models import VirtualMachine, VMInterface
from .choices import *
from .models import *

View File

@@ -1,14 +1,14 @@
import django_filters
from django.db.models import Q
from dcim.choices import LinkStatusChoices
from dcim.base_filtersets import ScopedFilterSet
from dcim.choices import LinkStatusChoices
from dcim.models import Interface
from ipam.models import VLAN
from netbox.filtersets import NestedGroupModelFilterSet, PrimaryModelFilterSet
from netbox.plugins.registration import register_filterset
from tenancy.filtersets import TenancyFilterSet
from utilities.filters import TreeNodeMultipleChoiceFilter
from utilities.filtersets import register_filterset
from .choices import *
from .models import *