From 205adeb2e9008e36d8076fb7b4c212f9c2e9faf3 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 7 May 2019 13:55:48 -0400 Subject: [PATCH] Remove NullableCharFieldFilter; add missing filter fields --- netbox/circuits/filters.py | 2 +- netbox/dcim/filters.py | 73 ++++++++++++------------- netbox/ipam/filters.py | 19 ++++++- netbox/secrets/filters.py | 2 +- netbox/tenancy/filters.py | 2 +- netbox/virtualization/filters.py | 9 ++- netbox/virtualization/tests/test_api.py | 2 +- 7 files changed, 60 insertions(+), 49 deletions(-) diff --git a/netbox/circuits/filters.py b/netbox/circuits/filters.py index 8fe0ba50c..64ba2a1cb 100644 --- a/netbox/circuits/filters.py +++ b/netbox/circuits/filters.py @@ -47,7 +47,7 @@ class CircuitTypeFilter(NameSlugSearchFilterSet): class Meta: model = CircuitType - fields = ['name', 'slug'] + fields = ['id', 'name', 'slug'] class CircuitFilter(CustomFieldFilterSet): diff --git a/netbox/dcim/filters.py b/netbox/dcim/filters.py index f75686f88..94224bf3c 100644 --- a/netbox/dcim/filters.py +++ b/netbox/dcim/filters.py @@ -8,9 +8,7 @@ from netaddr.core import AddrFormatError from extras.filters import CustomFieldFilterSet from tenancy.models import Tenant from utilities.constants import COLOR_CHOICES -from utilities.filters import ( - NameSlugSearchFilterSet, NullableCharFieldFilter, TagFilter, TreeNodeMultipleChoiceFilter -) +from utilities.filters import NameSlugSearchFilterSet, TagFilter, TreeNodeMultipleChoiceFilter from virtualization.models import Cluster from .constants import * from .models import ( @@ -36,7 +34,7 @@ class RegionFilter(NameSlugSearchFilterSet): class Meta: model = Region - fields = ['name', 'slug'] + fields = ['id', 'name', 'slug'] class SiteFilter(CustomFieldFilterSet): @@ -73,7 +71,10 @@ class SiteFilter(CustomFieldFilterSet): class Meta: model = Site - fields = ['id', 'name', 'slug', 'facility', 'asn', 'contact_name', 'contact_phone', 'contact_email'] + fields = [ + 'id', 'name', 'slug', 'facility', 'asn', 'latitude', 'longitude', 'contact_name', 'contact_phone', + 'contact_email', + ] def search(self, queryset, name, value): if not value.strip(): @@ -110,14 +111,14 @@ class RackGroupFilter(NameSlugSearchFilterSet): class Meta: model = RackGroup - fields = ['site_id', 'name', 'slug'] + fields = ['id', 'name', 'slug'] class RackRoleFilter(NameSlugSearchFilterSet): class Meta: model = RackRole - fields = ['name', 'slug', 'color'] + fields = ['id', 'name', 'slug', 'color'] class RackFilter(CustomFieldFilterSet): @@ -125,7 +126,6 @@ class RackFilter(CustomFieldFilterSet): method='search', label='Search', ) - facility_id = NullableCharFieldFilter() site_id = django_filters.ModelMultipleChoiceFilter( queryset=Site.objects.all(), label='Site (ID)', @@ -170,14 +170,13 @@ class RackFilter(CustomFieldFilterSet): to_field_name='slug', label='Role (slug)', ) - asset_tag = NullableCharFieldFilter() tag = TagFilter() class Meta: model = Rack fields = [ - 'id', 'name', 'serial', 'asset_tag', 'type', 'width', 'u_height', 'desc_units', 'outer_width', - 'outer_depth', 'outer_unit', + 'id', 'name', 'facility_id', 'serial', 'asset_tag', 'type', 'width', 'u_height', 'desc_units', + 'outer_width', 'outer_depth', 'outer_unit', ] def search(self, queryset, name, value): @@ -263,7 +262,7 @@ class ManufacturerFilter(NameSlugSearchFilterSet): class Meta: model = Manufacturer - fields = ['name', 'slug'] + fields = ['id', 'name', 'slug'] class DeviceTypeFilter(CustomFieldFilterSet): @@ -357,63 +356,63 @@ class ConsolePortTemplateFilter(DeviceTypeComponentFilterSet): class Meta: model = ConsolePortTemplate - fields = ['name'] + fields = ['id', 'name'] class ConsoleServerPortTemplateFilter(DeviceTypeComponentFilterSet): class Meta: model = ConsoleServerPortTemplate - fields = ['name'] + fields = ['id', 'name'] class PowerPortTemplateFilter(DeviceTypeComponentFilterSet): class Meta: model = PowerPortTemplate - fields = ['name'] + fields = ['id', 'name', 'maximum_draw', 'allocated_draw'] class PowerOutletTemplateFilter(DeviceTypeComponentFilterSet): class Meta: model = PowerOutletTemplate - fields = ['name'] + fields = ['id', 'name', 'feed_leg'] class InterfaceTemplateFilter(DeviceTypeComponentFilterSet): class Meta: model = InterfaceTemplate - fields = ['name', 'type', 'mgmt_only'] + fields = ['id', 'name', 'type', 'mgmt_only'] class FrontPortTemplateFilter(DeviceTypeComponentFilterSet): class Meta: model = FrontPortTemplate - fields = ['name', 'type'] + fields = ['id', 'name', 'type'] class RearPortTemplateFilter(DeviceTypeComponentFilterSet): class Meta: model = RearPortTemplate - fields = ['name', 'type'] + fields = ['id', 'name', 'type', 'positions'] class DeviceBayTemplateFilter(DeviceTypeComponentFilterSet): class Meta: model = DeviceBayTemplate - fields = ['name'] + fields = ['id', 'name'] class DeviceRoleFilter(NameSlugSearchFilterSet): class Meta: model = DeviceRole - fields = ['name', 'slug', 'color', 'vm_role'] + fields = ['id', 'name', 'slug', 'color', 'vm_role'] class PlatformFilter(NameSlugSearchFilterSet): @@ -431,7 +430,7 @@ class PlatformFilter(NameSlugSearchFilterSet): class Meta: model = Platform - fields = ['name', 'slug'] + fields = ['id', 'name', 'slug', 'napalm_driver'] class DeviceFilter(CustomFieldFilterSet): @@ -485,8 +484,6 @@ class DeviceFilter(CustomFieldFilterSet): to_field_name='slug', label='Platform (slug)', ) - name = NullableCharFieldFilter() - asset_tag = NullableCharFieldFilter() region_id = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='site__region__in', @@ -581,7 +578,7 @@ class DeviceFilter(CustomFieldFilterSet): class Meta: model = Device - fields = ['id', 'serial', 'face'] + fields = ['id', 'name', 'serial', 'asset_tag', 'face', 'vc_position', 'vc_priority'] def search(self, queryset, name, value): if not value.strip(): @@ -672,7 +669,7 @@ class ConsolePortFilter(DeviceComponentFilterSet): class Meta: model = ConsolePort - fields = ['name', 'description', 'connection_status'] + fields = ['id', 'name', 'description', 'connection_status'] class ConsoleServerPortFilter(DeviceComponentFilterSet): @@ -684,7 +681,7 @@ class ConsoleServerPortFilter(DeviceComponentFilterSet): class Meta: model = ConsoleServerPort - fields = ['name', 'description', 'connection_status'] + fields = ['id', 'name', 'description', 'connection_status'] class PowerPortFilter(DeviceComponentFilterSet): @@ -696,7 +693,7 @@ class PowerPortFilter(DeviceComponentFilterSet): class Meta: model = PowerPort - fields = ['name', 'description', 'connection_status'] + fields = ['id', 'name', 'maximum_draw', 'allocated_draw', 'description', 'connection_status'] class PowerOutletFilter(DeviceComponentFilterSet): @@ -708,7 +705,7 @@ class PowerOutletFilter(DeviceComponentFilterSet): class Meta: model = PowerOutlet - fields = ['name', 'description', 'connection_status'] + fields = ['id', 'name', 'feed_leg', 'description', 'connection_status'] class InterfaceFilter(django_filters.FilterSet): @@ -763,7 +760,7 @@ class InterfaceFilter(django_filters.FilterSet): class Meta: model = Interface - fields = ['name', 'connection_status', 'type', 'enabled', 'mtu', 'mgmt_only', 'description'] + fields = ['id', 'name', 'connection_status', 'type', 'enabled', 'mtu', 'mgmt_only', 'mode', 'description'] def search(self, queryset, name, value): if not value.strip(): @@ -827,7 +824,7 @@ class FrontPortFilter(DeviceComponentFilterSet): class Meta: model = FrontPort - fields = ['name', 'type', 'description'] + fields = ['id', 'name', 'type', 'description'] class RearPortFilter(DeviceComponentFilterSet): @@ -839,14 +836,14 @@ class RearPortFilter(DeviceComponentFilterSet): class Meta: model = RearPort - fields = ['name', 'type', 'description'] + fields = ['id', 'name', 'type', 'positions', 'description'] class DeviceBayFilter(DeviceComponentFilterSet): class Meta: model = DeviceBay - fields = ['name', 'description'] + fields = ['id', 'name', 'description'] class InventoryItemFilter(DeviceComponentFilterSet): @@ -877,11 +874,10 @@ class InventoryItemFilter(DeviceComponentFilterSet): to_field_name='slug', label='Manufacturer (slug)', ) - asset_tag = NullableCharFieldFilter() class Meta: model = InventoryItem - fields = ['name', 'part_id', 'serial', 'asset_tag', 'discovered'] + fields = ['id', 'name', 'part_id', 'serial', 'asset_tag', 'discovered'] def search(self, queryset, name, value): if not value.strip(): @@ -927,7 +923,7 @@ class VirtualChassisFilter(django_filters.FilterSet): class Meta: model = VirtualChassis - fields = ['domain'] + fields = ['id', 'domain'] def search(self, queryset, name, value): if not value.strip(): @@ -947,6 +943,9 @@ class CableFilter(django_filters.FilterSet): type = django_filters.MultipleChoiceFilter( choices=CABLE_TYPE_CHOICES ) + status = django_filters.MultipleChoiceFilter( + choices=CONNECTION_STATUS_CHOICES + ) color = django_filters.MultipleChoiceFilter( choices=COLOR_CHOICES ) @@ -961,7 +960,7 @@ class CableFilter(django_filters.FilterSet): class Meta: model = Cable - fields = ['type', 'status', 'color', 'length', 'length_unit'] + fields = ['id', 'label', 'length', 'length_unit'] def search(self, queryset, name, value): if not value.strip(): diff --git a/netbox/ipam/filters.py b/netbox/ipam/filters.py index 9145d4ca3..b4e64262a 100644 --- a/netbox/ipam/filters.py +++ b/netbox/ipam/filters.py @@ -56,6 +56,10 @@ class AggregateFilter(CustomFieldFilterSet): method='search', label='Search', ) + prefix = django_filters.CharFilter( + method='filter_prefix', + label='Prefix', + ) rir_id = django_filters.ModelMultipleChoiceFilter( queryset=RIR.objects.all(), label='RIR (ID)', @@ -83,6 +87,15 @@ class AggregateFilter(CustomFieldFilterSet): pass return queryset.filter(qs_filter) + def filter_prefix(self, queryset, name, value): + if not value.strip(): + return queryset + try: + query = str(netaddr.IPNetwork(value).cidr) + return queryset.filter(prefix=query) + except ValidationError: + return queryset.none() + class RoleFilter(NameSlugSearchFilterSet): q = django_filters.CharFilter( @@ -92,7 +105,7 @@ class RoleFilter(NameSlugSearchFilterSet): class Meta: model = Role - fields = ['name', 'slug'] + fields = ['id', 'name', 'slug'] class PrefixFilter(CustomFieldFilterSet): @@ -372,7 +385,7 @@ class VLANGroupFilter(NameSlugSearchFilterSet): class Meta: model = VLANGroup - fields = ['name', 'slug'] + fields = ['id', 'name', 'slug'] class VLANFilter(CustomFieldFilterSet): @@ -470,7 +483,7 @@ class ServiceFilter(django_filters.FilterSet): class Meta: model = Service - fields = ['name', 'protocol', 'port'] + fields = ['id', 'name', 'protocol', 'port'] def search(self, queryset, name, value): if not value.strip(): diff --git a/netbox/secrets/filters.py b/netbox/secrets/filters.py index ad299a2d9..a06791498 100644 --- a/netbox/secrets/filters.py +++ b/netbox/secrets/filters.py @@ -11,7 +11,7 @@ class SecretRoleFilter(NameSlugSearchFilterSet): class Meta: model = SecretRole - fields = ['name', 'slug'] + fields = ['id', 'name', 'slug'] class SecretFilter(CustomFieldFilterSet): diff --git a/netbox/tenancy/filters.py b/netbox/tenancy/filters.py index e193738a9..52e13425c 100644 --- a/netbox/tenancy/filters.py +++ b/netbox/tenancy/filters.py @@ -10,7 +10,7 @@ class TenantGroupFilter(NameSlugSearchFilterSet): class Meta: model = TenantGroup - fields = ['name', 'slug'] + fields = ['id', 'name', 'slug'] class TenantFilter(CustomFieldFilterSet): diff --git a/netbox/virtualization/filters.py b/netbox/virtualization/filters.py index 441783a31..69e1493cd 100644 --- a/netbox/virtualization/filters.py +++ b/netbox/virtualization/filters.py @@ -1,5 +1,4 @@ import django_filters -from django.core.exceptions import ObjectDoesNotExist from django.db.models import Q from netaddr import EUI from netaddr.core import AddrFormatError @@ -16,14 +15,14 @@ class ClusterTypeFilter(NameSlugSearchFilterSet): class Meta: model = ClusterType - fields = ['name', 'slug'] + fields = ['id', 'name', 'slug'] class ClusterGroupFilter(NameSlugSearchFilterSet): class Meta: model = ClusterGroup - fields = ['name', 'slug'] + fields = ['id', 'name', 'slug'] class ClusterFilter(CustomFieldFilterSet): @@ -167,7 +166,7 @@ class VirtualMachineFilter(CustomFieldFilterSet): class Meta: model = VirtualMachine - fields = ['id', 'name', 'cluster'] + fields = ['id', 'name', 'cluster', 'vcpus', 'memory', 'disk'] def search(self, queryset, name, value): if not value.strip(): @@ -201,7 +200,7 @@ class InterfaceFilter(django_filters.FilterSet): class Meta: model = Interface - fields = ['name', 'enabled', 'mtu'] + fields = ['id', 'name', 'enabled', 'mtu'] def _mac_address(self, queryset, name, value): value = value.strip() diff --git a/netbox/virtualization/tests/test_api.py b/netbox/virtualization/tests/test_api.py index 814e05854..f1e372dd4 100644 --- a/netbox/virtualization/tests/test_api.py +++ b/netbox/virtualization/tests/test_api.py @@ -464,7 +464,7 @@ class VirtualMachineTest(APITestCase): def test_config_context_included_by_default_in_list_view(self): url = reverse('virtualization-api:virtualmachine-list') - url = '{}?id__in={}'.format(url, self.virtualmachine_with_context_data.pk) + url = '{}?id={}'.format(url, self.virtualmachine_with_context_data.pk) response = self.client.get(url, **self.header) self.assertEqual(response.data['results'][0].get('config_context', {}).get('A'), 1)