mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-15 11:42:52 -06:00
Fixes #1649: Correct fitlering on null values (e.g. ?tenant_id=0) for django-filters v1.1.0+
This commit is contained in:
parent
a5b7c057eb
commit
4668149943
@ -7,7 +7,7 @@ from django.db.models import Q
|
|||||||
from dcim.models import Site
|
from dcim.models import Site
|
||||||
from extras.filters import CustomFieldFilterSet
|
from extras.filters import CustomFieldFilterSet
|
||||||
from tenancy.models import Tenant
|
from tenancy.models import Tenant
|
||||||
from utilities.filters import NullableModelMultipleChoiceFilter, NumericInFilter
|
from utilities.filters import NumericInFilter
|
||||||
from .models import Provider, Circuit, CircuitTermination, CircuitType
|
from .models import Provider, Circuit, CircuitTermination, CircuitType
|
||||||
|
|
||||||
|
|
||||||
@ -78,11 +78,11 @@ class CircuitFilter(CustomFieldFilterSet, django_filters.FilterSet):
|
|||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label='Circuit type (slug)',
|
label='Circuit type (slug)',
|
||||||
)
|
)
|
||||||
tenant_id = NullableModelMultipleChoiceFilter(
|
tenant_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
label='Tenant (ID)',
|
label='Tenant (ID)',
|
||||||
)
|
)
|
||||||
tenant = NullableModelMultipleChoiceFilter(
|
tenant = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='tenant',
|
name='tenant',
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
|
@ -9,7 +9,7 @@ from django.db.models import Q
|
|||||||
|
|
||||||
from extras.filters import CustomFieldFilterSet
|
from extras.filters import CustomFieldFilterSet
|
||||||
from tenancy.models import Tenant
|
from tenancy.models import Tenant
|
||||||
from utilities.filters import NullableCharFieldFilter, NullableModelMultipleChoiceFilter, NumericInFilter
|
from utilities.filters import NullableCharFieldFilter, NumericInFilter
|
||||||
from virtualization.models import Cluster
|
from virtualization.models import Cluster
|
||||||
from .models import (
|
from .models import (
|
||||||
ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
|
ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
|
||||||
@ -21,11 +21,11 @@ from .models import (
|
|||||||
|
|
||||||
|
|
||||||
class RegionFilter(django_filters.FilterSet):
|
class RegionFilter(django_filters.FilterSet):
|
||||||
parent_id = NullableModelMultipleChoiceFilter(
|
parent_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
label='Parent region (ID)',
|
label='Parent region (ID)',
|
||||||
)
|
)
|
||||||
parent = NullableModelMultipleChoiceFilter(
|
parent = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label='Parent region (slug)',
|
label='Parent region (slug)',
|
||||||
@ -42,20 +42,20 @@ class SiteFilter(CustomFieldFilterSet, django_filters.FilterSet):
|
|||||||
method='search',
|
method='search',
|
||||||
label='Search',
|
label='Search',
|
||||||
)
|
)
|
||||||
region_id = NullableModelMultipleChoiceFilter(
|
region_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
label='Region (ID)',
|
label='Region (ID)',
|
||||||
)
|
)
|
||||||
region = NullableModelMultipleChoiceFilter(
|
region = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label='Region (slug)',
|
label='Region (slug)',
|
||||||
)
|
)
|
||||||
tenant_id = NullableModelMultipleChoiceFilter(
|
tenant_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
label='Tenant (ID)',
|
label='Tenant (ID)',
|
||||||
)
|
)
|
||||||
tenant = NullableModelMultipleChoiceFilter(
|
tenant = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label='Tenant (slug)',
|
label='Tenant (slug)',
|
||||||
@ -126,31 +126,31 @@ class RackFilter(CustomFieldFilterSet, django_filters.FilterSet):
|
|||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label='Site (slug)',
|
label='Site (slug)',
|
||||||
)
|
)
|
||||||
group_id = NullableModelMultipleChoiceFilter(
|
group_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=RackGroup.objects.all(),
|
queryset=RackGroup.objects.all(),
|
||||||
label='Group (ID)',
|
label='Group (ID)',
|
||||||
)
|
)
|
||||||
group = NullableModelMultipleChoiceFilter(
|
group = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='group',
|
name='group',
|
||||||
queryset=RackGroup.objects.all(),
|
queryset=RackGroup.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label='Group',
|
label='Group',
|
||||||
)
|
)
|
||||||
tenant_id = NullableModelMultipleChoiceFilter(
|
tenant_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
label='Tenant (ID)',
|
label='Tenant (ID)',
|
||||||
)
|
)
|
||||||
tenant = NullableModelMultipleChoiceFilter(
|
tenant = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='tenant',
|
name='tenant',
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label='Tenant (slug)',
|
label='Tenant (slug)',
|
||||||
)
|
)
|
||||||
role_id = NullableModelMultipleChoiceFilter(
|
role_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=RackRole.objects.all(),
|
queryset=RackRole.objects.all(),
|
||||||
label='Role (ID)',
|
label='Role (ID)',
|
||||||
)
|
)
|
||||||
role = NullableModelMultipleChoiceFilter(
|
role = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='role',
|
name='role',
|
||||||
queryset=RackRole.objects.all(),
|
queryset=RackRole.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
@ -193,12 +193,12 @@ class RackReservationFilter(django_filters.FilterSet):
|
|||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label='Site (slug)',
|
label='Site (slug)',
|
||||||
)
|
)
|
||||||
group_id = NullableModelMultipleChoiceFilter(
|
group_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='rack__group',
|
name='rack__group',
|
||||||
queryset=RackGroup.objects.all(),
|
queryset=RackGroup.objects.all(),
|
||||||
label='Group (ID)',
|
label='Group (ID)',
|
||||||
)
|
)
|
||||||
group = NullableModelMultipleChoiceFilter(
|
group = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='rack__group',
|
name='rack__group',
|
||||||
queryset=RackGroup.objects.all(),
|
queryset=RackGroup.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
@ -368,21 +368,21 @@ class DeviceFilter(CustomFieldFilterSet, django_filters.FilterSet):
|
|||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label='Role (slug)',
|
label='Role (slug)',
|
||||||
)
|
)
|
||||||
tenant_id = NullableModelMultipleChoiceFilter(
|
tenant_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
label='Tenant (ID)',
|
label='Tenant (ID)',
|
||||||
)
|
)
|
||||||
tenant = NullableModelMultipleChoiceFilter(
|
tenant = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='tenant',
|
name='tenant',
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label='Tenant (slug)',
|
label='Tenant (slug)',
|
||||||
)
|
)
|
||||||
platform_id = NullableModelMultipleChoiceFilter(
|
platform_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Platform.objects.all(),
|
queryset=Platform.objects.all(),
|
||||||
label='Platform (ID)',
|
label='Platform (ID)',
|
||||||
)
|
)
|
||||||
platform = NullableModelMultipleChoiceFilter(
|
platform = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='platform',
|
name='platform',
|
||||||
queryset=Platform.objects.all(),
|
queryset=Platform.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
@ -405,12 +405,12 @@ class DeviceFilter(CustomFieldFilterSet, django_filters.FilterSet):
|
|||||||
queryset=RackGroup.objects.all(),
|
queryset=RackGroup.objects.all(),
|
||||||
label='Rack group (ID)',
|
label='Rack group (ID)',
|
||||||
)
|
)
|
||||||
rack_id = NullableModelMultipleChoiceFilter(
|
rack_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='rack',
|
name='rack',
|
||||||
queryset=Rack.objects.all(),
|
queryset=Rack.objects.all(),
|
||||||
label='Rack (ID)',
|
label='Rack (ID)',
|
||||||
)
|
)
|
||||||
cluster_id = NullableModelMultipleChoiceFilter(
|
cluster_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Cluster.objects.all(),
|
queryset=Cluster.objects.all(),
|
||||||
label='VM cluster (ID)',
|
label='VM cluster (ID)',
|
||||||
)
|
)
|
||||||
@ -595,7 +595,7 @@ class DeviceBayFilter(DeviceComponentFilterSet):
|
|||||||
|
|
||||||
|
|
||||||
class InventoryItemFilter(DeviceComponentFilterSet):
|
class InventoryItemFilter(DeviceComponentFilterSet):
|
||||||
parent_id = NullableModelMultipleChoiceFilter(
|
parent_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=InventoryItem.objects.all(),
|
queryset=InventoryItem.objects.all(),
|
||||||
label='Parent inventory item (ID)',
|
label='Parent inventory item (ID)',
|
||||||
)
|
)
|
||||||
|
@ -9,7 +9,7 @@ from django.db.models import Q
|
|||||||
from dcim.models import Site, Device, Interface
|
from dcim.models import Site, Device, Interface
|
||||||
from extras.filters import CustomFieldFilterSet
|
from extras.filters import CustomFieldFilterSet
|
||||||
from tenancy.models import Tenant
|
from tenancy.models import Tenant
|
||||||
from utilities.filters import NullableModelMultipleChoiceFilter, NumericInFilter
|
from utilities.filters import NumericInFilter
|
||||||
from virtualization.models import VirtualMachine
|
from virtualization.models import VirtualMachine
|
||||||
from .models import (
|
from .models import (
|
||||||
Aggregate, IPAddress, IPADDRESS_ROLE_CHOICES, IPADDRESS_STATUS_CHOICES, Prefix, PREFIX_STATUS_CHOICES, RIR, Role,
|
Aggregate, IPAddress, IPADDRESS_ROLE_CHOICES, IPADDRESS_STATUS_CHOICES, Prefix, PREFIX_STATUS_CHOICES, RIR, Role,
|
||||||
@ -23,11 +23,11 @@ class VRFFilter(CustomFieldFilterSet, django_filters.FilterSet):
|
|||||||
method='search',
|
method='search',
|
||||||
label='Search',
|
label='Search',
|
||||||
)
|
)
|
||||||
tenant_id = NullableModelMultipleChoiceFilter(
|
tenant_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
label='Tenant (ID)',
|
label='Tenant (ID)',
|
||||||
)
|
)
|
||||||
tenant = NullableModelMultipleChoiceFilter(
|
tenant = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='tenant',
|
name='tenant',
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
@ -110,37 +110,37 @@ class PrefixFilter(CustomFieldFilterSet, django_filters.FilterSet):
|
|||||||
method='filter_mask_length',
|
method='filter_mask_length',
|
||||||
label='Mask length',
|
label='Mask length',
|
||||||
)
|
)
|
||||||
vrf_id = NullableModelMultipleChoiceFilter(
|
vrf_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=VRF.objects.all(),
|
queryset=VRF.objects.all(),
|
||||||
label='VRF',
|
label='VRF',
|
||||||
)
|
)
|
||||||
vrf = NullableModelMultipleChoiceFilter(
|
vrf = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='vrf',
|
name='vrf',
|
||||||
queryset=VRF.objects.all(),
|
queryset=VRF.objects.all(),
|
||||||
to_field_name='rd',
|
to_field_name='rd',
|
||||||
label='VRF (RD)',
|
label='VRF (RD)',
|
||||||
)
|
)
|
||||||
tenant_id = NullableModelMultipleChoiceFilter(
|
tenant_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
label='Tenant (ID)',
|
label='Tenant (ID)',
|
||||||
)
|
)
|
||||||
tenant = NullableModelMultipleChoiceFilter(
|
tenant = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='tenant',
|
name='tenant',
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label='Tenant (slug)',
|
label='Tenant (slug)',
|
||||||
)
|
)
|
||||||
site_id = NullableModelMultipleChoiceFilter(
|
site_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
label='Site (ID)',
|
label='Site (ID)',
|
||||||
)
|
)
|
||||||
site = NullableModelMultipleChoiceFilter(
|
site = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='site',
|
name='site',
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label='Site (slug)',
|
label='Site (slug)',
|
||||||
)
|
)
|
||||||
vlan_id = NullableModelMultipleChoiceFilter(
|
vlan_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=VLAN.objects.all(),
|
queryset=VLAN.objects.all(),
|
||||||
label='VLAN (ID)',
|
label='VLAN (ID)',
|
||||||
)
|
)
|
||||||
@ -148,11 +148,11 @@ class PrefixFilter(CustomFieldFilterSet, django_filters.FilterSet):
|
|||||||
name='vlan__vid',
|
name='vlan__vid',
|
||||||
label='VLAN number (1-4095)',
|
label='VLAN number (1-4095)',
|
||||||
)
|
)
|
||||||
role_id = NullableModelMultipleChoiceFilter(
|
role_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Role.objects.all(),
|
queryset=Role.objects.all(),
|
||||||
label='Role (ID)',
|
label='Role (ID)',
|
||||||
)
|
)
|
||||||
role = NullableModelMultipleChoiceFilter(
|
role = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='role',
|
name='role',
|
||||||
queryset=Role.objects.all(),
|
queryset=Role.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
@ -207,21 +207,21 @@ class IPAddressFilter(CustomFieldFilterSet, django_filters.FilterSet):
|
|||||||
method='filter_mask_length',
|
method='filter_mask_length',
|
||||||
label='Mask length',
|
label='Mask length',
|
||||||
)
|
)
|
||||||
vrf_id = NullableModelMultipleChoiceFilter(
|
vrf_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=VRF.objects.all(),
|
queryset=VRF.objects.all(),
|
||||||
label='VRF',
|
label='VRF',
|
||||||
)
|
)
|
||||||
vrf = NullableModelMultipleChoiceFilter(
|
vrf = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='vrf',
|
name='vrf',
|
||||||
queryset=VRF.objects.all(),
|
queryset=VRF.objects.all(),
|
||||||
to_field_name='rd',
|
to_field_name='rd',
|
||||||
label='VRF (RD)',
|
label='VRF (RD)',
|
||||||
)
|
)
|
||||||
tenant_id = NullableModelMultipleChoiceFilter(
|
tenant_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
label='Tenant (ID)',
|
label='Tenant (ID)',
|
||||||
)
|
)
|
||||||
tenant = NullableModelMultipleChoiceFilter(
|
tenant = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='tenant',
|
name='tenant',
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
@ -290,11 +290,11 @@ class IPAddressFilter(CustomFieldFilterSet, django_filters.FilterSet):
|
|||||||
|
|
||||||
|
|
||||||
class VLANGroupFilter(django_filters.FilterSet):
|
class VLANGroupFilter(django_filters.FilterSet):
|
||||||
site_id = NullableModelMultipleChoiceFilter(
|
site_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
label='Site (ID)',
|
label='Site (ID)',
|
||||||
)
|
)
|
||||||
site = NullableModelMultipleChoiceFilter(
|
site = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='site',
|
name='site',
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
@ -312,41 +312,41 @@ class VLANFilter(CustomFieldFilterSet, django_filters.FilterSet):
|
|||||||
method='search',
|
method='search',
|
||||||
label='Search',
|
label='Search',
|
||||||
)
|
)
|
||||||
site_id = NullableModelMultipleChoiceFilter(
|
site_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
label='Site (ID)',
|
label='Site (ID)',
|
||||||
)
|
)
|
||||||
site = NullableModelMultipleChoiceFilter(
|
site = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='site',
|
name='site',
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label='Site (slug)',
|
label='Site (slug)',
|
||||||
)
|
)
|
||||||
group_id = NullableModelMultipleChoiceFilter(
|
group_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=VLANGroup.objects.all(),
|
queryset=VLANGroup.objects.all(),
|
||||||
label='Group (ID)',
|
label='Group (ID)',
|
||||||
)
|
)
|
||||||
group = NullableModelMultipleChoiceFilter(
|
group = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='group',
|
name='group',
|
||||||
queryset=VLANGroup.objects.all(),
|
queryset=VLANGroup.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label='Group',
|
label='Group',
|
||||||
)
|
)
|
||||||
tenant_id = NullableModelMultipleChoiceFilter(
|
tenant_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
label='Tenant (ID)',
|
label='Tenant (ID)',
|
||||||
)
|
)
|
||||||
tenant = NullableModelMultipleChoiceFilter(
|
tenant = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='tenant',
|
name='tenant',
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label='Tenant (slug)',
|
label='Tenant (slug)',
|
||||||
)
|
)
|
||||||
role_id = NullableModelMultipleChoiceFilter(
|
role_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Role.objects.all(),
|
queryset=Role.objects.all(),
|
||||||
label='Role (ID)',
|
label='Role (ID)',
|
||||||
)
|
)
|
||||||
role = NullableModelMultipleChoiceFilter(
|
role = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='role',
|
name='role',
|
||||||
queryset=Role.objects.all(),
|
queryset=Role.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
|
@ -206,6 +206,10 @@ LOGIN_URL = '/{}login/'.format(BASE_PATH)
|
|||||||
# Secrets
|
# Secrets
|
||||||
SECRETS_MIN_PUBKEY_SIZE = 2048
|
SECRETS_MIN_PUBKEY_SIZE = 2048
|
||||||
|
|
||||||
|
# Django filters
|
||||||
|
FILTERS_NULL_CHOICE_LABEL = 'None'
|
||||||
|
FILTERS_NULL_CHOICE_VALUE = '0' # Must be a string
|
||||||
|
|
||||||
# Django REST framework (API)
|
# Django REST framework (API)
|
||||||
REST_FRAMEWORK_VERSION = VERSION[0:3] # Use major.minor as API version
|
REST_FRAMEWORK_VERSION = VERSION[0:3] # Use major.minor as API version
|
||||||
REST_FRAMEWORK = {
|
REST_FRAMEWORK = {
|
||||||
|
@ -5,7 +5,7 @@ import django_filters
|
|||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
|
||||||
from extras.filters import CustomFieldFilterSet
|
from extras.filters import CustomFieldFilterSet
|
||||||
from utilities.filters import NullableModelMultipleChoiceFilter, NumericInFilter
|
from utilities.filters import NumericInFilter
|
||||||
from .models import Tenant, TenantGroup
|
from .models import Tenant, TenantGroup
|
||||||
|
|
||||||
|
|
||||||
@ -22,11 +22,11 @@ class TenantFilter(CustomFieldFilterSet, django_filters.FilterSet):
|
|||||||
method='search',
|
method='search',
|
||||||
label='Search',
|
label='Search',
|
||||||
)
|
)
|
||||||
group_id = NullableModelMultipleChoiceFilter(
|
group_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=TenantGroup.objects.all(),
|
queryset=TenantGroup.objects.all(),
|
||||||
label='Group (ID)',
|
label='Group (ID)',
|
||||||
)
|
)
|
||||||
group = NullableModelMultipleChoiceFilter(
|
group = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='group',
|
name='group',
|
||||||
queryset=TenantGroup.objects.all(),
|
queryset=TenantGroup.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
|
@ -4,7 +4,6 @@ import django_filters
|
|||||||
import itertools
|
import itertools
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.db.models import Q
|
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
|
|
||||||
|
|
||||||
@ -66,51 +65,3 @@ class NullableModelMultipleChoiceField(forms.ModelMultipleChoiceField):
|
|||||||
stripped_value = value
|
stripped_value = value
|
||||||
super(NullableModelMultipleChoiceField, self).clean(stripped_value)
|
super(NullableModelMultipleChoiceField, self).clean(stripped_value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
class NullableModelMultipleChoiceFilter(django_filters.ModelMultipleChoiceFilter):
|
|
||||||
"""
|
|
||||||
This class extends ModelMultipleChoiceFilter to accept an additional value which implies "is null". The default
|
|
||||||
queryset filter argument is:
|
|
||||||
|
|
||||||
.filter(fieldname=value)
|
|
||||||
|
|
||||||
When filtering by the value representing "is null" ('0' by default) the argument is modified to:
|
|
||||||
|
|
||||||
.filter(fieldname__isnull=True)
|
|
||||||
"""
|
|
||||||
field_class = NullableModelMultipleChoiceField
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
self.null_value = kwargs.get('null_value', 0)
|
|
||||||
super(NullableModelMultipleChoiceFilter, self).__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
def filter(self, qs, value):
|
|
||||||
value = value or () # Make sure we have an iterable
|
|
||||||
|
|
||||||
if self.is_noop(qs, value):
|
|
||||||
return qs
|
|
||||||
|
|
||||||
# Even though not a noop, no point filtering if empty
|
|
||||||
if not value:
|
|
||||||
return qs
|
|
||||||
|
|
||||||
q = Q()
|
|
||||||
for v in set(value):
|
|
||||||
# Filtering by "is null"
|
|
||||||
if v == force_text(self.null_value):
|
|
||||||
arg = {'{}__isnull'.format(self.name): True}
|
|
||||||
# Filtering by a related field (e.g. slug)
|
|
||||||
elif self.field.to_field_name is not None:
|
|
||||||
arg = {'{}__{}'.format(self.name, self.field.to_field_name): v}
|
|
||||||
# Filtering by primary key (default)
|
|
||||||
else:
|
|
||||||
arg = {self.name: v}
|
|
||||||
if self.conjoined:
|
|
||||||
qs = self.get_method(qs)(**arg)
|
|
||||||
else:
|
|
||||||
q |= Q(**arg)
|
|
||||||
if self.distinct:
|
|
||||||
return self.get_method(qs)(q).distinct()
|
|
||||||
|
|
||||||
return self.get_method(qs)(q)
|
|
||||||
|
@ -9,7 +9,7 @@ from django.db.models import Q
|
|||||||
from dcim.models import DeviceRole, Interface, Platform, Site
|
from dcim.models import DeviceRole, Interface, Platform, Site
|
||||||
from extras.filters import CustomFieldFilterSet
|
from extras.filters import CustomFieldFilterSet
|
||||||
from tenancy.models import Tenant
|
from tenancy.models import Tenant
|
||||||
from utilities.filters import NullableModelMultipleChoiceFilter, NumericInFilter
|
from utilities.filters import NumericInFilter
|
||||||
from .constants import STATUS_CHOICES
|
from .constants import STATUS_CHOICES
|
||||||
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine
|
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine
|
||||||
|
|
||||||
@ -20,11 +20,11 @@ class ClusterFilter(CustomFieldFilterSet):
|
|||||||
method='search',
|
method='search',
|
||||||
label='Search',
|
label='Search',
|
||||||
)
|
)
|
||||||
group_id = NullableModelMultipleChoiceFilter(
|
group_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=ClusterGroup.objects.all(),
|
queryset=ClusterGroup.objects.all(),
|
||||||
label='Parent group (ID)',
|
label='Parent group (ID)',
|
||||||
)
|
)
|
||||||
group = NullableModelMultipleChoiceFilter(
|
group = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=ClusterGroup.objects.all(),
|
queryset=ClusterGroup.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label='Parent group (slug)',
|
label='Parent group (slug)',
|
||||||
@ -72,12 +72,12 @@ class VirtualMachineFilter(CustomFieldFilterSet):
|
|||||||
status = django_filters.MultipleChoiceFilter(
|
status = django_filters.MultipleChoiceFilter(
|
||||||
choices=STATUS_CHOICES
|
choices=STATUS_CHOICES
|
||||||
)
|
)
|
||||||
cluster_group_id = NullableModelMultipleChoiceFilter(
|
cluster_group_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='cluster__group',
|
name='cluster__group',
|
||||||
queryset=ClusterGroup.objects.all(),
|
queryset=ClusterGroup.objects.all(),
|
||||||
label='Cluster group (ID)',
|
label='Cluster group (ID)',
|
||||||
)
|
)
|
||||||
cluster_group = NullableModelMultipleChoiceFilter(
|
cluster_group = django_filters.ModelMultipleChoiceFilter(
|
||||||
name='cluster__group',
|
name='cluster__group',
|
||||||
queryset=ClusterGroup.objects.all(),
|
queryset=ClusterGroup.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
@ -87,29 +87,29 @@ class VirtualMachineFilter(CustomFieldFilterSet):
|
|||||||
queryset=Cluster.objects.all(),
|
queryset=Cluster.objects.all(),
|
||||||
label='Cluster (ID)',
|
label='Cluster (ID)',
|
||||||
)
|
)
|
||||||
role_id = NullableModelMultipleChoiceFilter(
|
role_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=DeviceRole.objects.all(),
|
queryset=DeviceRole.objects.all(),
|
||||||
label='Role (ID)',
|
label='Role (ID)',
|
||||||
)
|
)
|
||||||
role = NullableModelMultipleChoiceFilter(
|
role = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=DeviceRole.objects.all(),
|
queryset=DeviceRole.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label='Role (slug)',
|
label='Role (slug)',
|
||||||
)
|
)
|
||||||
tenant_id = NullableModelMultipleChoiceFilter(
|
tenant_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
label='Tenant (ID)',
|
label='Tenant (ID)',
|
||||||
)
|
)
|
||||||
tenant = NullableModelMultipleChoiceFilter(
|
tenant = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label='Tenant (slug)',
|
label='Tenant (slug)',
|
||||||
)
|
)
|
||||||
platform_id = NullableModelMultipleChoiceFilter(
|
platform_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Platform.objects.all(),
|
queryset=Platform.objects.all(),
|
||||||
label='Platform (ID)',
|
label='Platform (ID)',
|
||||||
)
|
)
|
||||||
platform = NullableModelMultipleChoiceFilter(
|
platform = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Platform.objects.all(),
|
queryset=Platform.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label='Platform (slug)',
|
label='Platform (slug)',
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
Django>=1.11,<2.0
|
Django>=1.11,<2.0
|
||||||
django-cors-headers>=2.1
|
django-cors-headers>=2.1
|
||||||
django-debug-toolbar>=1.8
|
django-debug-toolbar>=1.8
|
||||||
django-filter>=1.0.4
|
django-filter>=1.1.0
|
||||||
django-mptt==0.8.7
|
django-mptt==0.8.7
|
||||||
django-rest-swagger>=2.1.0
|
django-rest-swagger>=2.1.0
|
||||||
django-tables2>=1.10.0
|
django-tables2>=1.10.0
|
||||||
|
Loading…
Reference in New Issue
Block a user