mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-04-27 19:17:01 +00:00
perf: page queryset mixin
This commit is contained in:
parent
11811c453b
commit
36f312b943
@ -1,6 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
from contextlib import nullcontext
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
|
||||||
@ -15,6 +16,7 @@ from common.drf.filters import (
|
|||||||
IDNotFilterBackend, NotOrRelFilterBackend, LabelFilterBackend
|
IDNotFilterBackend, NotOrRelFilterBackend, LabelFilterBackend
|
||||||
)
|
)
|
||||||
from common.utils import get_logger, lazyproperty
|
from common.utils import get_logger, lazyproperty
|
||||||
|
from orgs.utils import tmp_to_org, tmp_to_root_org
|
||||||
from .action import RenderToJsonMixin
|
from .action import RenderToJsonMixin
|
||||||
from .serializer import SerializerMixin
|
from .serializer import SerializerMixin
|
||||||
|
|
||||||
@ -125,25 +127,39 @@ class QuerySetMixin:
|
|||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
def paginate_queryset(self, queryset):
|
def paginate_queryset(self, queryset):
|
||||||
in_root_org = getattr(queryset, 'in_root_org')
|
|
||||||
page = super().paginate_queryset(queryset)
|
page = super().paginate_queryset(queryset)
|
||||||
|
|
||||||
if in_root_org:
|
|
||||||
return page
|
|
||||||
|
|
||||||
model = getattr(queryset, 'model', None)
|
model = getattr(queryset, 'model', None)
|
||||||
if not model or hasattr(queryset, 'custom'):
|
if not model or hasattr(queryset, 'custom'):
|
||||||
return page
|
return page
|
||||||
|
|
||||||
serializer_class = self.get_serializer_class()
|
serializer_class = self.get_serializer_class()
|
||||||
if page and serializer_class:
|
if page and serializer_class:
|
||||||
ids = [str(obj.id) for obj in page]
|
# 必须要返回 ids,用于排序
|
||||||
page = model.objects.filter(id__in=ids)
|
queryset, ids = self._get_page_again(page, model)
|
||||||
page = self.setup_eager_loading(page, is_paginated=True)
|
page = self.setup_eager_loading(queryset, is_paginated=True)
|
||||||
page_mapper = {str(obj.id): obj for obj in page}
|
page_mapper = {str(obj.id): obj for obj in page}
|
||||||
page = [page_mapper.get(_id) for _id in ids if _id in page_mapper]
|
page = [page_mapper.get(_id) for _id in ids if _id in page_mapper]
|
||||||
return page
|
return page
|
||||||
|
|
||||||
|
def _get_page_again(self, page, model):
|
||||||
|
"""
|
||||||
|
因为 setup_eager_loading 需要是 queryset 结构, 所以必须要重新构造
|
||||||
|
"""
|
||||||
|
id_org_mapper = {str(obj.id): getattr(obj, 'org_id', None) for obj in page}
|
||||||
|
ids = list(id_org_mapper.keys())
|
||||||
|
org_ids = list(set(id_org_mapper.values()) - {None})
|
||||||
|
|
||||||
|
if not org_ids:
|
||||||
|
context = nullcontext()
|
||||||
|
elif len(org_ids) == 1:
|
||||||
|
context = tmp_to_org(org_ids[0])
|
||||||
|
else:
|
||||||
|
context = tmp_to_root_org()
|
||||||
|
|
||||||
|
with context:
|
||||||
|
page = model.objects.filter(id__in=ids)
|
||||||
|
return page, ids
|
||||||
|
|
||||||
|
|
||||||
class ExtraFilterFieldsMixin:
|
class ExtraFilterFieldsMixin:
|
||||||
"""
|
"""
|
||||||
|
@ -153,9 +153,6 @@ def filter_org_queryset(queryset):
|
|||||||
# print(line)
|
# print(line)
|
||||||
# print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<")
|
# print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<")
|
||||||
queryset = queryset.filter(**kwargs)
|
queryset = queryset.filter(**kwargs)
|
||||||
|
|
||||||
if org and org.is_root():
|
|
||||||
queryset.in_root_org = True
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user