From 9634f397dfa63a476fd303a5ec13e47c7dfbbe68 Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 23 Aug 2023 15:47:22 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=B8=8D=E5=85=81=E8=AE=B8=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E8=87=AA=E5=B7=B1=E7=9A=84=E8=A7=92=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/api/filter.py | 4 ++-- apps/common/drf/filters.py | 24 +++++++++++++++++++++--- apps/users/api/relation.py | 2 +- apps/users/serializers/realtion.py | 7 ++++--- apps/users/serializers/user.py | 11 ++++++----- 5 files changed, 34 insertions(+), 14 deletions(-) diff --git a/apps/common/api/filter.py b/apps/common/api/filter.py index 56c3e6483..82c0dfca0 100644 --- a/apps/common/api/filter.py +++ b/apps/common/api/filter.py @@ -6,7 +6,7 @@ from itertools import chain from django.db import models from rest_framework.settings import api_settings -from common.drf.filters import IDSpmFilter, CustomFilter, IDInFilter +from common.drf.filters import IDSpmFilter, CustomFilter, IDInFilter, IDNotFilter __all__ = ['ExtraFilterFieldsMixin', 'OrderingFielderFieldsMixin'] @@ -17,7 +17,7 @@ class ExtraFilterFieldsMixin: """ 额外的 api filter """ - default_added_filters = [CustomFilter, IDSpmFilter, IDInFilter] + default_added_filters = [CustomFilter, IDSpmFilter, IDInFilter, IDNotFilter] filter_backends = api_settings.DEFAULT_FILTER_BACKENDS extra_filter_fields = [] extra_filter_backends = [] diff --git a/apps/common/drf/filters.py b/apps/common/drf/filters.py index c44874fd5..e99b9b4d1 100644 --- a/apps/common/drf/filters.py +++ b/apps/common/drf/filters.py @@ -13,17 +13,16 @@ from rest_framework.fields import DateTimeField from rest_framework.serializers import ValidationError from common import const +from common.db.fields import RelatedManager logger = logging.getLogger('jumpserver.common') __all__ = [ "DatetimeRangeFilter", "IDSpmFilter", 'IDInFilter', "CustomFilter", - "BaseFilterSet" + "BaseFilterSet", 'IDNotFilter' ] -from common.db.fields import RelatedManager - class BaseFilterSet(drf_filters.FilterSet): def do_nothing(self, queryset, name, value): @@ -149,6 +148,25 @@ class IDInFilter(filters.BaseFilterBackend): return queryset +class IDNotFilter(filters.BaseFilterBackend): + def get_schema_fields(self, view): + return [ + coreapi.Field( + name='id!', location='query', required=False, + type='string', example='/api/v1/users/users?id!=1,2,3', + description='Exclude by id set' + ) + ] + + def filter_queryset(self, request, queryset, view): + ids = request.query_params.get('id!') + if not ids: + return queryset + id_list = [i.strip() for i in ids.split(',')] + queryset = queryset.exclude(id__in=id_list) + return queryset + + class CustomFilter(filters.BaseFilterBackend): def get_schema_fields(self, view): diff --git a/apps/users/api/relation.py b/apps/users/api/relation.py index 5af72633c..4fbf29cc5 100644 --- a/apps/users/api/relation.py +++ b/apps/users/api/relation.py @@ -14,7 +14,7 @@ class UserUserGroupRelationViewSet(JMSBulkRelationModelViewSet): perm_model = UserGroup filterset_fields = ('user', 'usergroup') search_fields = filterset_fields - serializer_class = serializers.UserUserGroupRelationSerializer + serializer_class = serializers.User2GroupRelationSerializer m2m_field = User.groups.field def get_queryset(self): diff --git a/apps/users/serializers/realtion.py b/apps/users/serializers/realtion.py index b768c57fc..3e26eb7c7 100644 --- a/apps/users/serializers/realtion.py +++ b/apps/users/serializers/realtion.py @@ -4,15 +4,16 @@ from rest_framework import serializers from ..models import User -__all__ = ['UserUserGroupRelationSerializer'] +__all__ = ['User2GroupRelationSerializer'] -class UserUserGroupRelationSerializer(serializers.ModelSerializer): +class User2GroupRelationSerializer(serializers.ModelSerializer): user_display = serializers.CharField(read_only=True) usergroup_display = serializers.CharField(read_only=True) class Meta: model = User.groups.through fields = [ - 'id', 'user', 'user_display', 'usergroup', 'usergroup_display' + 'id', 'user', 'user_display', + 'usergroup', 'usergroup_display' ] diff --git a/apps/users/serializers/user.py b/apps/users/serializers/user.py index ea7568622..82ce8f0da 100644 --- a/apps/users/serializers/user.py +++ b/apps/users/serializers/user.py @@ -56,15 +56,16 @@ class RolesSerializerMixin(serializers.Serializer): if request.user.is_anonymous: return fields - action = view.action or "list" - if action in ("partial_bulk_update", "bulk_update", "partial_update", "update"): - action = "create" - model_cls_field_mapper = { SystemRoleBinding: ["system_roles"], OrgRoleBinding: ["org_roles"], } + update_actions = ("partial_bulk_update", "bulk_update", "partial_update", "update") + action = view.action or "list" + if action in update_actions: + action = "create" + for model_cls, fields_names in model_cls_field_mapper.items(): perms = RBACPermission.parse_action_model_perms(action, model_cls) if request.user.has_perms(perms): @@ -156,7 +157,7 @@ class UserSerializer(RolesSerializerMixin, CommonBulkSerializerMixin, serializer "is_first_login", "wecom_id", "dingtalk_id", "feishu_id", ] - disallow_self_update_fields = ["is_active"] + disallow_self_update_fields = ["is_active", "system_roles", "org_roles"] extra_kwargs = { "password": { "write_only": True,