Consolidate FilterSet classes

This commit is contained in:
jeremystretch 2021-04-29 15:59:11 -04:00
parent 0de50e0afe
commit c4e88fd11a
12 changed files with 484 additions and 487 deletions

View File

@ -3,10 +3,9 @@ from django.db.models import Q
from dcim.filters import CableTerminationFilterSet from dcim.filters import CableTerminationFilterSet
from dcim.models import Region, Site, SiteGroup from dcim.models import Region, Site, SiteGroup
from extras.filters import CustomFieldModelFilterSet, CreatedUpdatedFilterSet
from tenancy.filters import TenancyFilterSet from tenancy.filters import TenancyFilterSet
from utilities.filters import TagFilter, TreeNodeMultipleChoiceFilter from utilities.filters import TagFilter, TreeNodeMultipleChoiceFilter
from utilities.filtersets import BaseFilterSet, NameSlugSearchFilterSet from utilities.filtersets import ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, PrimaryModelFilterSet
from .choices import * from .choices import *
from .models import * from .models import *
@ -19,7 +18,7 @@ __all__ = (
) )
class ProviderFilterSet(BaseFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet): class ProviderFilterSet(PrimaryModelFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -79,7 +78,7 @@ class ProviderFilterSet(BaseFilterSet, CustomFieldModelFilterSet, CreatedUpdated
) )
class ProviderNetworkFilterSet(BaseFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet): class ProviderNetworkFilterSet(PrimaryModelFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -109,14 +108,14 @@ class ProviderNetworkFilterSet(BaseFilterSet, CustomFieldModelFilterSet, Created
).distinct() ).distinct()
class CircuitTypeFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet): class CircuitTypeFilterSet(OrganizationalModelFilterSet):
class Meta: class Meta:
model = CircuitType model = CircuitType
fields = ['id', 'name', 'slug'] fields = ['id', 'name', 'slug']
class CircuitFilterSet(BaseFilterSet, CustomFieldModelFilterSet, TenancyFilterSet, CreatedUpdatedFilterSet): class CircuitFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -206,7 +205,7 @@ class CircuitFilterSet(BaseFilterSet, CustomFieldModelFilterSet, TenancyFilterSe
).distinct() ).distinct()
class CircuitTerminationFilterSet(BaseFilterSet, CreatedUpdatedFilterSet, CableTerminationFilterSet): class CircuitTerminationFilterSet(ChangeLoggedModelFilterSet, CableTerminationFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',

View File

@ -1,14 +1,16 @@
import django_filters import django_filters
from django.contrib.auth.models import User from django.contrib.auth.models import User
from extras.filters import CustomFieldModelFilterSet, LocalConfigContextFilterSet, CreatedUpdatedFilterSet from extras.filtersets import LocalConfigContextFilterSet
from tenancy.filters import TenancyFilterSet from tenancy.filters import TenancyFilterSet
from tenancy.models import Tenant from tenancy.models import Tenant
from utilities.choices import ColorChoices from utilities.choices import ColorChoices
from utilities.filters import ( from utilities.filters import (
MultiValueCharFilter, MultiValueMACAddressFilter, MultiValueNumberFilter, TagFilter, TreeNodeMultipleChoiceFilter, MultiValueCharFilter, MultiValueMACAddressFilter, MultiValueNumberFilter, TagFilter, TreeNodeMultipleChoiceFilter,
) )
from utilities.filtersets import BaseFilterSet, NameSlugSearchFilterSet from utilities.filtersets import (
BaseFilterSet, ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, PrimaryModelFilterSet,
)
from virtualization.models import Cluster from virtualization.models import Cluster
from .choices import * from .choices import *
from .constants import * from .constants import *
@ -57,7 +59,7 @@ __all__ = (
) )
class RegionFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet): class RegionFilterSet(OrganizationalModelFilterSet):
parent_id = django_filters.ModelMultipleChoiceFilter( parent_id = django_filters.ModelMultipleChoiceFilter(
queryset=Region.objects.all(), queryset=Region.objects.all(),
label='Parent region (ID)', label='Parent region (ID)',
@ -74,7 +76,7 @@ class RegionFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilt
fields = ['id', 'name', 'slug', 'description'] fields = ['id', 'name', 'slug', 'description']
class SiteGroupFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet): class SiteGroupFilterSet(OrganizationalModelFilterSet):
parent_id = django_filters.ModelMultipleChoiceFilter( parent_id = django_filters.ModelMultipleChoiceFilter(
queryset=SiteGroup.objects.all(), queryset=SiteGroup.objects.all(),
label='Parent site group (ID)', label='Parent site group (ID)',
@ -91,7 +93,7 @@ class SiteGroupFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedF
fields = ['id', 'name', 'slug', 'description'] fields = ['id', 'name', 'slug', 'description']
class SiteFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet): class SiteFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -154,7 +156,7 @@ class SiteFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSet,
return queryset.filter(qs_filter) return queryset.filter(qs_filter)
class LocationFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet): class LocationFilterSet(OrganizationalModelFilterSet):
region_id = TreeNodeMultipleChoiceFilter( region_id = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(), queryset=Region.objects.all(),
field_name='site__region', field_name='site__region',
@ -218,14 +220,14 @@ class LocationFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFi
) )
class RackRoleFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet): class RackRoleFilterSet(OrganizationalModelFilterSet):
class Meta: class Meta:
model = RackRole model = RackRole
fields = ['id', 'name', 'slug', 'color'] fields = ['id', 'name', 'slug', 'color']
class RackFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet): class RackFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -323,7 +325,7 @@ class RackFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSet,
) )
class RackReservationFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet): class RackReservationFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -383,14 +385,14 @@ class RackReservationFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModel
) )
class ManufacturerFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet): class ManufacturerFilterSet(OrganizationalModelFilterSet):
class Meta: class Meta:
model = Manufacturer model = Manufacturer
fields = ['id', 'name', 'slug', 'description'] fields = ['id', 'name', 'slug', 'description']
class DeviceTypeFilterSet(BaseFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet): class DeviceTypeFilterSet(PrimaryModelFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -476,7 +478,7 @@ class DeviceTypeFilterSet(BaseFilterSet, CustomFieldModelFilterSet, CreatedUpdat
return queryset.exclude(devicebaytemplates__isnull=value) return queryset.exclude(devicebaytemplates__isnull=value)
class DeviceTypeComponentFilterSet(NameSlugSearchFilterSet, CreatedUpdatedFilterSet): class DeviceTypeComponentFilterSet(django_filters.FilterSet):
devicetype_id = django_filters.ModelMultipleChoiceFilter( devicetype_id = django_filters.ModelMultipleChoiceFilter(
queryset=DeviceType.objects.all(), queryset=DeviceType.objects.all(),
field_name='device_type_id', field_name='device_type_id',
@ -484,28 +486,28 @@ class DeviceTypeComponentFilterSet(NameSlugSearchFilterSet, CreatedUpdatedFilter
) )
class ConsolePortTemplateFilterSet(BaseFilterSet, DeviceTypeComponentFilterSet): class ConsolePortTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
class Meta: class Meta:
model = ConsolePortTemplate model = ConsolePortTemplate
fields = ['id', 'name', 'type'] fields = ['id', 'name', 'type']
class ConsoleServerPortTemplateFilterSet(BaseFilterSet, DeviceTypeComponentFilterSet): class ConsoleServerPortTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
class Meta: class Meta:
model = ConsoleServerPortTemplate model = ConsoleServerPortTemplate
fields = ['id', 'name', 'type'] fields = ['id', 'name', 'type']
class PowerPortTemplateFilterSet(BaseFilterSet, DeviceTypeComponentFilterSet): class PowerPortTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
class Meta: class Meta:
model = PowerPortTemplate model = PowerPortTemplate
fields = ['id', 'name', 'type', 'maximum_draw', 'allocated_draw'] fields = ['id', 'name', 'type', 'maximum_draw', 'allocated_draw']
class PowerOutletTemplateFilterSet(BaseFilterSet, DeviceTypeComponentFilterSet): class PowerOutletTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
feed_leg = django_filters.MultipleChoiceFilter( feed_leg = django_filters.MultipleChoiceFilter(
choices=PowerOutletFeedLegChoices, choices=PowerOutletFeedLegChoices,
null_value=None null_value=None
@ -516,7 +518,7 @@ class PowerOutletTemplateFilterSet(BaseFilterSet, DeviceTypeComponentFilterSet):
fields = ['id', 'name', 'type', 'feed_leg'] fields = ['id', 'name', 'type', 'feed_leg']
class InterfaceTemplateFilterSet(BaseFilterSet, DeviceTypeComponentFilterSet): class InterfaceTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
type = django_filters.MultipleChoiceFilter( type = django_filters.MultipleChoiceFilter(
choices=InterfaceTypeChoices, choices=InterfaceTypeChoices,
null_value=None null_value=None
@ -527,7 +529,7 @@ class InterfaceTemplateFilterSet(BaseFilterSet, DeviceTypeComponentFilterSet):
fields = ['id', 'name', 'type', 'mgmt_only'] fields = ['id', 'name', 'type', 'mgmt_only']
class FrontPortTemplateFilterSet(BaseFilterSet, DeviceTypeComponentFilterSet): class FrontPortTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
type = django_filters.MultipleChoiceFilter( type = django_filters.MultipleChoiceFilter(
choices=PortTypeChoices, choices=PortTypeChoices,
null_value=None null_value=None
@ -538,7 +540,7 @@ class FrontPortTemplateFilterSet(BaseFilterSet, DeviceTypeComponentFilterSet):
fields = ['id', 'name', 'type'] fields = ['id', 'name', 'type']
class RearPortTemplateFilterSet(BaseFilterSet, DeviceTypeComponentFilterSet): class RearPortTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
type = django_filters.MultipleChoiceFilter( type = django_filters.MultipleChoiceFilter(
choices=PortTypeChoices, choices=PortTypeChoices,
null_value=None null_value=None
@ -549,21 +551,21 @@ class RearPortTemplateFilterSet(BaseFilterSet, DeviceTypeComponentFilterSet):
fields = ['id', 'name', 'type', 'positions'] fields = ['id', 'name', 'type', 'positions']
class DeviceBayTemplateFilterSet(BaseFilterSet, DeviceTypeComponentFilterSet): class DeviceBayTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
class Meta: class Meta:
model = DeviceBayTemplate model = DeviceBayTemplate
fields = ['id', 'name'] fields = ['id', 'name']
class DeviceRoleFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet): class DeviceRoleFilterSet(OrganizationalModelFilterSet):
class Meta: class Meta:
model = DeviceRole model = DeviceRole
fields = ['id', 'name', 'slug', 'color', 'vm_role'] fields = ['id', 'name', 'slug', 'color', 'vm_role']
class PlatformFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet): class PlatformFilterSet(OrganizationalModelFilterSet):
manufacturer_id = django_filters.ModelMultipleChoiceFilter( manufacturer_id = django_filters.ModelMultipleChoiceFilter(
field_name='manufacturer', field_name='manufacturer',
queryset=Manufacturer.objects.all(), queryset=Manufacturer.objects.all(),
@ -581,13 +583,7 @@ class PlatformFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFi
fields = ['id', 'name', 'slug', 'napalm_driver', 'description'] fields = ['id', 'name', 'slug', 'napalm_driver', 'description']
class DeviceFilterSet( class DeviceFilterSet(PrimaryModelFilterSet, TenancyFilterSet, LocalConfigContextFilterSet):
BaseFilterSet,
TenancyFilterSet,
LocalConfigContextFilterSet,
CustomFieldModelFilterSet,
CreatedUpdatedFilterSet
):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -792,7 +788,7 @@ class DeviceFilterSet(
return queryset.exclude(devicebays__isnull=value) return queryset.exclude(devicebays__isnull=value)
class DeviceComponentFilterSet(CustomFieldModelFilterSet, CreatedUpdatedFilterSet): class DeviceComponentFilterSet(django_filters.FilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -876,7 +872,7 @@ class PathEndpointFilterSet(django_filters.FilterSet):
return queryset.filter(Q(_path__isnull=True) | Q(_path__is_active=False)) return queryset.filter(Q(_path__isnull=True) | Q(_path__is_active=False))
class ConsolePortFilterSet(BaseFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet, PathEndpointFilterSet): class ConsolePortFilterSet(PrimaryModelFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet, PathEndpointFilterSet):
type = django_filters.MultipleChoiceFilter( type = django_filters.MultipleChoiceFilter(
choices=ConsolePortTypeChoices, choices=ConsolePortTypeChoices,
null_value=None null_value=None
@ -887,12 +883,7 @@ class ConsolePortFilterSet(BaseFilterSet, DeviceComponentFilterSet, CableTermina
fields = ['id', 'name', 'label', 'description'] fields = ['id', 'name', 'label', 'description']
class ConsoleServerPortFilterSet( class ConsoleServerPortFilterSet(PrimaryModelFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet, PathEndpointFilterSet):
BaseFilterSet,
DeviceComponentFilterSet,
CableTerminationFilterSet,
PathEndpointFilterSet
):
type = django_filters.MultipleChoiceFilter( type = django_filters.MultipleChoiceFilter(
choices=ConsolePortTypeChoices, choices=ConsolePortTypeChoices,
null_value=None null_value=None
@ -903,7 +894,7 @@ class ConsoleServerPortFilterSet(
fields = ['id', 'name', 'label', 'description'] fields = ['id', 'name', 'label', 'description']
class PowerPortFilterSet(BaseFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet, PathEndpointFilterSet): class PowerPortFilterSet(PrimaryModelFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet, PathEndpointFilterSet):
type = django_filters.MultipleChoiceFilter( type = django_filters.MultipleChoiceFilter(
choices=PowerPortTypeChoices, choices=PowerPortTypeChoices,
null_value=None null_value=None
@ -914,7 +905,7 @@ class PowerPortFilterSet(BaseFilterSet, DeviceComponentFilterSet, CableTerminati
fields = ['id', 'name', 'label', 'maximum_draw', 'allocated_draw', 'description'] fields = ['id', 'name', 'label', 'maximum_draw', 'allocated_draw', 'description']
class PowerOutletFilterSet(BaseFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet, PathEndpointFilterSet): class PowerOutletFilterSet(PrimaryModelFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet, PathEndpointFilterSet):
type = django_filters.MultipleChoiceFilter( type = django_filters.MultipleChoiceFilter(
choices=PowerOutletTypeChoices, choices=PowerOutletTypeChoices,
null_value=None null_value=None
@ -929,7 +920,7 @@ class PowerOutletFilterSet(BaseFilterSet, DeviceComponentFilterSet, CableTermina
fields = ['id', 'name', 'label', 'feed_leg', 'description'] fields = ['id', 'name', 'label', 'feed_leg', 'description']
class InterfaceFilterSet(BaseFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet, PathEndpointFilterSet): class InterfaceFilterSet(PrimaryModelFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet, PathEndpointFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -1027,7 +1018,7 @@ class InterfaceFilterSet(BaseFilterSet, DeviceComponentFilterSet, CableTerminati
}.get(value, queryset.none()) }.get(value, queryset.none())
class FrontPortFilterSet(BaseFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet): class FrontPortFilterSet(PrimaryModelFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet):
type = django_filters.MultipleChoiceFilter( type = django_filters.MultipleChoiceFilter(
choices=PortTypeChoices, choices=PortTypeChoices,
null_value=None null_value=None
@ -1038,7 +1029,7 @@ class FrontPortFilterSet(BaseFilterSet, DeviceComponentFilterSet, CableTerminati
fields = ['id', 'name', 'label', 'type', 'description'] fields = ['id', 'name', 'label', 'type', 'description']
class RearPortFilterSet(BaseFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet): class RearPortFilterSet(PrimaryModelFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet):
type = django_filters.MultipleChoiceFilter( type = django_filters.MultipleChoiceFilter(
choices=PortTypeChoices, choices=PortTypeChoices,
null_value=None null_value=None
@ -1049,14 +1040,14 @@ class RearPortFilterSet(BaseFilterSet, DeviceComponentFilterSet, CableTerminatio
fields = ['id', 'name', 'label', 'type', 'positions', 'description'] fields = ['id', 'name', 'label', 'type', 'positions', 'description']
class DeviceBayFilterSet(BaseFilterSet, DeviceComponentFilterSet): class DeviceBayFilterSet(PrimaryModelFilterSet, DeviceComponentFilterSet):
class Meta: class Meta:
model = DeviceBay model = DeviceBay
fields = ['id', 'name', 'label', 'description'] fields = ['id', 'name', 'label', 'description']
class InventoryItemFilterSet(BaseFilterSet, DeviceComponentFilterSet): class InventoryItemFilterSet(PrimaryModelFilterSet, DeviceComponentFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -1129,7 +1120,7 @@ class InventoryItemFilterSet(BaseFilterSet, DeviceComponentFilterSet):
return queryset.filter(qs_filter) return queryset.filter(qs_filter)
class VirtualChassisFilterSet(BaseFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet): class VirtualChassisFilterSet(PrimaryModelFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -1209,7 +1200,7 @@ class VirtualChassisFilterSet(BaseFilterSet, CustomFieldModelFilterSet, CreatedU
return queryset.filter(qs_filter).distinct() return queryset.filter(qs_filter).distinct()
class CableFilterSet(BaseFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet): class CableFilterSet(PrimaryModelFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -1273,7 +1264,7 @@ class CableFilterSet(BaseFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFil
return queryset return queryset
class ConnectionFilterSet: class ConnectionFilterSet(BaseFilterSet):
def filter_site(self, queryset, name, value): def filter_site(self, queryset, name, value):
if not value.strip(): if not value.strip():
@ -1286,7 +1277,7 @@ class ConnectionFilterSet:
return queryset.filter(**{f'{name}__in': value}) return queryset.filter(**{f'{name}__in': value})
class ConsoleConnectionFilterSet(ConnectionFilterSet, BaseFilterSet): class ConsoleConnectionFilterSet(ConnectionFilterSet):
site = django_filters.CharFilter( site = django_filters.CharFilter(
method='filter_site', method='filter_site',
label='Site (slug)', label='Site (slug)',
@ -1304,7 +1295,7 @@ class ConsoleConnectionFilterSet(ConnectionFilterSet, BaseFilterSet):
fields = ['name'] fields = ['name']
class PowerConnectionFilterSet(ConnectionFilterSet, BaseFilterSet): class PowerConnectionFilterSet(ConnectionFilterSet):
site = django_filters.CharFilter( site = django_filters.CharFilter(
method='filter_site', method='filter_site',
label='Site (slug)', label='Site (slug)',
@ -1322,7 +1313,7 @@ class PowerConnectionFilterSet(ConnectionFilterSet, BaseFilterSet):
fields = ['name'] fields = ['name']
class InterfaceConnectionFilterSet(ConnectionFilterSet, BaseFilterSet): class InterfaceConnectionFilterSet(ConnectionFilterSet):
site = django_filters.CharFilter( site = django_filters.CharFilter(
method='filter_site', method='filter_site',
label='Site (slug)', label='Site (slug)',
@ -1340,7 +1331,7 @@ class InterfaceConnectionFilterSet(ConnectionFilterSet, BaseFilterSet):
fields = [] fields = []
class PowerPanelFilterSet(BaseFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet): class PowerPanelFilterSet(PrimaryModelFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -1402,13 +1393,7 @@ class PowerPanelFilterSet(BaseFilterSet, CustomFieldModelFilterSet, CreatedUpdat
return queryset.filter(qs_filter) return queryset.filter(qs_filter)
class PowerFeedFilterSet( class PowerFeedFilterSet(PrimaryModelFilterSet, CableTerminationFilterSet, PathEndpointFilterSet):
BaseFilterSet,
CableTerminationFilterSet,
PathEndpointFilterSet,
CustomFieldModelFilterSet,
CreatedUpdatedFilterSet
):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',

View File

@ -9,7 +9,7 @@ from rest_framework.routers import APIRootView
from rest_framework.viewsets import ReadOnlyModelViewSet, ViewSet from rest_framework.viewsets import ReadOnlyModelViewSet, ViewSet
from rq import Worker from rq import Worker
from extras import filters from extras import filtersets
from extras.choices import JobResultStatusChoices from extras.choices import JobResultStatusChoices
from extras.models import * from extras.models import *
from extras.models import CustomField from extras.models import CustomField
@ -61,7 +61,7 @@ class WebhookViewSet(ModelViewSet):
metadata_class = ContentTypeMetadata metadata_class = ContentTypeMetadata
queryset = Webhook.objects.all() queryset = Webhook.objects.all()
serializer_class = serializers.WebhookSerializer serializer_class = serializers.WebhookSerializer
filterset_class = filters.WebhookFilterSet filterset_class = filtersets.WebhookFilterSet
# #
@ -72,7 +72,7 @@ class CustomFieldViewSet(ModelViewSet):
metadata_class = ContentTypeMetadata metadata_class = ContentTypeMetadata
queryset = CustomField.objects.all() queryset = CustomField.objects.all()
serializer_class = serializers.CustomFieldSerializer serializer_class = serializers.CustomFieldSerializer
filterset_class = filters.CustomFieldFilterSet filterset_class = filtersets.CustomFieldFilterSet
class CustomFieldModelViewSet(ModelViewSet): class CustomFieldModelViewSet(ModelViewSet):
@ -101,7 +101,7 @@ class CustomLinkViewSet(ModelViewSet):
metadata_class = ContentTypeMetadata metadata_class = ContentTypeMetadata
queryset = CustomLink.objects.all() queryset = CustomLink.objects.all()
serializer_class = serializers.CustomLinkSerializer serializer_class = serializers.CustomLinkSerializer
filterset_class = filters.CustomLinkFilterSet filterset_class = filtersets.CustomLinkFilterSet
# #
@ -112,7 +112,7 @@ class ExportTemplateViewSet(ModelViewSet):
metadata_class = ContentTypeMetadata metadata_class = ContentTypeMetadata
queryset = ExportTemplate.objects.all() queryset = ExportTemplate.objects.all()
serializer_class = serializers.ExportTemplateSerializer serializer_class = serializers.ExportTemplateSerializer
filterset_class = filters.ExportTemplateFilterSet filterset_class = filtersets.ExportTemplateFilterSet
# #
@ -124,7 +124,7 @@ class TagViewSet(ModelViewSet):
tagged_items=count_related(TaggedItem, 'tag') tagged_items=count_related(TaggedItem, 'tag')
) )
serializer_class = serializers.TagSerializer serializer_class = serializers.TagSerializer
filterset_class = filters.TagFilterSet filterset_class = filtersets.TagFilterSet
# #
@ -135,7 +135,7 @@ class ImageAttachmentViewSet(ModelViewSet):
metadata_class = ContentTypeMetadata metadata_class = ContentTypeMetadata
queryset = ImageAttachment.objects.all() queryset = ImageAttachment.objects.all()
serializer_class = serializers.ImageAttachmentSerializer serializer_class = serializers.ImageAttachmentSerializer
filterset_class = filters.ImageAttachmentFilterSet filterset_class = filtersets.ImageAttachmentFilterSet
# #
@ -146,7 +146,7 @@ class JournalEntryViewSet(ModelViewSet):
metadata_class = ContentTypeMetadata metadata_class = ContentTypeMetadata
queryset = JournalEntry.objects.all() queryset = JournalEntry.objects.all()
serializer_class = serializers.JournalEntrySerializer serializer_class = serializers.JournalEntrySerializer
filterset_class = filters.JournalEntryFilterSet filterset_class = filtersets.JournalEntryFilterSet
# #
@ -158,7 +158,7 @@ class ConfigContextViewSet(ModelViewSet):
'regions', 'site_groups', 'sites', 'roles', 'platforms', 'tenant_groups', 'tenants', 'regions', 'site_groups', 'sites', 'roles', 'platforms', 'tenant_groups', 'tenants',
) )
serializer_class = serializers.ConfigContextSerializer serializer_class = serializers.ConfigContextSerializer
filterset_class = filters.ConfigContextFilterSet filterset_class = filtersets.ConfigContextFilterSet
# #
@ -358,7 +358,7 @@ class ObjectChangeViewSet(ReadOnlyModelViewSet):
metadata_class = ContentTypeMetadata metadata_class = ContentTypeMetadata
queryset = ObjectChange.objects.prefetch_related('user') queryset = ObjectChange.objects.prefetch_related('user')
serializer_class = serializers.ObjectChangeSerializer serializer_class = serializers.ObjectChangeSerializer
filterset_class = filters.ObjectChangeFilterSet filterset_class = filtersets.ObjectChangeFilterSet
# #
@ -371,7 +371,7 @@ class JobResultViewSet(ReadOnlyModelViewSet):
""" """
queryset = JobResult.objects.prefetch_related('user') queryset = JobResult.objects.prefetch_related('user')
serializer_class = serializers.JobResultSerializer serializer_class = serializers.JobResultSerializer
filterset_class = filters.JobResultFilterSet filterset_class = filtersets.JobResultFilterSet
# #
@ -384,4 +384,4 @@ class ContentTypeViewSet(ReadOnlyModelViewSet):
""" """
queryset = ContentType.objects.order_by('app_label', 'model') queryset = ContentType.objects.order_by('app_label', 'model')
serializer_class = serializers.ContentTypeSerializer serializer_class = serializers.ContentTypeSerializer
filterset_class = filters.ContentTypeFilterSet filterset_class = filtersets.ContentTypeFilterSet

View File

@ -1,32 +1,10 @@
import django_filters import django_filters
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.db.models import Q
from django.forms import DateField, IntegerField, NullBooleanField from django.forms import DateField, IntegerField, NullBooleanField
from dcim.models import DeviceRole, DeviceType, Platform, Region, Site, SiteGroup
from tenancy.models import Tenant, TenantGroup
from utilities.filtersets import BaseFilterSet
from utilities.filters import ContentTypeFilter
from virtualization.models import Cluster, ClusterGroup
from .choices import * from .choices import *
from .models import *
__all__ = ( __all__ = (
'ConfigContextFilterSet',
'ContentTypeFilterSet',
'CreatedUpdatedFilterSet',
'CustomFieldFilter', 'CustomFieldFilter',
'CustomLinkFilterSet',
'CustomFieldModelFilterSet',
'ExportTemplateFilterSet',
'ImageAttachmentFilterSet',
'JournalEntryFilterSet',
'LocalConfigContextFilterSet',
'ObjectChangeFilterSet',
'TagFilterSet',
'WebhookFilterSet',
) )
EXACT_FILTER_TYPES = ( EXACT_FILTER_TYPES = (
@ -37,41 +15,6 @@ EXACT_FILTER_TYPES = (
) )
class CreatedUpdatedFilterSet(django_filters.FilterSet):
created = django_filters.DateFilter()
created__gte = django_filters.DateFilter(
field_name='created',
lookup_expr='gte'
)
created__lte = django_filters.DateFilter(
field_name='created',
lookup_expr='lte'
)
last_updated = django_filters.DateTimeFilter()
last_updated__gte = django_filters.DateTimeFilter(
field_name='last_updated',
lookup_expr='gte'
)
last_updated__lte = django_filters.DateTimeFilter(
field_name='last_updated',
lookup_expr='lte'
)
class WebhookFilterSet(BaseFilterSet):
content_types = ContentTypeFilter()
http_method = django_filters.MultipleChoiceFilter(
choices=WebhookHttpMethodChoices
)
class Meta:
model = Webhook
fields = [
'id', 'content_types', 'name', 'type_create', 'type_update', 'type_delete', 'payload_url', 'enabled',
'http_method', 'http_content_type', 'secret', 'ssl_verification', 'ca_file_path',
]
class CustomFieldFilter(django_filters.Filter): class CustomFieldFilter(django_filters.Filter):
""" """
Filter objects by the presence of a CustomFieldValue. The filter's name is used as the CustomField name. Filter objects by the presence of a CustomFieldValue. The filter's name is used as the CustomField name.
@ -93,312 +36,3 @@ class CustomFieldFilter(django_filters.Filter):
if custom_field.type not in EXACT_FILTER_TYPES: if custom_field.type not in EXACT_FILTER_TYPES:
if custom_field.filter_logic == CustomFieldFilterLogicChoices.FILTER_LOOSE: if custom_field.filter_logic == CustomFieldFilterLogicChoices.FILTER_LOOSE:
self.lookup_expr = 'icontains' self.lookup_expr = 'icontains'
class CustomFieldModelFilterSet(django_filters.FilterSet):
"""
Dynamically add a Filter for each CustomField applicable to the parent model.
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
custom_fields = CustomField.objects.filter(
content_types=ContentType.objects.get_for_model(self._meta.model)
).exclude(
filter_logic=CustomFieldFilterLogicChoices.FILTER_DISABLED
)
for cf in custom_fields:
self.filters['cf_{}'.format(cf.name)] = CustomFieldFilter(field_name=cf.name, custom_field=cf)
class CustomFieldFilterSet(django_filters.FilterSet):
content_types = ContentTypeFilter()
class Meta:
model = CustomField
fields = ['id', 'content_types', 'name', 'required', 'filter_logic', 'weight']
class CustomLinkFilterSet(BaseFilterSet):
class Meta:
model = CustomLink
fields = ['id', 'content_type', 'name', 'link_text', 'link_url', 'weight', 'group_name', 'new_window']
class ExportTemplateFilterSet(BaseFilterSet):
class Meta:
model = ExportTemplate
fields = ['id', 'content_type', 'name']
class ImageAttachmentFilterSet(BaseFilterSet):
content_type = ContentTypeFilter()
class Meta:
model = ImageAttachment
fields = ['id', 'content_type_id', 'object_id', 'name']
class JournalEntryFilterSet(BaseFilterSet, CreatedUpdatedFilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
)
created = django_filters.DateTimeFromToRangeFilter()
assigned_object_type = ContentTypeFilter()
created_by_id = django_filters.ModelMultipleChoiceFilter(
queryset=User.objects.all(),
label='User (ID)',
)
created_by = django_filters.ModelMultipleChoiceFilter(
field_name='created_by__username',
queryset=User.objects.all(),
to_field_name='username',
label='User (name)',
)
kind = django_filters.MultipleChoiceFilter(
choices=JournalEntryKindChoices
)
class Meta:
model = JournalEntry
fields = ['id', 'assigned_object_type_id', 'assigned_object_id', 'created', 'kind']
def search(self, queryset, name, value):
if not value.strip():
return queryset
return queryset.filter(comments__icontains=value)
class TagFilterSet(BaseFilterSet, CreatedUpdatedFilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
)
class Meta:
model = Tag
fields = ['id', 'name', 'slug', 'color']
def search(self, queryset, name, value):
if not value.strip():
return queryset
return queryset.filter(
Q(name__icontains=value) |
Q(slug__icontains=value)
)
class ConfigContextFilterSet(BaseFilterSet, CreatedUpdatedFilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
)
region_id = django_filters.ModelMultipleChoiceFilter(
field_name='regions',
queryset=Region.objects.all(),
label='Region',
)
region = django_filters.ModelMultipleChoiceFilter(
field_name='regions__slug',
queryset=Region.objects.all(),
to_field_name='slug',
label='Region (slug)',
)
site_group = django_filters.ModelMultipleChoiceFilter(
field_name='site_groups__slug',
queryset=SiteGroup.objects.all(),
to_field_name='slug',
label='Site group (slug)',
)
site_group_id = django_filters.ModelMultipleChoiceFilter(
field_name='site_groups',
queryset=SiteGroup.objects.all(),
label='Site group',
)
site_id = django_filters.ModelMultipleChoiceFilter(
field_name='sites',
queryset=Site.objects.all(),
label='Site',
)
site = django_filters.ModelMultipleChoiceFilter(
field_name='sites__slug',
queryset=Site.objects.all(),
to_field_name='slug',
label='Site (slug)',
)
device_type_id = django_filters.ModelMultipleChoiceFilter(
field_name='device_types',
queryset=DeviceType.objects.all(),
label='Device type',
)
role_id = django_filters.ModelMultipleChoiceFilter(
field_name='roles',
queryset=DeviceRole.objects.all(),
label='Role',
)
role = django_filters.ModelMultipleChoiceFilter(
field_name='roles__slug',
queryset=DeviceRole.objects.all(),
to_field_name='slug',
label='Role (slug)',
)
platform_id = django_filters.ModelMultipleChoiceFilter(
field_name='platforms',
queryset=Platform.objects.all(),
label='Platform',
)
platform = django_filters.ModelMultipleChoiceFilter(
field_name='platforms__slug',
queryset=Platform.objects.all(),
to_field_name='slug',
label='Platform (slug)',
)
cluster_group_id = django_filters.ModelMultipleChoiceFilter(
field_name='cluster_groups',
queryset=ClusterGroup.objects.all(),
label='Cluster group',
)
cluster_group = django_filters.ModelMultipleChoiceFilter(
field_name='cluster_groups__slug',
queryset=ClusterGroup.objects.all(),
to_field_name='slug',
label='Cluster group (slug)',
)
cluster_id = django_filters.ModelMultipleChoiceFilter(
field_name='clusters',
queryset=Cluster.objects.all(),
label='Cluster',
)
tenant_group_id = django_filters.ModelMultipleChoiceFilter(
field_name='tenant_groups',
queryset=TenantGroup.objects.all(),
label='Tenant group',
)
tenant_group = django_filters.ModelMultipleChoiceFilter(
field_name='tenant_groups__slug',
queryset=TenantGroup.objects.all(),
to_field_name='slug',
label='Tenant group (slug)',
)
tenant_id = django_filters.ModelMultipleChoiceFilter(
field_name='tenants',
queryset=Tenant.objects.all(),
label='Tenant',
)
tenant = django_filters.ModelMultipleChoiceFilter(
field_name='tenants__slug',
queryset=Tenant.objects.all(),
to_field_name='slug',
label='Tenant (slug)',
)
tag = django_filters.ModelMultipleChoiceFilter(
field_name='tags__slug',
queryset=Tag.objects.all(),
to_field_name='slug',
label='Tag (slug)',
)
class Meta:
model = ConfigContext
fields = ['id', 'name', 'is_active']
def search(self, queryset, name, value):
if not value.strip():
return queryset
return queryset.filter(
Q(name__icontains=value) |
Q(description__icontains=value) |
Q(data__icontains=value)
)
#
# Filter for Local Config Context Data
#
class LocalConfigContextFilterSet(django_filters.FilterSet):
local_context_data = django_filters.BooleanFilter(
method='_local_context_data',
label='Has local config context data',
)
def _local_context_data(self, queryset, name, value):
return queryset.exclude(local_context_data__isnull=value)
class ObjectChangeFilterSet(BaseFilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
)
time = django_filters.DateTimeFromToRangeFilter()
changed_object_type = ContentTypeFilter()
user_id = django_filters.ModelMultipleChoiceFilter(
queryset=User.objects.all(),
label='User (ID)',
)
user = django_filters.ModelMultipleChoiceFilter(
field_name='user__username',
queryset=User.objects.all(),
to_field_name='username',
label='User name',
)
class Meta:
model = ObjectChange
fields = [
'id', 'user', 'user_name', 'request_id', 'action', 'changed_object_type_id', 'changed_object_id',
'object_repr',
]
def search(self, queryset, name, value):
if not value.strip():
return queryset
return queryset.filter(
Q(user_name__icontains=value) |
Q(object_repr__icontains=value)
)
#
# Job Results
#
class JobResultFilterSet(BaseFilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
)
created = django_filters.DateTimeFilter()
completed = django_filters.DateTimeFilter()
status = django_filters.MultipleChoiceFilter(
choices=JobResultStatusChoices,
null_value=None
)
class Meta:
model = JobResult
fields = [
'id', 'created', 'completed', 'status', 'user', 'obj_type', 'name'
]
def search(self, queryset, name, value):
if not value.strip():
return queryset
return queryset.filter(
Q(user__username__icontains=value)
)
#
# ContentTypes
#
class ContentTypeFilterSet(django_filters.FilterSet):
class Meta:
model = ContentType
fields = ['id', 'app_label', 'model']

340
netbox/extras/filtersets.py Normal file
View File

@ -0,0 +1,340 @@
import django_filters
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.db.models import Q
from dcim.models import DeviceRole, DeviceType, Platform, Region, Site, SiteGroup
from tenancy.models import Tenant, TenantGroup
from utilities.filters import ContentTypeFilter
from utilities.filtersets import BaseFilterSet, ChangeLoggedModelFilterSet
from virtualization.models import Cluster, ClusterGroup
from .choices import *
from .models import *
__all__ = (
'ConfigContextFilterSet',
'ContentTypeFilterSet',
'CustomLinkFilterSet',
'ExportTemplateFilterSet',
'ImageAttachmentFilterSet',
'JournalEntryFilterSet',
'LocalConfigContextFilterSet',
'ObjectChangeFilterSet',
'TagFilterSet',
'WebhookFilterSet',
)
EXACT_FILTER_TYPES = (
CustomFieldTypeChoices.TYPE_BOOLEAN,
CustomFieldTypeChoices.TYPE_DATE,
CustomFieldTypeChoices.TYPE_INTEGER,
CustomFieldTypeChoices.TYPE_SELECT,
)
class WebhookFilterSet(BaseFilterSet):
content_types = ContentTypeFilter()
http_method = django_filters.MultipleChoiceFilter(
choices=WebhookHttpMethodChoices
)
class Meta:
model = Webhook
fields = [
'id', 'content_types', 'name', 'type_create', 'type_update', 'type_delete', 'payload_url', 'enabled',
'http_method', 'http_content_type', 'secret', 'ssl_verification', 'ca_file_path',
]
class CustomFieldFilterSet(django_filters.FilterSet):
content_types = ContentTypeFilter()
class Meta:
model = CustomField
fields = ['id', 'content_types', 'name', 'required', 'filter_logic', 'weight']
class CustomLinkFilterSet(BaseFilterSet):
class Meta:
model = CustomLink
fields = ['id', 'content_type', 'name', 'link_text', 'link_url', 'weight', 'group_name', 'new_window']
class ExportTemplateFilterSet(BaseFilterSet):
class Meta:
model = ExportTemplate
fields = ['id', 'content_type', 'name']
class ImageAttachmentFilterSet(BaseFilterSet):
content_type = ContentTypeFilter()
class Meta:
model = ImageAttachment
fields = ['id', 'content_type_id', 'object_id', 'name']
class JournalEntryFilterSet(ChangeLoggedModelFilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
)
created = django_filters.DateTimeFromToRangeFilter()
assigned_object_type = ContentTypeFilter()
created_by_id = django_filters.ModelMultipleChoiceFilter(
queryset=User.objects.all(),
label='User (ID)',
)
created_by = django_filters.ModelMultipleChoiceFilter(
field_name='created_by__username',
queryset=User.objects.all(),
to_field_name='username',
label='User (name)',
)
kind = django_filters.MultipleChoiceFilter(
choices=JournalEntryKindChoices
)
class Meta:
model = JournalEntry
fields = ['id', 'assigned_object_type_id', 'assigned_object_id', 'created', 'kind']
def search(self, queryset, name, value):
if not value.strip():
return queryset
return queryset.filter(comments__icontains=value)
class TagFilterSet(ChangeLoggedModelFilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
)
class Meta:
model = Tag
fields = ['id', 'name', 'slug', 'color']
def search(self, queryset, name, value):
if not value.strip():
return queryset
return queryset.filter(
Q(name__icontains=value) |
Q(slug__icontains=value)
)
class ConfigContextFilterSet(ChangeLoggedModelFilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
)
region_id = django_filters.ModelMultipleChoiceFilter(
field_name='regions',
queryset=Region.objects.all(),
label='Region',
)
region = django_filters.ModelMultipleChoiceFilter(
field_name='regions__slug',
queryset=Region.objects.all(),
to_field_name='slug',
label='Region (slug)',
)
site_group = django_filters.ModelMultipleChoiceFilter(
field_name='site_groups__slug',
queryset=SiteGroup.objects.all(),
to_field_name='slug',
label='Site group (slug)',
)
site_group_id = django_filters.ModelMultipleChoiceFilter(
field_name='site_groups',
queryset=SiteGroup.objects.all(),
label='Site group',
)
site_id = django_filters.ModelMultipleChoiceFilter(
field_name='sites',
queryset=Site.objects.all(),
label='Site',
)
site = django_filters.ModelMultipleChoiceFilter(
field_name='sites__slug',
queryset=Site.objects.all(),
to_field_name='slug',
label='Site (slug)',
)
device_type_id = django_filters.ModelMultipleChoiceFilter(
field_name='device_types',
queryset=DeviceType.objects.all(),
label='Device type',
)
role_id = django_filters.ModelMultipleChoiceFilter(
field_name='roles',
queryset=DeviceRole.objects.all(),
label='Role',
)
role = django_filters.ModelMultipleChoiceFilter(
field_name='roles__slug',
queryset=DeviceRole.objects.all(),
to_field_name='slug',
label='Role (slug)',
)
platform_id = django_filters.ModelMultipleChoiceFilter(
field_name='platforms',
queryset=Platform.objects.all(),
label='Platform',
)
platform = django_filters.ModelMultipleChoiceFilter(
field_name='platforms__slug',
queryset=Platform.objects.all(),
to_field_name='slug',
label='Platform (slug)',
)
cluster_group_id = django_filters.ModelMultipleChoiceFilter(
field_name='cluster_groups',
queryset=ClusterGroup.objects.all(),
label='Cluster group',
)
cluster_group = django_filters.ModelMultipleChoiceFilter(
field_name='cluster_groups__slug',
queryset=ClusterGroup.objects.all(),
to_field_name='slug',
label='Cluster group (slug)',
)
cluster_id = django_filters.ModelMultipleChoiceFilter(
field_name='clusters',
queryset=Cluster.objects.all(),
label='Cluster',
)
tenant_group_id = django_filters.ModelMultipleChoiceFilter(
field_name='tenant_groups',
queryset=TenantGroup.objects.all(),
label='Tenant group',
)
tenant_group = django_filters.ModelMultipleChoiceFilter(
field_name='tenant_groups__slug',
queryset=TenantGroup.objects.all(),
to_field_name='slug',
label='Tenant group (slug)',
)
tenant_id = django_filters.ModelMultipleChoiceFilter(
field_name='tenants',
queryset=Tenant.objects.all(),
label='Tenant',
)
tenant = django_filters.ModelMultipleChoiceFilter(
field_name='tenants__slug',
queryset=Tenant.objects.all(),
to_field_name='slug',
label='Tenant (slug)',
)
tag = django_filters.ModelMultipleChoiceFilter(
field_name='tags__slug',
queryset=Tag.objects.all(),
to_field_name='slug',
label='Tag (slug)',
)
class Meta:
model = ConfigContext
fields = ['id', 'name', 'is_active']
def search(self, queryset, name, value):
if not value.strip():
return queryset
return queryset.filter(
Q(name__icontains=value) |
Q(description__icontains=value) |
Q(data__icontains=value)
)
#
# Filter for Local Config Context Data
#
class LocalConfigContextFilterSet(django_filters.FilterSet):
local_context_data = django_filters.BooleanFilter(
method='_local_context_data',
label='Has local config context data',
)
def _local_context_data(self, queryset, name, value):
return queryset.exclude(local_context_data__isnull=value)
class ObjectChangeFilterSet(BaseFilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
)
time = django_filters.DateTimeFromToRangeFilter()
changed_object_type = ContentTypeFilter()
user_id = django_filters.ModelMultipleChoiceFilter(
queryset=User.objects.all(),
label='User (ID)',
)
user = django_filters.ModelMultipleChoiceFilter(
field_name='user__username',
queryset=User.objects.all(),
to_field_name='username',
label='User name',
)
class Meta:
model = ObjectChange
fields = [
'id', 'user', 'user_name', 'request_id', 'action', 'changed_object_type_id', 'changed_object_id',
'object_repr',
]
def search(self, queryset, name, value):
if not value.strip():
return queryset
return queryset.filter(
Q(user_name__icontains=value) |
Q(object_repr__icontains=value)
)
#
# Job Results
#
class JobResultFilterSet(BaseFilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
)
created = django_filters.DateTimeFilter()
completed = django_filters.DateTimeFilter()
status = django_filters.MultipleChoiceFilter(
choices=JobResultStatusChoices,
null_value=None
)
class Meta:
model = JobResult
fields = [
'id', 'created', 'completed', 'status', 'user', 'obj_type', 'name'
]
def search(self, queryset, name, value):
if not value.strip():
return queryset
return queryset.filter(
Q(user__username__icontains=value)
)
#
# ContentTypes
#
class ContentTypeFilterSet(django_filters.FilterSet):
class Meta:
model = ContentType
fields = ['id', 'app_label', 'model']

View File

@ -6,7 +6,7 @@ from django.test import TestCase
from dcim.models import DeviceRole, DeviceType, Manufacturer, Platform, Rack, Region, Site, SiteGroup from dcim.models import DeviceRole, DeviceType, Manufacturer, Platform, Rack, Region, Site, SiteGroup
from extras.choices import JournalEntryKindChoices, ObjectChangeActionChoices from extras.choices import JournalEntryKindChoices, ObjectChangeActionChoices
from extras.filters import * from extras.filtersets import *
from extras.models import * from extras.models import *
from ipam.models import IPAddress from ipam.models import IPAddress
from tenancy.models import Tenant, TenantGroup from tenancy.models import Tenant, TenantGroup

View File

@ -13,7 +13,7 @@ from utilities.forms import ConfirmationForm
from utilities.tables import paginate_table from utilities.tables import paginate_table
from utilities.utils import copy_safe_request, count_related, shallow_compare_dict from utilities.utils import copy_safe_request, count_related, shallow_compare_dict
from utilities.views import ContentTypePermissionRequiredMixin from utilities.views import ContentTypePermissionRequiredMixin
from . import filters, forms, tables from . import filtersets, forms, tables
from .choices import JobResultStatusChoices from .choices import JobResultStatusChoices
from .models import ConfigContext, ImageAttachment, JournalEntry, ObjectChange, JobResult, Tag, TaggedItem from .models import ConfigContext, ImageAttachment, JournalEntry, ObjectChange, JobResult, Tag, TaggedItem
from .reports import get_report, get_reports, run_report from .reports import get_report, get_reports, run_report
@ -28,7 +28,7 @@ class TagListView(generic.ObjectListView):
queryset = Tag.objects.annotate( queryset = Tag.objects.annotate(
items=count_related(TaggedItem, 'tag') items=count_related(TaggedItem, 'tag')
) )
filterset = filters.TagFilterSet filterset = filtersets.TagFilterSet
filterset_form = forms.TagFilterForm filterset_form = forms.TagFilterForm
table = tables.TagTable table = tables.TagTable
@ -94,7 +94,7 @@ class TagBulkDeleteView(generic.BulkDeleteView):
class ConfigContextListView(generic.ObjectListView): class ConfigContextListView(generic.ObjectListView):
queryset = ConfigContext.objects.all() queryset = ConfigContext.objects.all()
filterset = filters.ConfigContextFilterSet filterset = filtersets.ConfigContextFilterSet
filterset_form = forms.ConfigContextFilterForm filterset_form = forms.ConfigContextFilterForm
table = tables.ConfigContextTable table = tables.ConfigContextTable
action_buttons = ('add',) action_buttons = ('add',)
@ -127,7 +127,7 @@ class ConfigContextEditView(generic.ObjectEditView):
class ConfigContextBulkEditView(generic.BulkEditView): class ConfigContextBulkEditView(generic.BulkEditView):
queryset = ConfigContext.objects.all() queryset = ConfigContext.objects.all()
filterset = filters.ConfigContextFilterSet filterset = filtersets.ConfigContextFilterSet
table = tables.ConfigContextTable table = tables.ConfigContextTable
form = forms.ConfigContextBulkEditForm form = forms.ConfigContextBulkEditForm
@ -173,7 +173,7 @@ class ObjectConfigContextView(generic.ObjectView):
class ObjectChangeListView(generic.ObjectListView): class ObjectChangeListView(generic.ObjectListView):
queryset = ObjectChange.objects.all() queryset = ObjectChange.objects.all()
filterset = filters.ObjectChangeFilterSet filterset = filtersets.ObjectChangeFilterSet
filterset_form = forms.ObjectChangeFilterForm filterset_form = forms.ObjectChangeFilterForm
table = tables.ObjectChangeTable table = tables.ObjectChangeTable
template_name = 'extras/objectchange_list.html' template_name = 'extras/objectchange_list.html'
@ -300,7 +300,7 @@ class ImageAttachmentDeleteView(generic.ObjectDeleteView):
class JournalEntryListView(generic.ObjectListView): class JournalEntryListView(generic.ObjectListView):
queryset = JournalEntry.objects.all() queryset = JournalEntry.objects.all()
filterset = filters.JournalEntryFilterSet filterset = filtersets.JournalEntryFilterSet
filterset_form = forms.JournalEntryFilterForm filterset_form = forms.JournalEntryFilterForm
table = tables.JournalEntryTable table = tables.JournalEntryTable
action_buttons = ('export',) action_buttons = ('export',)
@ -338,14 +338,14 @@ class JournalEntryDeleteView(generic.ObjectDeleteView):
class JournalEntryBulkEditView(generic.BulkEditView): class JournalEntryBulkEditView(generic.BulkEditView):
queryset = JournalEntry.objects.prefetch_related('created_by') queryset = JournalEntry.objects.prefetch_related('created_by')
filterset = filters.JournalEntryFilterSet filterset = filtersets.JournalEntryFilterSet
table = tables.JournalEntryTable table = tables.JournalEntryTable
form = forms.JournalEntryBulkEditForm form = forms.JournalEntryBulkEditForm
class JournalEntryBulkDeleteView(generic.BulkDeleteView): class JournalEntryBulkDeleteView(generic.BulkDeleteView):
queryset = JournalEntry.objects.prefetch_related('created_by') queryset = JournalEntry.objects.prefetch_related('created_by')
filterset = filters.JournalEntryFilterSet filterset = filtersets.JournalEntryFilterSet
table = tables.JournalEntryTable table = tables.JournalEntryTable

View File

@ -6,13 +6,12 @@ from django.db.models import Q
from netaddr.core import AddrFormatError from netaddr.core import AddrFormatError
from dcim.models import Device, Interface, Region, Site, SiteGroup from dcim.models import Device, Interface, Region, Site, SiteGroup
from extras.filters import CustomFieldModelFilterSet, CreatedUpdatedFilterSet
from tenancy.filters import TenancyFilterSet from tenancy.filters import TenancyFilterSet
from utilities.filters import ( from utilities.filters import (
ContentTypeFilter, MultiValueCharFilter, MultiValueNumberFilter, NumericArrayFilter, TagFilter, ContentTypeFilter, MultiValueCharFilter, MultiValueNumberFilter, NumericArrayFilter, TagFilter,
TreeNodeMultipleChoiceFilter, TreeNodeMultipleChoiceFilter,
) )
from utilities.filtersets import BaseFilterSet, NameSlugSearchFilterSet from utilities.filtersets import OrganizationalModelFilterSet, PrimaryModelFilterSet
from virtualization.models import VirtualMachine, VMInterface from virtualization.models import VirtualMachine, VMInterface
from .choices import * from .choices import *
from .models import Aggregate, IPAddress, Prefix, RIR, Role, RouteTarget, Service, VLAN, VLANGroup, VRF from .models import Aggregate, IPAddress, Prefix, RIR, Role, RouteTarget, Service, VLAN, VLANGroup, VRF
@ -32,7 +31,7 @@ __all__ = (
) )
class VRFFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet): class VRFFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -75,7 +74,7 @@ class VRFFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSet, C
fields = ['id', 'name', 'rd', 'enforce_unique'] fields = ['id', 'name', 'rd', 'enforce_unique']
class RouteTargetFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet): class RouteTargetFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -117,14 +116,14 @@ class RouteTargetFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilt
fields = ['id', 'name'] fields = ['id', 'name']
class RIRFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet): class RIRFilterSet(OrganizationalModelFilterSet):
class Meta: class Meta:
model = RIR model = RIR
fields = ['id', 'name', 'slug', 'is_private', 'description'] fields = ['id', 'name', 'slug', 'is_private', 'description']
class AggregateFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet): class AggregateFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -174,7 +173,7 @@ class AggregateFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilter
return queryset.none() return queryset.none()
class RoleFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet): class RoleFilterSet(OrganizationalModelFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -185,7 +184,7 @@ class RoleFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilter
fields = ['id', 'name', 'slug'] fields = ['id', 'name', 'slug']
class PrefixFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet): class PrefixFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -370,7 +369,7 @@ class PrefixFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSet
) )
class IPAddressFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet): class IPAddressFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -536,7 +535,7 @@ class IPAddressFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilter
return queryset.exclude(assigned_object_id__isnull=value) return queryset.exclude(assigned_object_id__isnull=value)
class VLANGroupFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet): class VLANGroupFilterSet(OrganizationalModelFilterSet):
scope_type = ContentTypeFilter() scope_type = ContentTypeFilter()
region = django_filters.NumberFilter( region = django_filters.NumberFilter(
method='filter_scope' method='filter_scope'
@ -571,7 +570,7 @@ class VLANGroupFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedF
) )
class VLANFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet): class VLANFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -667,7 +666,7 @@ class VLANFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSet,
return queryset.get_for_virtualmachine(value) return queryset.get_for_virtualmachine(value)
class ServiceFilterSet(BaseFilterSet, CreatedUpdatedFilterSet): class ServiceFilterSet(PrimaryModelFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',

View File

@ -2,9 +2,8 @@ import django_filters
from django.db.models import Q from django.db.models import Q
from dcim.models import Device from dcim.models import Device
from extras.filters import CustomFieldModelFilterSet, CreatedUpdatedFilterSet
from utilities.filters import TagFilter from utilities.filters import TagFilter
from utilities.filtersets import BaseFilterSet, NameSlugSearchFilterSet from utilities.filtersets import OrganizationalModelFilterSet, PrimaryModelFilterSet
from virtualization.models import VirtualMachine from virtualization.models import VirtualMachine
from .models import Secret, SecretRole from .models import Secret, SecretRole
@ -15,14 +14,14 @@ __all__ = (
) )
class SecretRoleFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet): class SecretRoleFilterSet(OrganizationalModelFilterSet):
class Meta: class Meta:
model = SecretRole model = SecretRole
fields = ['id', 'name', 'slug'] fields = ['id', 'name', 'slug']
class SecretFilterSet(BaseFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet): class SecretFilterSet(PrimaryModelFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',

View File

@ -1,9 +1,8 @@
import django_filters import django_filters
from django.db.models import Q from django.db.models import Q
from extras.filters import CustomFieldModelFilterSet, CreatedUpdatedFilterSet
from utilities.filters import TagFilter, TreeNodeMultipleChoiceFilter from utilities.filters import TagFilter, TreeNodeMultipleChoiceFilter
from utilities.filtersets import BaseFilterSet, NameSlugSearchFilterSet from utilities.filtersets import OrganizationalModelFilterSet, PrimaryModelFilterSet
from .models import Tenant, TenantGroup from .models import Tenant, TenantGroup
@ -14,7 +13,7 @@ __all__ = (
) )
class TenantGroupFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet): class TenantGroupFilterSet(OrganizationalModelFilterSet):
parent_id = django_filters.ModelMultipleChoiceFilter( parent_id = django_filters.ModelMultipleChoiceFilter(
queryset=TenantGroup.objects.all(), queryset=TenantGroup.objects.all(),
label='Tenant group (ID)', label='Tenant group (ID)',
@ -31,7 +30,7 @@ class TenantGroupFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdate
fields = ['id', 'name', 'slug', 'description'] fields = ['id', 'name', 'slug', 'description']
class TenantFilterSet(BaseFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet): class TenantFilterSet(PrimaryModelFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',

View File

@ -1,9 +1,13 @@
import django_filters import django_filters
from copy import deepcopy from copy import deepcopy
from dcim.forms import MACAddressField from django.contrib.contenttypes.models import ContentType
from django.db import models from django.db import models
from django_filters.utils import get_model_field, resolve_field from django_filters.utils import get_model_field, resolve_field
from dcim.forms import MACAddressField
from extras.choices import CustomFieldFilterLogicChoices
from extras.filters import CustomFieldFilter
from extras.models import CustomField
from utilities.constants import ( from utilities.constants import (
FILTER_CHAR_BASED_LOOKUP_MAP, FILTER_NEGATION_LOOKUP_MAP, FILTER_TREENODE_NEGATION_LOOKUP_MAP, FILTER_CHAR_BASED_LOOKUP_MAP, FILTER_NEGATION_LOOKUP_MAP, FILTER_TREENODE_NEGATION_LOOKUP_MAP,
FILTER_NUMERIC_BASED_LOOKUP_MAP FILTER_NUMERIC_BASED_LOOKUP_MAP
@ -11,6 +15,14 @@ from utilities.constants import (
from utilities import filters from utilities import filters
__all__ = (
'BaseFilterSet',
'ChangeLoggedModelFilterSet',
'OrganizationalModelFilterSet',
'PrimaryModelFilterSet',
)
# #
# FilterSets # FilterSets
# #
@ -172,7 +184,43 @@ class BaseFilterSet(django_filters.FilterSet):
return filters return filters
class NameSlugSearchFilterSet(django_filters.FilterSet): class ChangeLoggedModelFilterSet(BaseFilterSet):
created = django_filters.DateFilter()
created__gte = django_filters.DateFilter(
field_name='created',
lookup_expr='gte'
)
created__lte = django_filters.DateFilter(
field_name='created',
lookup_expr='lte'
)
last_updated = django_filters.DateTimeFilter()
last_updated__gte = django_filters.DateTimeFilter(
field_name='last_updated',
lookup_expr='gte'
)
last_updated__lte = django_filters.DateTimeFilter(
field_name='last_updated',
lookup_expr='lte'
)
class PrimaryModelFilterSet(ChangeLoggedModelFilterSet):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Dynamically add a Filter for each CustomField applicable to the parent model
custom_fields = CustomField.objects.filter(
content_types=ContentType.objects.get_for_model(self._meta.model)
).exclude(
filter_logic=CustomFieldFilterLogicChoices.FILTER_DISABLED
)
for cf in custom_fields:
self.filters['cf_{}'.format(cf.name)] = CustomFieldFilter(field_name=cf.name, custom_field=cf)
class OrganizationalModelFilterSet(PrimaryModelFilterSet):
""" """
A base class for adding the search method to models which only expose the `name` and `slug` fields A base class for adding the search method to models which only expose the `name` and `slug` fields
""" """

View File

@ -2,10 +2,10 @@ import django_filters
from django.db.models import Q from django.db.models import Q
from dcim.models import DeviceRole, Platform, Region, Site, SiteGroup from dcim.models import DeviceRole, Platform, Region, Site, SiteGroup
from extras.filters import CustomFieldModelFilterSet, CreatedUpdatedFilterSet, LocalConfigContextFilterSet from extras.filtersets import LocalConfigContextFilterSet
from tenancy.filters import TenancyFilterSet from tenancy.filters import TenancyFilterSet
from utilities.filters import MultiValueMACAddressFilter, TagFilter, TreeNodeMultipleChoiceFilter from utilities.filters import MultiValueMACAddressFilter, TagFilter, TreeNodeMultipleChoiceFilter
from utilities.filtersets import BaseFilterSet, NameSlugSearchFilterSet from utilities.filtersets import OrganizationalModelFilterSet, PrimaryModelFilterSet
from .choices import * from .choices import *
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
@ -18,21 +18,21 @@ __all__ = (
) )
class ClusterTypeFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet): class ClusterTypeFilterSet(OrganizationalModelFilterSet):
class Meta: class Meta:
model = ClusterType model = ClusterType
fields = ['id', 'name', 'slug', 'description'] fields = ['id', 'name', 'slug', 'description']
class ClusterGroupFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet): class ClusterGroupFilterSet(OrganizationalModelFilterSet):
class Meta: class Meta:
model = ClusterGroup model = ClusterGroup
fields = ['id', 'name', 'slug', 'description'] fields = ['id', 'name', 'slug', 'description']
class ClusterFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet): class ClusterFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -108,13 +108,7 @@ class ClusterFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSe
) )
class VirtualMachineFilterSet( class VirtualMachineFilterSet(PrimaryModelFilterSet, TenancyFilterSet, LocalConfigContextFilterSet):
BaseFilterSet,
LocalConfigContextFilterSet,
TenancyFilterSet,
CustomFieldModelFilterSet,
CreatedUpdatedFilterSet
):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -235,7 +229,7 @@ class VirtualMachineFilterSet(
return queryset.exclude(params) return queryset.exclude(params)
class VMInterfaceFilterSet(BaseFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet): class VMInterfaceFilterSet(PrimaryModelFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',