From 5921b2ee8f0d87b22ea05d624b920913978863c4 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 18 Apr 2023 16:29:41 +0800 Subject: [PATCH 1/2] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E8=8A=82=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/accounts/serializers/account/account.py | 2 +- apps/assets/serializers/asset/common.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/accounts/serializers/account/account.py b/apps/accounts/serializers/account/account.py index 9ebbeda51..4dd6bf041 100644 --- a/apps/accounts/serializers/account/account.py +++ b/apps/accounts/serializers/account/account.py @@ -59,7 +59,7 @@ class AccountCreateUpdateSerializerMixin(serializers.Serializer): def set_uniq_name_if_need(self, initial_data, asset): name = initial_data.get('name') - if name is None: + if name is not None: return if not name: name = initial_data.get('username') diff --git a/apps/assets/serializers/asset/common.py b/apps/assets/serializers/asset/common.py index 15958f17a..568450ec4 100644 --- a/apps/assets/serializers/asset/common.py +++ b/apps/assets/serializers/asset/common.py @@ -267,12 +267,13 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali nodes_display = self.initial_data.get('nodes_display') if nodes_display: return nodes + default_node = Node.org_root() request = self.context.get('request') if not request: - return [] + return [default_node] node_id = request.query_params.get('node_id') if not node_id: - return [] + return [default_node] nodes = Node.objects.filter(id=node_id) return nodes From 8b98bbddaa5b57ac3f795ca5e1384668f3a8dba3 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 18 Apr 2023 17:07:01 +0800 Subject: [PATCH 2/2] =?UTF-8?q?perf:=20custom=20fields=20=E4=BB=85custom?= =?UTF-8?q?=20=E7=B1=BB=E5=9E=8B=E8=B5=84=E4=BA=A7=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/serializers/asset/common.py | 51 +++++-------------------- apps/assets/serializers/asset/custom.py | 41 +++++++++++++++++++- apps/common/const/common.py | 3 ++ apps/common/serializers/common.py | 8 +++- apps/common/serializers/fields.py | 2 +- 5 files changed, 60 insertions(+), 45 deletions(-) diff --git a/apps/assets/serializers/asset/common.py b/apps/assets/serializers/asset/common.py index 568450ec4..db248e5ef 100644 --- a/apps/assets/serializers/asset/common.py +++ b/apps/assets/serializers/asset/common.py @@ -1,18 +1,18 @@ # -*- coding: utf-8 -*- # -import re - -from django.db.models import F, QuerySet +from django.db.models import F from django.db.transaction import atomic from django.utils.translation import ugettext_lazy as _ from rest_framework import serializers from accounts.models import Account from accounts.serializers import AccountSerializer -from common.serializers import WritableNestedModelSerializer, SecretReadableMixin, CommonModelSerializer, \ - MethodSerializer -from common.serializers.dynamic import create_serializer_class +from common.const import UUID_PATTERN +from common.serializers import ( + WritableNestedModelSerializer, SecretReadableMixin, + CommonModelSerializer, MethodSerializer +) from common.serializers.fields import LabeledChoiceField from orgs.mixins.serializers import BulkOrgResourceModelSerializer from ...const import Category, AllTypes @@ -25,8 +25,6 @@ __all__ = [ 'AccountSecretSerializer', 'AssetProtocolsPermsSerializer' ] -uuid_pattern = re.compile(r'[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}') - class AssetProtocolsSerializer(serializers.ModelSerializer): port = serializers.IntegerField(required=False, allow_null=True, max_value=65535, min_value=1) @@ -121,12 +119,11 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali protocols = AssetProtocolsSerializer(many=True, required=False, label=_('Protocols'), default=()) accounts = AssetAccountSerializer(many=True, required=False, allow_null=True, write_only=True, label=_('Account')) nodes_display = serializers.ListField(read_only=False, required=False, label=_("Node path")) - custom_info = MethodSerializer(label=_('Custom info')) class Meta: model = Asset fields_mini = ['id', 'name', 'address'] - fields_small = fields_mini + ['custom_info', 'is_active', 'comment'] + fields_small = fields_mini + ['is_active', 'comment'] fields_fk = ['domain', 'platform'] fields_m2m = [ 'nodes', 'labels', 'protocols', @@ -193,36 +190,6 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali .annotate(type=F("platform__type")) return queryset - def get_custom_info_serializer(self): - request = self.context.get('request') - default_field = serializers.DictField(required=False, label=_('Custom info')) - - if not request: - return default_field - - if self.instance and isinstance(self.instance, (QuerySet, list)): - return default_field - - if not self.instance and uuid_pattern.findall(request.path): - pk = uuid_pattern.findall(request.path)[0] - self.instance = Asset.objects.filter(id=pk).first() - - platform = None - if self.instance: - platform = self.instance.platform - elif request.query_params.get('platform'): - platform_id = request.query_params.get('platform') - platform_id = int(platform_id) if platform_id.isdigit() else 0 - platform = Platform.objects.filter(id=platform_id).first() - - if not platform: - return default_field - custom_fields = platform.custom_fields - if not custom_fields: - return default_field - name = platform.name.title() + 'CustomSerializer' - return create_serializer_class(name, custom_fields)() - @staticmethod def perform_nodes_display_create(instance, nodes_display): if not nodes_display: @@ -336,8 +303,8 @@ class DetailMixin(serializers.Serializer): def get_instance(self): request = self.context.get('request') - if not self.instance and uuid_pattern.findall(request.path): - pk = uuid_pattern.findall(request.path)[0] + if not self.instance and UUID_PATTERN.findall(request.path): + pk = UUID_PATTERN.findall(request.path)[0] self.instance = Asset.objects.filter(id=pk).first() return self.instance diff --git a/apps/assets/serializers/asset/custom.py b/apps/assets/serializers/asset/custom.py index d88024218..5e5cd774c 100644 --- a/apps/assets/serializers/asset/custom.py +++ b/apps/assets/serializers/asset/custom.py @@ -1,9 +1,48 @@ -from assets.models import Custom +from django.db.models import QuerySet +from django.utils.translation import gettext_lazy as _ +from rest_framework import serializers + +from assets.models import Custom, Platform, Asset +from common.const import UUID_PATTERN +from common.serializers import MethodSerializer, create_serializer_class from .common import AssetSerializer __all__ = ['CustomSerializer'] class CustomSerializer(AssetSerializer): + custom_info = MethodSerializer(label=_('Custom info')) + class Meta(AssetSerializer.Meta): model = Custom + fields = AssetSerializer.Meta.fields + ['custom_info'] + + def get_custom_info_serializer(self): + request = self.context.get('request') + default_field = serializers.DictField(required=False, label=_('Custom info')) + + if not request: + return default_field + + if self.instance and isinstance(self.instance, (QuerySet, list)): + return default_field + + if not self.instance and UUID_PATTERN.findall(request.path): + pk = UUID_PATTERN.findall(request.path)[0] + self.instance = Asset.objects.filter(id=pk).first() + + platform = None + if self.instance: + platform = self.instance.platform + elif request.query_params.get('platform'): + platform_id = request.query_params.get('platform') + platform_id = int(platform_id) if platform_id.isdigit() else 0 + platform = Platform.objects.filter(id=platform_id).first() + + if not platform: + return default_field + custom_fields = platform.custom_fields + if not custom_fields: + return default_field + name = platform.name.title() + 'CustomSerializer' + return create_serializer_class(name, custom_fields)() diff --git a/apps/common/const/common.py b/apps/common/const/common.py index 86ae030d9..33a889ecb 100644 --- a/apps/common/const/common.py +++ b/apps/common/const/common.py @@ -1,3 +1,5 @@ +import re + from django.utils.translation import ugettext_lazy as _ create_success_msg = _("%(name)s was created successfully") @@ -9,3 +11,4 @@ KEY_CACHE_RESOURCE_IDS = "RESOURCE_IDS_{}" # AD User AccountDisable # https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/useraccountcontrol-manipulate-account-properties LDAP_AD_ACCOUNT_DISABLE = 2 +UUID_PATTERN = re.compile(r'[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}') diff --git a/apps/common/serializers/common.py b/apps/common/serializers/common.py index 1515fe911..208023ac4 100644 --- a/apps/common/serializers/common.py +++ b/apps/common/serializers/common.py @@ -1,3 +1,5 @@ +import logging + from django.utils.functional import cached_property from django.utils.translation import gettext_lazy as _ from drf_writable_nested.serializers import WritableNestedModelSerializer as NestedModelSerializer @@ -35,7 +37,11 @@ class MethodSerializer(serializers.Serializer): @cached_property def serializer(self) -> serializers.Serializer: method = getattr(self.parent, self.method_name) - _serializer = method() + try: + _serializer = method() + except Exception as e: + logging.error(e, exc_info=True) + raise e # 设置serializer的parent值,否则在serializer实例中获取parent会出现断层 setattr(_serializer, 'parent', self.parent) return _serializer diff --git a/apps/common/serializers/fields.py b/apps/common/serializers/fields.py index 514a96fd0..e8a350023 100644 --- a/apps/common/serializers/fields.py +++ b/apps/common/serializers/fields.py @@ -63,7 +63,7 @@ class LabeledChoiceField(ChoiceField): def to_representation(self, key): if key is None: return key - label = self.choice_mapper.get(key) + label = self.choice_mapper.get(key, key) return {"value": key, "label": label} def to_internal_value(self, data):