mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Merge pull request #9527 from kkthxbye-code/fix-9374
Partially fixes #9374 - Implement a custom paginator for DeviceViewSet to improve config_context load times
This commit is contained in:
@ -19,6 +19,7 @@ from ipam.models import Prefix, VLAN
|
|||||||
from netbox.api.authentication import IsAuthenticatedOrLoginNotRequired
|
from netbox.api.authentication import IsAuthenticatedOrLoginNotRequired
|
||||||
from netbox.api.exceptions import ServiceUnavailable
|
from netbox.api.exceptions import ServiceUnavailable
|
||||||
from netbox.api.metadata import ContentTypeMetadata
|
from netbox.api.metadata import ContentTypeMetadata
|
||||||
|
from netbox.api.pagination import StripCountAnnotationsPaginator
|
||||||
from netbox.api.viewsets import NetBoxModelViewSet
|
from netbox.api.viewsets import NetBoxModelViewSet
|
||||||
from netbox.config import get_config
|
from netbox.config import get_config
|
||||||
from utilities.api import get_serializer_for_model
|
from utilities.api import get_serializer_for_model
|
||||||
@ -392,6 +393,7 @@ class DeviceViewSet(ConfigContextQuerySetMixin, NetBoxModelViewSet):
|
|||||||
'virtual_chassis__master', 'primary_ip4__nat_outside', 'primary_ip6__nat_outside', 'tags',
|
'virtual_chassis__master', 'primary_ip4__nat_outside', 'primary_ip6__nat_outside', 'tags',
|
||||||
)
|
)
|
||||||
filterset_class = filtersets.DeviceFilterSet
|
filterset_class = filtersets.DeviceFilterSet
|
||||||
|
pagination_class = StripCountAnnotationsPaginator
|
||||||
|
|
||||||
def get_serializer_class(self):
|
def get_serializer_class(self):
|
||||||
"""
|
"""
|
||||||
|
@ -16,7 +16,7 @@ class OptionalLimitOffsetPagination(LimitOffsetPagination):
|
|||||||
def paginate_queryset(self, queryset, request, view=None):
|
def paginate_queryset(self, queryset, request, view=None):
|
||||||
|
|
||||||
if isinstance(queryset, QuerySet):
|
if isinstance(queryset, QuerySet):
|
||||||
self.count = queryset.count()
|
self.count = self.get_queryset_count(queryset)
|
||||||
else:
|
else:
|
||||||
# We're dealing with an iterable, not a QuerySet
|
# We're dealing with an iterable, not a QuerySet
|
||||||
self.count = len(queryset)
|
self.count = len(queryset)
|
||||||
@ -52,6 +52,9 @@ class OptionalLimitOffsetPagination(LimitOffsetPagination):
|
|||||||
|
|
||||||
return self.default_limit
|
return self.default_limit
|
||||||
|
|
||||||
|
def get_queryset_count(self, queryset):
|
||||||
|
return queryset.count()
|
||||||
|
|
||||||
def get_next_link(self):
|
def get_next_link(self):
|
||||||
|
|
||||||
# Pagination has been disabled
|
# Pagination has been disabled
|
||||||
@ -67,3 +70,16 @@ class OptionalLimitOffsetPagination(LimitOffsetPagination):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
return super().get_previous_link()
|
return super().get_previous_link()
|
||||||
|
|
||||||
|
|
||||||
|
class StripCountAnnotationsPaginator(OptionalLimitOffsetPagination):
|
||||||
|
"""
|
||||||
|
Strips the annotations on the queryset before getting the count
|
||||||
|
to optimize pagination of complex queries.
|
||||||
|
"""
|
||||||
|
def get_queryset_count(self, queryset):
|
||||||
|
# Clone the queryset to avoid messing up the actual query
|
||||||
|
cloned_queryset = queryset.all()
|
||||||
|
cloned_queryset.query.annotations.clear()
|
||||||
|
|
||||||
|
return cloned_queryset.count()
|
||||||
|
Reference in New Issue
Block a user