mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-25 18:08:38 -06:00
Merge pull request #2935 from DanSheps/2781-fixsitelistfilterregion
Fixes: #2781 - Enable Filtering by Multiple Regions on Site and Device Lists
This commit is contained in:
commit
e97ad3f066
@ -8,7 +8,9 @@ from netaddr.core import AddrFormatError
|
|||||||
from extras.filters import CustomFieldFilterSet
|
from extras.filters import CustomFieldFilterSet
|
||||||
from tenancy.models import Tenant
|
from tenancy.models import Tenant
|
||||||
from utilities.constants import COLOR_CHOICES
|
from utilities.constants import COLOR_CHOICES
|
||||||
from utilities.filters import NameSlugSearchFilterSet, NullableCharFieldFilter, NumericInFilter, TagFilter
|
from utilities.filters import (
|
||||||
|
NameSlugSearchFilterSet, NullableCharFieldFilter, NumericInFilter, TagFilter, TreeNodeMultipleChoiceFilter
|
||||||
|
)
|
||||||
from virtualization.models import Cluster
|
from virtualization.models import Cluster
|
||||||
from .constants import *
|
from .constants import *
|
||||||
from .models import (
|
from .models import (
|
||||||
@ -49,14 +51,15 @@ class SiteFilter(CustomFieldFilterSet, django_filters.FilterSet):
|
|||||||
choices=SITE_STATUS_CHOICES,
|
choices=SITE_STATUS_CHOICES,
|
||||||
null_value=None
|
null_value=None
|
||||||
)
|
)
|
||||||
region_id = django_filters.NumberFilter(
|
region_id = TreeNodeMultipleChoiceFilter(
|
||||||
method='filter_region',
|
queryset=Region.objects.all(),
|
||||||
field_name='pk',
|
field_name='region__in',
|
||||||
label='Region (ID)',
|
label='Region (ID)',
|
||||||
)
|
)
|
||||||
region = django_filters.CharFilter(
|
region = TreeNodeMultipleChoiceFilter(
|
||||||
method='filter_region',
|
queryset=Region.objects.all(),
|
||||||
field_name='slug',
|
field_name='region__in',
|
||||||
|
to_field_name='slug',
|
||||||
label='Region (slug)',
|
label='Region (slug)',
|
||||||
)
|
)
|
||||||
tenant_id = django_filters.ModelMultipleChoiceFilter(
|
tenant_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
@ -95,16 +98,6 @@ class SiteFilter(CustomFieldFilterSet, django_filters.FilterSet):
|
|||||||
pass
|
pass
|
||||||
return queryset.filter(qs_filter)
|
return queryset.filter(qs_filter)
|
||||||
|
|
||||||
def filter_region(self, queryset, name, value):
|
|
||||||
try:
|
|
||||||
region = Region.objects.get(**{name: value})
|
|
||||||
except ObjectDoesNotExist:
|
|
||||||
return queryset.none()
|
|
||||||
return queryset.filter(
|
|
||||||
Q(region=region) |
|
|
||||||
Q(region__in=region.get_descendants())
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class RackGroupFilter(NameSlugSearchFilterSet):
|
class RackGroupFilter(NameSlugSearchFilterSet):
|
||||||
site_id = django_filters.ModelMultipleChoiceFilter(
|
site_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
@ -513,14 +506,15 @@ class DeviceFilter(CustomFieldFilterSet):
|
|||||||
)
|
)
|
||||||
name = NullableCharFieldFilter()
|
name = NullableCharFieldFilter()
|
||||||
asset_tag = NullableCharFieldFilter()
|
asset_tag = NullableCharFieldFilter()
|
||||||
region_id = django_filters.NumberFilter(
|
region_id = TreeNodeMultipleChoiceFilter(
|
||||||
method='filter_region',
|
queryset=Region.objects.all(),
|
||||||
field_name='pk',
|
field_name='region__in',
|
||||||
label='Region (ID)',
|
label='Region (ID)',
|
||||||
)
|
)
|
||||||
region = django_filters.CharFilter(
|
region = TreeNodeMultipleChoiceFilter(
|
||||||
method='filter_region',
|
queryset=Region.objects.all(),
|
||||||
field_name='slug',
|
field_name='region__in',
|
||||||
|
to_field_name='slug',
|
||||||
label='Region (slug)',
|
label='Region (slug)',
|
||||||
)
|
)
|
||||||
site_id = django_filters.ModelMultipleChoiceFilter(
|
site_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
|
@ -4,6 +4,15 @@ from django.db.models import Q
|
|||||||
from taggit.models import Tag
|
from taggit.models import Tag
|
||||||
|
|
||||||
|
|
||||||
|
class TreeNodeMultipleChoiceFilter(django_filters.ModelMultipleChoiceFilter):
|
||||||
|
"""
|
||||||
|
Filters for a set of Models, including all descendant models within a Tree. Example: [<Region: R1>,<Region: R2>]
|
||||||
|
"""
|
||||||
|
def filter(self, qs, value):
|
||||||
|
value = [node.get_descendants(include_self=True) for node in value]
|
||||||
|
return super().filter(qs, value)
|
||||||
|
|
||||||
|
|
||||||
class NumericInFilter(django_filters.BaseInFilter, django_filters.NumberFilter):
|
class NumericInFilter(django_filters.BaseInFilter, django_filters.NumberFilter):
|
||||||
"""
|
"""
|
||||||
Filters for a set of numeric values. Example: id__in=100,200,300
|
Filters for a set of numeric values. Example: id__in=100,200,300
|
||||||
|
Loading…
Reference in New Issue
Block a user