1
0
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:
Jeremy Stretch
2022-06-17 13:44:37 -04:00
committed by GitHub
2 changed files with 19 additions and 1 deletions

View File

@ -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):
""" """

View File

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