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

View File

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

View File

@ -9,7 +9,7 @@ from rest_framework.routers import APIRootView
from rest_framework.viewsets import ReadOnlyModelViewSet, ViewSet
from rq import Worker
from extras import filters
from extras import filtersets
from extras.choices import JobResultStatusChoices
from extras.models import *
from extras.models import CustomField
@ -61,7 +61,7 @@ class WebhookViewSet(ModelViewSet):
metadata_class = ContentTypeMetadata
queryset = Webhook.objects.all()
serializer_class = serializers.WebhookSerializer
filterset_class = filters.WebhookFilterSet
filterset_class = filtersets.WebhookFilterSet
#
@ -72,7 +72,7 @@ class CustomFieldViewSet(ModelViewSet):
metadata_class = ContentTypeMetadata
queryset = CustomField.objects.all()
serializer_class = serializers.CustomFieldSerializer
filterset_class = filters.CustomFieldFilterSet
filterset_class = filtersets.CustomFieldFilterSet
class CustomFieldModelViewSet(ModelViewSet):
@ -101,7 +101,7 @@ class CustomLinkViewSet(ModelViewSet):
metadata_class = ContentTypeMetadata
queryset = CustomLink.objects.all()
serializer_class = serializers.CustomLinkSerializer
filterset_class = filters.CustomLinkFilterSet
filterset_class = filtersets.CustomLinkFilterSet
#
@ -112,7 +112,7 @@ class ExportTemplateViewSet(ModelViewSet):
metadata_class = ContentTypeMetadata
queryset = ExportTemplate.objects.all()
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')
)
serializer_class = serializers.TagSerializer
filterset_class = filters.TagFilterSet
filterset_class = filtersets.TagFilterSet
#
@ -135,7 +135,7 @@ class ImageAttachmentViewSet(ModelViewSet):
metadata_class = ContentTypeMetadata
queryset = ImageAttachment.objects.all()
serializer_class = serializers.ImageAttachmentSerializer
filterset_class = filters.ImageAttachmentFilterSet
filterset_class = filtersets.ImageAttachmentFilterSet
#
@ -146,7 +146,7 @@ class JournalEntryViewSet(ModelViewSet):
metadata_class = ContentTypeMetadata
queryset = JournalEntry.objects.all()
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',
)
serializer_class = serializers.ConfigContextSerializer
filterset_class = filters.ConfigContextFilterSet
filterset_class = filtersets.ConfigContextFilterSet
#
@ -358,7 +358,7 @@ class ObjectChangeViewSet(ReadOnlyModelViewSet):
metadata_class = ContentTypeMetadata
queryset = ObjectChange.objects.prefetch_related('user')
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')
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')
serializer_class = serializers.ContentTypeSerializer
filterset_class = filters.ContentTypeFilterSet
filterset_class = filtersets.ContentTypeFilterSet

View File

@ -1,32 +1,10 @@
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 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 .models import *
__all__ = (
'ConfigContextFilterSet',
'ContentTypeFilterSet',
'CreatedUpdatedFilterSet',
'CustomFieldFilter',
'CustomLinkFilterSet',
'CustomFieldModelFilterSet',
'ExportTemplateFilterSet',
'ImageAttachmentFilterSet',
'JournalEntryFilterSet',
'LocalConfigContextFilterSet',
'ObjectChangeFilterSet',
'TagFilterSet',
'WebhookFilterSet',
)
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):
"""
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.filter_logic == CustomFieldFilterLogicChoices.FILTER_LOOSE:
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 extras.choices import JournalEntryKindChoices, ObjectChangeActionChoices
from extras.filters import *
from extras.filtersets import *
from extras.models import *
from ipam.models import IPAddress
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.utils import copy_safe_request, count_related, shallow_compare_dict
from utilities.views import ContentTypePermissionRequiredMixin
from . import filters, forms, tables
from . import filtersets, forms, tables
from .choices import JobResultStatusChoices
from .models import ConfigContext, ImageAttachment, JournalEntry, ObjectChange, JobResult, Tag, TaggedItem
from .reports import get_report, get_reports, run_report
@ -28,7 +28,7 @@ class TagListView(generic.ObjectListView):
queryset = Tag.objects.annotate(
items=count_related(TaggedItem, 'tag')
)
filterset = filters.TagFilterSet
filterset = filtersets.TagFilterSet
filterset_form = forms.TagFilterForm
table = tables.TagTable
@ -94,7 +94,7 @@ class TagBulkDeleteView(generic.BulkDeleteView):
class ConfigContextListView(generic.ObjectListView):
queryset = ConfigContext.objects.all()
filterset = filters.ConfigContextFilterSet
filterset = filtersets.ConfigContextFilterSet
filterset_form = forms.ConfigContextFilterForm
table = tables.ConfigContextTable
action_buttons = ('add',)
@ -127,7 +127,7 @@ class ConfigContextEditView(generic.ObjectEditView):
class ConfigContextBulkEditView(generic.BulkEditView):
queryset = ConfigContext.objects.all()
filterset = filters.ConfigContextFilterSet
filterset = filtersets.ConfigContextFilterSet
table = tables.ConfigContextTable
form = forms.ConfigContextBulkEditForm
@ -173,7 +173,7 @@ class ObjectConfigContextView(generic.ObjectView):
class ObjectChangeListView(generic.ObjectListView):
queryset = ObjectChange.objects.all()
filterset = filters.ObjectChangeFilterSet
filterset = filtersets.ObjectChangeFilterSet
filterset_form = forms.ObjectChangeFilterForm
table = tables.ObjectChangeTable
template_name = 'extras/objectchange_list.html'
@ -300,7 +300,7 @@ class ImageAttachmentDeleteView(generic.ObjectDeleteView):
class JournalEntryListView(generic.ObjectListView):
queryset = JournalEntry.objects.all()
filterset = filters.JournalEntryFilterSet
filterset = filtersets.JournalEntryFilterSet
filterset_form = forms.JournalEntryFilterForm
table = tables.JournalEntryTable
action_buttons = ('export',)
@ -338,14 +338,14 @@ class JournalEntryDeleteView(generic.ObjectDeleteView):
class JournalEntryBulkEditView(generic.BulkEditView):
queryset = JournalEntry.objects.prefetch_related('created_by')
filterset = filters.JournalEntryFilterSet
filterset = filtersets.JournalEntryFilterSet
table = tables.JournalEntryTable
form = forms.JournalEntryBulkEditForm
class JournalEntryBulkDeleteView(generic.BulkDeleteView):
queryset = JournalEntry.objects.prefetch_related('created_by')
filterset = filters.JournalEntryFilterSet
filterset = filtersets.JournalEntryFilterSet
table = tables.JournalEntryTable

View File

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

View File

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

View File

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

View File

@ -1,9 +1,13 @@
import django_filters
from copy import deepcopy
from dcim.forms import MACAddressField
from django.contrib.contenttypes.models import ContentType
from django.db import models
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 (
FILTER_CHAR_BASED_LOOKUP_MAP, FILTER_NEGATION_LOOKUP_MAP, FILTER_TREENODE_NEGATION_LOOKUP_MAP,
FILTER_NUMERIC_BASED_LOOKUP_MAP
@ -11,6 +15,14 @@ from utilities.constants import (
from utilities import filters
__all__ = (
'BaseFilterSet',
'ChangeLoggedModelFilterSet',
'OrganizationalModelFilterSet',
'PrimaryModelFilterSet',
)
#
# FilterSets
#
@ -172,7 +184,43 @@ class BaseFilterSet(django_filters.FilterSet):
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
"""

View File

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