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

This commit is contained in:
jeremystretch 2021-04-27 10:04:28 -04:00
parent 9a588231c5
commit 58659cf3b6
8 changed files with 48 additions and 47 deletions

View File

@ -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

View File

@ -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',

View File

@ -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',

View File

@ -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
#

View File

@ -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'

View File

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

View File

@ -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)',

View File

@ -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