فهرست منبع

Fixes #6262: Support filtering by created/updated time for all relevant objects

jeremystretch 4 سال پیش
والد
کامیت
58659cf3b6

+ 1 - 0
docs/release-notes/version-2.11.md

@@ -16,6 +16,7 @@
 * [#6252](https://github.com/netbox-community/netbox/issues/6252) - Fix assignment of console port speed values above 19.2kbps
 * [#6254](https://github.com/netbox-community/netbox/issues/6254) - Disable ordering of space column in racks table
 * [#6258](https://github.com/netbox-community/netbox/issues/6258) - Fix parent assignment for SiteGroup API serializer
+* [#6262](https://github.com/netbox-community/netbox/issues/6262) - Support filtering by created/updated time for all relevant objects
 * [#6267](https://github.com/netbox-community/netbox/issues/6267) - Fix cable tracing API endpoint for circuit terminations
 * [#6289](https://github.com/netbox-community/netbox/issues/6289) - Fix assignment of VC member interfaces to LAG interfaces
 

+ 3 - 3
netbox/circuits/filters.py

@@ -1,7 +1,7 @@
 import django_filters
 from django.db.models import Q
 
-from dcim.filters import CableTerminationFilterSet, PathEndpointFilterSet
+from dcim.filters import CableTerminationFilterSet
 from dcim.models import Region, Site, SiteGroup
 from extras.filters import CustomFieldModelFilterSet, CreatedUpdatedFilterSet
 from tenancy.filters import TenancyFilterSet
@@ -110,7 +110,7 @@ class ProviderNetworkFilterSet(BaseFilterSet, CustomFieldModelFilterSet, Created
         ).distinct()
 
 
-class CircuitTypeFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
+class CircuitTypeFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet):
 
     class Meta:
         model = CircuitType
@@ -207,7 +207,7 @@ class CircuitFilterSet(BaseFilterSet, CustomFieldModelFilterSet, TenancyFilterSe
         ).distinct()
 
 
-class CircuitTerminationFilterSet(BaseFilterSet, CableTerminationFilterSet):
+class CircuitTerminationFilterSet(BaseFilterSet, CreatedUpdatedFilterSet, CableTerminationFilterSet):
     q = django_filters.CharFilter(
         method='search',
         label='Search',

+ 13 - 13
netbox/dcim/filters.py

@@ -57,7 +57,7 @@ __all__ = (
 )
 
 
-class RegionFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
+class RegionFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet):
     parent_id = django_filters.ModelMultipleChoiceFilter(
         queryset=Region.objects.all(),
         label='Parent region (ID)',
@@ -74,7 +74,7 @@ class RegionFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
         fields = ['id', 'name', 'slug', 'description']
 
 
-class SiteGroupFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
+class SiteGroupFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet):
     parent_id = django_filters.ModelMultipleChoiceFilter(
         queryset=SiteGroup.objects.all(),
         label='Parent site group (ID)',
@@ -154,7 +154,7 @@ class SiteFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSet,
         return queryset.filter(qs_filter)
 
 
-class LocationFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
+class LocationFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet):
     region_id = TreeNodeMultipleChoiceFilter(
         queryset=Region.objects.all(),
         field_name='site__region',
@@ -218,7 +218,7 @@ class LocationFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
         )
 
 
-class RackRoleFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
+class RackRoleFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet):
 
     class Meta:
         model = RackRole
@@ -323,7 +323,7 @@ class RackFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSet,
         )
 
 
-class RackReservationFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSet):
+class RackReservationFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet):
     q = django_filters.CharFilter(
         method='search',
         label='Search',
@@ -383,7 +383,7 @@ class RackReservationFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModel
         )
 
 
-class ManufacturerFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
+class ManufacturerFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet):
 
     class Meta:
         model = Manufacturer
