Merge pull request #9631 from jumpserver/pr@dev@perf_ordering

perf: 优化排序
pull/9632/head^2
老广 2023-02-20 13:41:30 +08:00 committed by GitHub
commit 5058d8158d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 142 additions and 63 deletions

View File

@ -20,7 +20,6 @@ class AccountBackupPlanViewSet(OrgBulkModelViewSet):
model = AccountBackupAutomation
filter_fields = ('name',)
search_fields = filter_fields
ordering_fields = ('name',)
ordering = ('name',)
serializer_class = serializers.AccountBackupSerializer

View File

@ -25,7 +25,6 @@ class ChangeSecretAutomationViewSet(OrgBulkModelViewSet):
model = ChangeSecretAutomation
filter_fields = ('name', 'secret_type', 'secret_strategy')
search_fields = filter_fields
ordering_fields = ('name',)
serializer_class = serializers.ChangeSecretAutomationSerializer

View File

@ -15,7 +15,6 @@ class GatherAccountsAutomationViewSet(OrgBulkModelViewSet):
model = GatherAccountsAutomation
filter_fields = ('name',)
search_fields = filter_fields
ordering_fields = ('name',)
serializer_class = serializers.GatherAccountAutomationSerializer

View File

@ -22,7 +22,6 @@ class PushAccountAutomationViewSet(OrgBulkModelViewSet):
model = PushAccountAutomation
filter_fields = ('name', 'secret_type', 'secret_strategy')
search_fields = filter_fields
ordering_fields = ('name',)
serializer_class = serializers.PushAccountAutomationSerializer

View File

@ -95,7 +95,6 @@ class AssetViewSet(SuggestionMixin, NodeFilterMixin, OrgBulkModelViewSet):
model = Asset
filterset_class = AssetFilterSet
search_fields = ("name", "address")
ordering_fields = ("name", "address", "connectivity")
ordering = ("name", "connectivity")
serializer_classes = (
("default", serializers.AssetSerializer),

View File

@ -3,8 +3,9 @@ from django.utils.translation import ugettext as _
from django.views.generic.detail import SingleObjectMixin
from rest_framework.serializers import ValidationError
from rest_framework.views import APIView, Response
from common.utils import get_logger
from assets.tasks import test_gateways_connectivity_manual
from common.utils import get_logger
from orgs.mixins.api import OrgBulkModelViewSet
from .asset import HostViewSet
from .. import serializers
@ -18,14 +19,12 @@ class DomainViewSet(OrgBulkModelViewSet):
model = Domain
filterset_fields = ("name",)
search_fields = filterset_fields
serializer_class = serializers.DomainSerializer
ordering_fields = ('name',)
ordering = ('name',)
def get_serializer_class(self):
if self.request.query_params.get('gateway'):
return serializers.DomainWithGatewaySerializer
return super().get_serializer_class()
return serializers.DomainSerializer
class GatewayViewSet(HostViewSet):

View File

@ -0,0 +1,38 @@
# Generated by Django 3.2.14 on 2023-02-20 02:51
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('assets', '0109_alter_asset_options'),
]
operations = [
migrations.AddField(
model_name='platform',
name='created_by',
field=models.CharField(blank=True, max_length=128, null=True, verbose_name='Created by'),
),
migrations.AddField(
model_name='platform',
name='date_created',
field=models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date created'),
),
migrations.AddField(
model_name='platform',
name='date_updated',
field=models.DateTimeField(auto_now=True, verbose_name='Date updated'),
),
migrations.AddField(
model_name='platform',
name='updated_by',
field=models.CharField(blank=True, max_length=128, null=True, verbose_name='Updated by'),
),
migrations.AlterField(
model_name='platform',
name='comment',
field=models.TextField(blank=True, default='', verbose_name='Comment'),
),
]

View File

