Jeremy Stretch 7 лет назад
Родитель
Сommit
78725b8483
3 измененных файлов с 11 добавлено и 30 удалено
  1. 1 0
      CHANGELOG.md
  2. 2 13
      netbox/dcim/filters.py
  3. 8 17
      netbox/virtualization/filters.py

+ 1 - 0
CHANGELOG.md

@@ -3,6 +3,7 @@ v2.5.8 (FUTURE)
 ## Bug Fixes
 
 * [#2705](https://github.com/digitalocean/netbox/issues/2705) - Fix endpoint grouping in API docs
+* [#2781](https://github.com/digitalocean/netbox/issues/2781) - Fix filtering of sites/devices/VMs by multiple regions
 * [#2923](https://github.com/digitalocean/netbox/issues/2923) - Provider filter form's site field should be blank by default
 * [#2938](https://github.com/digitalocean/netbox/issues/2938) - Enforce deterministic ordering of device components returned by API
 * [#2939](https://github.com/digitalocean/netbox/issues/2939) - Exclude circuit terminations from API interface connections endpoint

+ 2 - 13
netbox/dcim/filters.py

@@ -1,6 +1,5 @@
 import django_filters
 from django.contrib.auth.models import User
-from django.core.exceptions import ObjectDoesNotExist
 from django.db.models import Q
 from netaddr import EUI
 from netaddr.core import AddrFormatError
@@ -508,12 +507,12 @@ class DeviceFilter(CustomFieldFilterSet):
     asset_tag = NullableCharFieldFilter()
     region_id = TreeNodeMultipleChoiceFilter(
         queryset=Region.objects.all(),
-        field_name='region__in',
+        field_name='site__region__in',
         label='Region (ID)',
     )
     region = TreeNodeMultipleChoiceFilter(
         queryset=Region.objects.all(),
-        field_name='region__in',
+        field_name='site__region__in',
         to_field_name='slug',
         label='Region (slug)',
     )
@@ -613,16 +612,6 @@ class DeviceFilter(CustomFieldFilterSet):
             Q(comments__icontains=value)
         ).distinct()
 
-    def filter_region(self, queryset, name, value):
-        try:
-            region = Region.objects.get(**{name: value})
-        except ObjectDoesNotExist:
-            return queryset.none()
-        return queryset.filter(
-            Q(site__region=region) |
-            Q(site__region__in=region.get_descendants())
-        )
-
     def _mac_address(self, queryset, name, value):
         value = value.strip()
         if not value:

+ 8 - 17
netbox/virtualization/filters.py

@@ -7,7 +7,7 @@ from netaddr.core import AddrFormatError
 from dcim.models import DeviceRole, Interface, Platform, Region, Site
 from extras.filters import CustomFieldFilterSet
 from tenancy.models import Tenant
-from utilities.filters import NameSlugSearchFilterSet, NumericInFilter, TagFilter
+from utilities.filters import NameSlugSearchFilterSet, NumericInFilter, TagFilter, TreeNodeMultipleChoiceFilter
 from .constants import VM_STATUS_CHOICES
 from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine
 
@@ -119,14 +119,15 @@ class VirtualMachineFilter(CustomFieldFilterSet):
         queryset=Cluster.objects.all(),
         label='Cluster (ID)',
     )
-    region_id = django_filters.NumberFilter(
-        method='filter_region',
-        field_name='pk',
+    region_id = TreeNodeMultipleChoiceFilter(
+        queryset=Region.objects.all(),
+        field_name='cluster__site__region__in',
         label='Region (ID)',
     )
-    region = django_filters.CharFilter(
-        method='filter_region',
-        field_name='slug',
+    region = TreeNodeMultipleChoiceFilter(
+        queryset=Region.objects.all(),
+        field_name='cluster__site__region__in',
+        to_field_name='slug',
         label='Region (slug)',
     )
     site_id = django_filters.ModelMultipleChoiceFilter(
@@ -184,16 +185,6 @@ class VirtualMachineFilter(CustomFieldFilterSet):
             Q(comments__icontains=value)
         )
 
-    def filter_region(self, queryset, name, value):
-        try:
-            region = Region.objects.get(**{name: value})
-        except ObjectDoesNotExist:
-            return queryset.none()
-        return queryset.filter(
-            Q(cluster__site__region=region) |
-            Q(cluster__site__region__in=region.get_descendants())
-        )
-
 
 class InterfaceFilter(django_filters.FilterSet):
     q = django_filters.CharFilter(