@@ -476,7 +476,7 @@ class DeviceTypeFilterSet(BaseFilterSet, CustomFieldModelFilterSet, CreatedUpdat
         return queryset.exclude(devicebaytemplates__isnull=value)
 
 
-class DeviceTypeComponentFilterSet(NameSlugSearchFilterSet):
+class DeviceTypeComponentFilterSet(NameSlugSearchFilterSet, CreatedUpdatedFilterSet):
     devicetype_id = django_filters.ModelMultipleChoiceFilter(
         queryset=DeviceType.objects.all(),
         field_name='device_type_id',
@@ -556,14 +556,14 @@ class DeviceBayTemplateFilterSet(BaseFilterSet, DeviceTypeComponentFilterSet):
         fields = ['id', 'name']
 
 
-class DeviceRoleFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
+class DeviceRoleFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet):
 
     class Meta:
         model = DeviceRole
         fields = ['id', 'name', 'slug', 'color', 'vm_role']
 
 
-class PlatformFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
+class PlatformFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet):
     manufacturer_id = django_filters.ModelMultipleChoiceFilter(
         field_name='manufacturer',
         queryset=Manufacturer.objects.all(),
@@ -792,7 +792,7 @@ class DeviceFilterSet(
         return queryset.exclude(devicebays__isnull=value)
 
 
-class DeviceComponentFilterSet(CustomFieldModelFilterSet):
+class DeviceComponentFilterSet(CustomFieldModelFilterSet, CreatedUpdatedFilterSet):
     q = django_filters.CharFilter(
         method='search',
         label='Search',
@@ -1129,7 +1129,7 @@ class InventoryItemFilterSet(BaseFilterSet, DeviceComponentFilterSet):
         return queryset.filter(qs_filter)
 
 
-class VirtualChassisFilterSet(BaseFilterSet, CustomFieldModelFilterSet):
+class VirtualChassisFilterSet(BaseFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet):
     q = django_filters.CharFilter(
         method='search',
         label='Search',
@@ -1209,7 +1209,7 @@ class VirtualChassisFilterSet(BaseFilterSet, CustomFieldModelFilterSet):
         return queryset.filter(qs_filter).distinct()
 
 
-class CableFilterSet(BaseFilterSet, CustomFieldModelFilterSet):
+class CableFilterSet(BaseFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet):
     q = django_filters.CharFilter(
         method='search',
         label='Search',
@@ -1340,7 +1340,7 @@ class InterfaceConnectionFilterSet(ConnectionFilterSet, BaseFilterSet):
         fields = []
 
 
-class PowerPanelFilterSet(BaseFilterSet):
+class PowerPanelFilterSet(BaseFilterSet, CustomFieldModelFilterSet, CreatedUpdatedFilterSet):
     q = django_filters.CharFilter(
         method='search',
         label='Search',

+ 24 - 24
netbox/extras/filters.py

@@ -36,6 +36,27 @@ 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(
@@ -119,7 +140,7 @@ class ImageAttachmentFilterSet(BaseFilterSet):
         fields = ['id', 'content_type_id', 'object_id', 'name']
 
 
-class JournalEntryFilterSet(BaseFilterSet):
+class JournalEntryFilterSet(BaseFilterSet, CreatedUpdatedFilterSet):
     q = django_filters.CharFilter(
         method='search',
         label='Search',
@@ -150,7 +171,7 @@ class JournalEntryFilterSet(BaseFilterSet):
         return queryset.filter(comments__icontains=value)
 
 
-class TagFilterSet(BaseFilterSet):
+class TagFilterSet(BaseFilterSet, CreatedUpdatedFilterSet):
     q = django_filters.CharFilter(
         method='search',
         label='Search',
@@ -169,7 +190,7 @@ class TagFilterSet(BaseFilterSet):
         )
 
 
-class ConfigContextFilterSet(BaseFilterSet):
+class ConfigContextFilterSet(BaseFilterSet, CreatedUpdatedFilterSet):
     q = django_filters.CharFilter(
         method='search',
         label='Search',
@@ -341,27 +362,6 @@ class ObjectChangeFilterSet(BaseFilterSet):
         )
 
 
-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'
-    )
-
-
 #
 # Job Results
 #

+ 3 - 3
netbox/ipam/filters.py

@@ -116,7 +116,7 @@ class RouteTargetFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilt
         fields = ['id', 'name']
 
 
-class RIRFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
+class RIRFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet):
 
     class Meta:
         model = RIR
@@ -173,7 +173,7 @@ class AggregateFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilter
             return queryset.none()
 
 
-class RoleFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
+class RoleFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet):
     q = django_filters.CharFilter(
         method='search',
         label='Search',
@@ -535,7 +535,7 @@ class IPAddressFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilter
         return queryset.exclude(assigned_object_id__isnull=value)
 
 
-class VLANGroupFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
+class VLANGroupFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet):
     scope_type = ContentTypeFilter()
     region = django_filters.NumberFilter(
         method='filter_scope'

+ 1 - 1
netbox/secrets/filters.py

@@ -14,7 +14,7 @@ __all__ = (
 )
 
 
-class SecretRoleFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
+class SecretRoleFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet):
 
     class Meta:
         model = SecretRole

+ 1 - 1
netbox/tenancy/filters.py

@@ -13,7 +13,7 @@ __all__ = (
 )
 
 
-class TenantGroupFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
+class TenantGroupFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet):
     parent_id = django_filters.ModelMultipleChoiceFilter(
         queryset=TenantGroup.objects.all(),
         label='Tenant group (ID)',

+ 2 - 2
netbox/virtualization/filters.py

@@ -20,14 +20,14 @@ __all__ = (
 )
 
 
-class ClusterTypeFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
+class ClusterTypeFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet):
 
     class Meta:
         model = ClusterType
         fields = ['id', 'name', 'slug', 'description']
 
 
-class ClusterGroupFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
+class ClusterGroupFilterSet(BaseFilterSet, NameSlugSearchFilterSet, CreatedUpdatedFilterSet):
 
     class Meta:
         model = ClusterGroup