@ -4,6 +4,7 @@ from django.utils.translation import gettext_lazy as _
from assets.const import AllTypes
from assets.const import Protocol
from common.db.fields import JsonDictTextField
from common.db.models import JMSBaseModel
__all__ = ['Platform', 'PlatformProtocol', 'PlatformAutomation']
@ -61,7 +62,7 @@ class PlatformAutomation(models.Model):
)
class Platform(models.Model):
class Platform(JMSBaseModel):
"""
对资产提供 约束和默认值
对资产进行抽象
@ -71,12 +72,12 @@ class Platform(models.Model):
utf8 = 'utf-8', 'UTF-8'
gbk = 'gbk', 'GBK'
id = models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')
name = models.SlugField(verbose_name=_("Name"), unique=True, allow_unicode=True)
category = models.CharField(default='host', max_length=32, verbose_name=_("Category"))
type = models.CharField(max_length=32, default='linux', verbose_name=_("Type"))
meta = JsonDictTextField(blank=True, null=True, verbose_name=_("Meta"))
internal = models.BooleanField(default=False, verbose_name=_("Internal"))
comment = models.TextField(blank=True, null=True, verbose_name=_("Comment"))
# 资产有关的
charset = models.CharField(
default=CharsetChoices.utf8, choices=CharsetChoices.choices, max_length=8, verbose_name=_("Charset")

View File

@ -106,12 +106,13 @@ class PlatformSerializer(WritableNestedModelSerializer):
fields_small = fields_mini + [
"category", "type", "charset",
]
fields = fields_small + [
"protocols",
"domain_enabled", "su_enabled",
"su_method", "automation",
"comment",
fields_other = [
'date_created', 'date_updated', 'created_by', 'updated_by',
]
fields = fields_small + [
"protocols", "domain_enabled", "su_enabled",
"su_method", "automation", "comment",
] + fields_other
extra_kwargs = {
"su_enabled": {"label": _('Su enabled')},
"domain_enabled": {"label": _('Domain enabled')},

View File

@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-
#
import logging
from itertools import chain
from django.db import models
from rest_framework.settings import api_settings
from common.drf.filters import IDSpmFilter, CustomFilter, IDInFilter
__all__ = ['ExtraFilterFieldsMixin']
__all__ = ['ExtraFilterFieldsMixin', 'OrderingFielderFieldsMixin']
class ExtraFilterFieldsMixin:
@ -33,3 +34,55 @@ class ExtraFilterFieldsMixin:
for backend in self.get_filter_backends():
queryset = backend().filter_queryset(self.request, queryset, self)
return queryset
class OrderingFielderFieldsMixin:
"""
额外的 api ordering
"""
ordering_fields = None
extra_ordering_fields = []
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.ordering_fields = self._get_ordering_fields()
def _get_ordering_fields(self):
if isinstance(self.__class__.ordering_fields, (list, tuple)):
return self.__class__.ordering_fields
try:
valid_fields = self.get_valid_ordering_fields()
except Exception as e:
logging.debug('get_valid_ordering_fields error: %s' % e)
valid_fields = []
fields = list(chain(
valid_fields,
self.extra_ordering_fields
))
return fields
def get_valid_ordering_fields(self):
if getattr(self, 'model', None):
model = self.model
elif getattr(self, 'queryset', None):
model = self.queryset.model
else:
queryset = self.get_queryset()
model = queryset.model
if not model:
return []
excludes_fields = (
models.UUIDField, models.Model, models.ForeignKey,
models.FileField, models.JSONField, models.ManyToManyField,
models.DurationField,
)
valid_fields = []
for field in model._meta.fields:
if isinstance(field, excludes_fields):
continue
valid_fields.append(field.name)
return valid_fields

View File

@ -7,7 +7,7 @@ from django.db.models.signals import m2m_changed
from rest_framework.response import Response
from .action import RenderToJsonMixin
from .filter import ExtraFilterFieldsMixin
from .filter import ExtraFilterFieldsMixin, OrderingFielderFieldsMixin
from .serializer import SerializerMixin
__all__ = [
@ -98,7 +98,6 @@ class QuerySetMixin:
return queryset
class CommonApiMixin(SerializerMixin, ExtraFilterFieldsMixin,
QuerySetMixin, RenderToJsonMixin,
PaginatedResponseMixin):
class CommonApiMixin(SerializerMixin, ExtraFilterFieldsMixin, OrderingFielderFieldsMixin,
QuerySetMixin, RenderToJsonMixin, PaginatedResponseMixin):
pass

View File

@ -1,18 +1,20 @@
# -*- coding: utf-8 -*-
#
from rest_framework import filters
from rest_framework.fields import DateTimeField
from rest_framework.serializers import ValidationError
from rest_framework.compat import coreapi, coreschema
import logging
from django.core.cache import cache
from django.core.exceptions import ImproperlyConfigured
from django_filters import rest_framework as drf_filters
import logging
from rest_framework import filters
from rest_framework.compat import coreapi, coreschema
from rest_framework.fields import DateTimeField
from rest_framework.serializers import ValidationError
from common import const
__all__ = [
"DatetimeRangeFilter", "IDSpmFilter", 'IDInFilter', "CustomFilter",
"DatetimeRangeFilter", "IDSpmFilter",
'IDInFilter', "CustomFilter",
"BaseFilterSet"
]

View File

@ -1,9 +1,9 @@
# ~*~ coding: utf-8 ~*~
from __future__ import unicode_literals
from rest_framework import serializers
from django.utils.translation import gettext_lazy as _
from django.utils.translation import gettext_lazy as _
from django_celery_beat.models import PeriodicTask
from rest_framework import serializers
__all__ = [
'CeleryResultSerializer', 'CeleryTaskExecutionSerializer',
@ -41,7 +41,7 @@ class CeleryTaskExecutionSerializer(serializers.ModelSerializer):
class Meta:
model = CeleryTaskExecution
fields = [
"id", "name", "args", "kwargs", "time_cost", "timedelta", "is_success", "is_finished", "date_published",
"date_start",
"date_finished"
"id", "name", "args", "kwargs", "time_cost", "timedelta",
"is_success", "is_finished", "date_published",
"date_start", "date_finished"
]

View File

@ -1,20 +1,20 @@
# -*- coding: utf-8 -*-
#
from django.utils.translation import ugettext as _
from django.conf import settings
from rest_framework_bulk import BulkModelViewSet
from rest_framework.generics import RetrieveAPIView
from django.utils.translation import ugettext as _
from rest_framework.exceptions import PermissionDenied
from rest_framework.generics import RetrieveAPIView
from common.utils import get_logger
from common.permissions import IsValidUser
from users.models import User, UserGroup
from assets.models import (
Asset, Domain, Label, Node,
)
from perms.models import AssetPermission
from common.api import JMSBulkModelViewSet
from common.permissions import IsValidUser
from common.utils import get_logger
from orgs.utils import current_org, tmp_to_root_org
from perms.models import AssetPermission
from users.models import User, UserGroup
from .models import Organization
from .serializers import (
OrgSerializer, CurrentOrgSerializer
@ -29,12 +29,11 @@ org_related_models = [
]
class OrgViewSet(BulkModelViewSet):
class OrgViewSet(JMSBulkModelViewSet):
filterset_fields = ('name',)
search_fields = ('name', 'comment')
queryset = Organization.objects.all()
serializer_class = OrgSerializer
ordering_fields = ('name',)
ordering = ('name',)
def get_serializer_class(self):

View File

@ -16,5 +16,4 @@ class AssetPermissionViewSet(OrgBulkModelViewSet):
serializer_class = serializers.AssetPermissionSerializer
filterset_class = AssetPermissionFilter
search_fields = ('name',)
ordering_fields = ('name',)
ordering = ('name',)

View File

@ -1,19 +1,18 @@
import abc
from rest_framework.generics import ListAPIView
from assets.models import Asset, Node
from assets.api.asset.asset import AssetFilterSet
from assets.models import Asset, Node
from common.utils import get_logger, lazyproperty
from perms import serializers
from perms.pagination import AllPermedAssetPagination
from perms.pagination import NodePermedAssetPagination
from perms.utils import UserPermAssetUtil
from common.utils import get_logger, lazyproperty
from .mixin import (
SelfOrPKUserMixin
)
__all__ = [
'UserAllPermedAssetsApi',
'UserDirectPermedAssetsApi',
@ -26,8 +25,8 @@ logger = get_logger(__name__)
class BaseUserPermedAssetsApi(SelfOrPKUserMixin, ListAPIView):
ordering = ('name',)
ordering_fields = ("name", "address")
search_fields = ('name', 'address', 'comment')
ordering_fields = ("name", "address")
filterset_class = AssetFilterSet
serializer_class = serializers.AssetPermedSerializer
only_fields = serializers.AssetPermedSerializer.Meta.only_fields

View File

@ -1,22 +1,23 @@
# -*- coding: utf-8 -*-
#
import logging
from rest_framework.views import APIView, Response
from rest_framework_bulk import BulkModelViewSet
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView, Response
from common.api import JMSBulkModelViewSet
from common.utils import get_object_or_none
from orgs.utils import tmp_to_root_org
from terminal.models import Session, Task
from terminal import serializers
from terminal.models import Session, Task
from terminal.utils import is_session_approver
__all__ = ['TaskViewSet', 'KillSessionAPI', 'KillSessionForTicketAPI']
logger = logging.getLogger(__file__)
class TaskViewSet(BulkModelViewSet):
class TaskViewSet(JMSBulkModelViewSet):
queryset = Task.objects.all()
serializer_class = serializers.TaskSerializer
filterset_fields = ('is_finished',)
@ -51,7 +52,7 @@ class KillSessionAPI(APIView):
class KillSessionForTicketAPI(APIView):
permission_classes = (IsAuthenticated, )
permission_classes = (IsAuthenticated,)
def post(self, request, *args, **kwargs):
session_ids = request.data

View File

@ -35,10 +35,6 @@ class TicketViewSet(CommonApiMixin, viewsets.ModelViewSet):
search_fields = [
'title', 'type', 'status'
]
ordering_fields = (
'title', 'status', 'state', 'action_display',
'date_created', 'serial_num',
)
ordering = ('-date_created',)
rbac_perms = {
'open': 'tickets.view_ticket',

View File

@ -1,10 +1,9 @@
# -*- coding: utf-8 -*-
#
from ..serializers import UserGroupSerializer
from ..models import UserGroup
from orgs.mixins.api import OrgBulkModelViewSet
from ..models import UserGroup
from ..serializers import UserGroupSerializer
__all__ = ['UserGroupViewSet']
@ -14,5 +13,4 @@ class UserGroupViewSet(OrgBulkModelViewSet):
filterset_fields = ("name",)
search_fields = filterset_fields
serializer_class = UserGroupSerializer
ordering_fields = ('name', )
ordering = ('name', )
ordering = ('name',)

View File

@ -39,7 +39,6 @@ class UserViewSet(CommonApiMixin, UserQuerysetMixin, SuggestionMixin, BulkModelV
'suggestion': MiniUserSerializer,
'invite': InviteSerializer,
}
ordering_fields = ('name',)
ordering = ('name',)
rbac_perms = {
'match': 'users.match_user',