mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-27 02:48:38 -06:00
Enable filtering by attribute values
This commit is contained in:
parent
4fd3a91d2f
commit
94b3aae0a2
@ -11,7 +11,7 @@ from ipam.filtersets import PrimaryIPFilterSet
|
|||||||
from ipam.models import ASN, IPAddress, VLANTranslationPolicy, VRF
|
from ipam.models import ASN, IPAddress, VLANTranslationPolicy, VRF
|
||||||
from netbox.choices import ColorChoices
|
from netbox.choices import ColorChoices
|
||||||
from netbox.filtersets import (
|
from netbox.filtersets import (
|
||||||
BaseFilterSet, ChangeLoggedModelFilterSet, NestedGroupModelFilterSet, NetBoxModelFilterSet,
|
AttributeFiltersMixin, BaseFilterSet, ChangeLoggedModelFilterSet, NestedGroupModelFilterSet, NetBoxModelFilterSet,
|
||||||
OrganizationalModelFilterSet,
|
OrganizationalModelFilterSet,
|
||||||
)
|
)
|
||||||
from tenancy.filtersets import TenancyFilterSet, ContactModelFilterSet
|
from tenancy.filtersets import TenancyFilterSet, ContactModelFilterSet
|
||||||
@ -691,7 +691,7 @@ class ModuleTypeProfileFilterSet(NetBoxModelFilterSet):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ModuleTypeFilterSet(NetBoxModelFilterSet):
|
class ModuleTypeFilterSet(AttributeFiltersMixin, NetBoxModelFilterSet):
|
||||||
profile_id = django_filters.ModelMultipleChoiceFilter(
|
profile_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=ModuleTypeProfile.objects.all(),
|
queryset=ModuleTypeProfile.objects.all(),
|
||||||
label=_('Profile (ID)'),
|
label=_('Profile (ID)'),
|
||||||
|
@ -128,7 +128,7 @@ class ModuleType(ImageAttachmentsMixin, PrimaryModel, WeightMixin):
|
|||||||
"""
|
"""
|
||||||
Returns a human-friendly representation of the attributes defined for a ModuleType according to its profile.
|
Returns a human-friendly representation of the attributes defined for a ModuleType according to its profile.
|
||||||
"""
|
"""
|
||||||
if self.profile is None or not self.profile.schema:
|
if not self.attribute_data or self.profile is None or not self.profile.schema:
|
||||||
return {}
|
return {}
|
||||||
attrs = {}
|
attrs = {}
|
||||||
for name, options in self.profile.schema.get('properties', {}).items():
|
for name, options in self.profile.schema.get('properties', {}).items():
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
import django_filters
|
import django_filters
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
@ -20,6 +22,7 @@ from utilities.forms.fields import MACAddressField
|
|||||||
from utilities import filters
|
from utilities import filters
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
|
'AttributeFiltersMixin',
|
||||||
'BaseFilterSet',
|
'BaseFilterSet',
|
||||||
'ChangeLoggedModelFilterSet',
|
'ChangeLoggedModelFilterSet',
|
||||||
'NetBoxModelFilterSet',
|
'NetBoxModelFilterSet',
|
||||||
@ -345,3 +348,28 @@ class NestedGroupModelFilterSet(NetBoxModelFilterSet):
|
|||||||
)
|
)
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
|
class AttributeFiltersMixin:
|
||||||
|
attributes_field_name = 'attribute_data'
|
||||||
|
attribute_filter_prefix = 'attr_'
|
||||||
|
|
||||||
|
def __init__(self, data=None, queryset=None, *, request=None, prefix=None):
|
||||||
|
self.attr_filters = {}
|
||||||
|
|
||||||
|
# Extract JSONField-based filters from the incoming data
|
||||||
|
if data is not None:
|
||||||
|
for key, value in data.items():
|
||||||
|
if key.startswith(self.attribute_filter_prefix):
|
||||||
|
# Attempt to case the value to a native JSON type
|
||||||
|
try:
|
||||||
|
value = json.loads(value)
|
||||||
|
except (ValueError, json.JSONDecodeError):
|
||||||
|
pass
|
||||||
|
field = f'{self.attributes_field_name}__{key.split(self.attribute_filter_prefix, 1)[1]}'
|
||||||
|
self.attr_filters[field] = value
|
||||||
|
|
||||||
|
super().__init__(data=data, queryset=queryset, request=request, prefix=prefix)
|
||||||
|
|
||||||
|
def filter_queryset(self, queryset):
|
||||||
|
return super().filter_queryset(queryset).filter(**self.attr_filters)
|
||||||
|
Loading…
Reference in New Issue
Block a user