perf: 修改 display field

pull/9169/head
ibuler 2022-12-07 18:58:57 +08:00
parent 6a1c5aba12
commit 0c7de50708
11 changed files with 89 additions and 220 deletions

View File

@ -4,6 +4,7 @@
from django.db import models
from django.utils.translation import ugettext_lazy as _
from common.utils import lazyproperty
from orgs.mixins.models import JMSOrgBaseModel
@ -27,6 +28,10 @@ class Label(JMSOrgBaseModel):
for name in names:
yield name, cls.objects.filter(name=name)
@lazyproperty
def asset_count(self):
return self.assets.count()
def __str__(self):
return "{}:{}".format(self.name, self.value)

View File

@ -1,25 +1,22 @@
# -*- coding: utf-8 -*-
#
from rest_framework import serializers
from django.db.models import Count
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from ..models import Label
class LabelSerializer(BulkOrgResourceModelSerializer):
asset_count = serializers.SerializerMethodField(label=_("Assets amount"))
category_display = serializers.ReadOnlyField(source='get_category_display', label=_('Category display'))
asset_count = serializers.ReadOnlyField(label=_("Assets amount"))
class Meta:
model = Label
fields_mini = ['id', 'name']
fields_small = fields_mini + [
'value', 'category', 'category_display',
'is_active',
'date_created',
'comment',
'value', 'category', 'is_active',
'date_created', 'comment',
]
fields_m2m = ['asset_count', 'assets']
fields = fields_small + fields_m2m
@ -30,14 +27,10 @@ class LabelSerializer(BulkOrgResourceModelSerializer):
'assets': {'required': False, 'label': _('Asset')}
}
@staticmethod
def get_asset_count(obj):
return obj.assets.count()
def get_field_names(self, declared_fields, info):
fields = super().get_field_names(declared_fields, info)
fields.extend(['get_category_display'])
return fields
@classmethod
def setup_eager_loading(cls, queryset):
queryset = queryset.annotate(asset_count=Count('assets'))
return queryset
class LabelDistinctSerializer(BulkOrgResourceModelSerializer):

View File

@ -42,20 +42,13 @@ class PlatformAutomationSerializer(serializers.ModelSerializer):
model = PlatformAutomation
fields = [
"id",
"ansible_enabled",
"ansible_config",
"ping_enabled",
"ping_method",
"gather_facts_enabled",
"gather_facts_method",
"push_account_enabled",
"push_account_method",
"change_secret_enabled",
"change_secret_method",
"verify_account_enabled",
"verify_account_method",
"gather_accounts_enabled",
"gather_accounts_method",
"ansible_enabled", "ansible_config",
"ping_enabled", "ping_method",
"gather_facts_enabled", "gather_facts_method",
"push_account_enabled", "push_account_method",
"change_secret_enabled", "change_secret_method",
"verify_account_enabled", "verify_account_method",
"gather_accounts_enabled", "gather_accounts_method",
]
extra_kwargs = {
"ping_enabled": {"label": "启用资产探测"},
@ -80,13 +73,8 @@ class PlatformProtocolsSerializer(serializers.ModelSerializer):
class Meta:
model = PlatformProtocol
fields = [
"id",
"name",
"port",
"primary",
"default",
"required",
"secret_types",
"id", "name", "port", "primary",
"default", "required", "secret_types",
"setting",
]
@ -112,17 +100,12 @@ class PlatformSerializer(WritableNestedModelSerializer):
model = Platform
fields_mini = ["id", "name", "internal"]
fields_small = fields_mini + [
"category",
"type",
"charset",
"category", "type", "charset",
]
fields = fields_small + [
"protocols_enabled",
"protocols",
"domain_enabled",
"su_enabled",
"su_method",
"automation",
"protocols_enabled", "protocols",
"domain_enabled", "su_enabled",
"su_method", "automation",
"comment",
]
extra_kwargs = {

View File

@ -44,18 +44,11 @@ class UserLoginLogSerializer(serializers.ModelSerializer):
model = models.UserLoginLog
fields_mini = ["id"]
fields_small = fields_mini + [
"username",
"type",
"ip",
"city",
"user_agent",
"mfa",
"reason",
"reason_display",
"backend",
"backend_display",
"status",
"datetime",
"username", "type", "ip",
"city", "user_agent", "mfa",
"reason", "reason_display",
"backend", "backend_display",
"status", "datetime",
]
fields = fields_small
extra_kwargs = {
@ -78,14 +71,9 @@ class OperateLogSerializer(serializers.ModelSerializer):
model = models.OperateLog
fields_mini = ["id"]
fields_small = fields_mini + [
"user",
"action",
"resource_type",
"resource_type_display",
"resource",
"remote_addr",
"datetime",
"org_id",
"user", "action", "resource_type",
"resource_type_display", "resource",
"remote_addr", "datetime", "org_id",
]
fields = fields_small
extra_kwargs = {"resource_type_display": {"label": _("Resource Type")}}
@ -101,44 +89,3 @@ class SessionAuditSerializer(serializers.ModelSerializer):
class Meta:
model = Session
fields = "__all__"
#
# class CommandExecutionSerializer(serializers.ModelSerializer):
# is_success = serializers.BooleanField(read_only=True, label=_('Is success'))
# hosts_display = serializers.ListSerializer(
# child=serializers.CharField(), source='hosts', read_only=True, label=_('Hosts display')
# )
#
# class Meta:
# model = CommandExecution
# fields_mini = ['id']
# fields_small = fields_mini + [
# 'command', 'is_finished', 'user',
# 'date_start', 'result', 'is_success', 'org_id'
# ]
# fields = fields_small + ['hosts', 'hosts_display', 'user_display']
# extra_kwargs = {
# 'result': {'label': _('Result')}, # model 上的方法,只能在这修改
# 'is_success': {'label': _('Is success')},
# 'hosts': {'label': _('Hosts')}, # 外键,会生成 sql。不在 model 上修改
# 'user': {'label': _('User')},
# 'user_display': {'label': _('User display')},
# }
#
# @classmethod
# def setup_eager_loading(cls, queryset):
# """ Perform necessary eager loading of data. """
# queryset = queryset.prefetch_related('user', 'hosts')
# return queryset
#
#
# class CommandExecutionHostsRelationSerializer(BulkSerializerMixin, serializers.ModelSerializer):
# asset_display = serializers.ReadOnlyField()
# commandexecution_display = serializers.ReadOnlyField()
#
# class Meta:
# model = CommandExecution.hosts.through
# fields = [
# 'id', 'asset', 'asset_display', 'commandexecution', 'commandexecution_display'
# ]

View File

@ -1,16 +1,15 @@
from collections import Iterable
from django.db.models import NOT_PROVIDED
from django.core.exceptions import ObjectDoesNotExist
from rest_framework.utils import html
from django.db.models import NOT_PROVIDED
from rest_framework import serializers
from rest_framework.settings import api_settings
from rest_framework.exceptions import ValidationError
from rest_framework.fields import SkipField, empty
from rest_framework.settings import api_settings
from rest_framework.utils import html
from common.drf.fields import EncryptedField
from common.utils import lazyproperty
from ..fields import LabeledChoiceField, ObjectRelatedField
__all__ = [
'BulkSerializerMixin', 'BulkListSerializerMixin',
@ -43,6 +42,7 @@ class BulkSerializerMixin(object):
Become rest_framework_bulk not support uuid as a primary key
so rewrite it. https://github.com/miki725/django-rest-framework-bulk/issues/66
"""
def to_internal_value(self, data):
from rest_framework_bulk import BulkListSerializer
ret = super(BulkSerializerMixin, self).to_internal_value(data)
@ -308,7 +308,12 @@ class DynamicFieldsMixin:
self.fields.pop(field, None)
class CommonSerializerMixin(DynamicFieldsMixin, DefaultValueFieldsMixin):
class RelatedModelSerializerMixin:
serializer_related_field = ObjectRelatedField
serializer_choice_field = LabeledChoiceField
class SomeFieldsMixin:
instance: None
initial_data: dict
common_fields = (
@ -342,5 +347,10 @@ class CommonSerializerMixin(DynamicFieldsMixin, DefaultValueFieldsMixin):
return primary_names + common_names
class CommonSerializerMixin(DynamicFieldsMixin, RelatedModelSerializerMixin,
SomeFieldsMixin, DefaultValueFieldsMixin):
pass
class CommonBulkSerializerMixin(BulkSerializerMixin, CommonSerializerMixin):
pass

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:03b1fcb75dae7e070f662f2ad554774d51311d2561367f5d28addc3b14899195
size 119767
oid sha256:5c366d6b10c4ce62bd8ed7c69ecaec5533f1a178b3cc7db4e6008769a6c8bb1f
size 119897

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6bd3c45b4301a45fa1b110716b3ea78bcbb53a2913f707ab754882df061256cc
size 98368
oid sha256:9f0b10566b4d35accd3a8766b14d6903243d93c5d7c55b208d930a189e590f2f
size 106125

View File

@ -1,6 +1,7 @@
from rest_framework import serializers
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
from common.drf.fields import LabeledChoiceField
from users.models import User
from ..models import Role
@ -8,13 +9,13 @@ __all__ = ['RoleSerializer', 'RoleUserSerializer']
class RoleSerializer(serializers.ModelSerializer):
scope_display = serializers.ReadOnlyField(source='get_scope_display', label=_('Scope display'))
scope = LabeledChoiceField(choices=Role.Scope.choices, label=_("Scope"))
class Meta:
model = Role
fields_mini = ['id', 'name', 'display_name', 'scope']
read_only_fields = [
'users_amount', 'builtin', 'scope_display',
'users_amount', 'builtin',
'date_created', 'date_updated',
'created_by', 'updated_by',
]

View File

@ -36,16 +36,10 @@ class SessionCommandSerializer(SimpleSessionCommandSerializer):
# 限制 64 字符,不能直接迁移成 128 字符,命令表数据量会比较大
account = serializers.CharField(label=_("Account "))
output = serializers.CharField(max_length=2048, allow_blank=True, label=_("Output"))
risk_level_display = serializers.SerializerMethodField(label=_('Risk level display'))
timestamp = serializers.IntegerField(label=_('Timestamp'))
timestamp_display = serializers.DateTimeField(read_only=True, label=_('Datetime'))
remote_addr = serializers.CharField(read_only=True, label=_('Remote Address'))
@staticmethod
def get_risk_level_display(obj):
risk_mapper = dict(AbstractSessionCommand.RISK_LEVEL_CHOICES)
return risk_mapper.get(obj.risk_level)
def validate_account(self, value):
if len(value) > 64:
value = pretty_string(value, 64)

View File

@ -1,9 +1,8 @@
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
from django.utils.translation import ugettext_lazy as _
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from assets.const import Protocol
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from ..models import Session
__all__ = [
@ -14,7 +13,6 @@ __all__ = [
class SessionSerializer(BulkOrgResourceModelSerializer):
org_id = serializers.CharField(allow_blank=True)
terminal_display = serializers.CharField(read_only=True, label=_('Terminal display'))
protocol = serializers.ChoiceField(choices=Protocol.choices, label=_("Protocol"))
class Meta:
@ -22,11 +20,11 @@ class SessionSerializer(BulkOrgResourceModelSerializer):
fields_mini = ["id"]
fields_small = fields_mini + [
"user", "asset", "user_id", "asset_id", 'account', "protocol",
"login_from", "login_from_display", "remote_addr", "is_success",
"login_from", "remote_addr", "is_success",
"is_finished", "has_replay", "date_start", "date_end",
]
fields_fk = ["terminal", ]
fields_custom = ["can_replay", "can_join", "can_terminate", 'terminal_display']
fields_custom = ["can_replay", "can_join", "can_terminate"]
fields = fields_small + fields_fk + fields_custom
extra_kwargs = {
"protocol": {'label': _('Protocol')},

View File

@ -1,18 +1,19 @@
# -*- coding: utf-8 -*-
#
from functools import partial
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
from common.drf.fields import EncryptedField, ObjectRelatedField, LabeledChoiceField
from common.drf.serializers import CommonBulkSerializerMixin
from common.validators import PhoneValidator
from common.utils import pretty_string, get_logger
from common.drf.fields import EncryptedField
from common.validators import PhoneValidator
from rbac.builtin import BuiltinRole
from rbac.permissions import RBACPermission
from rbac.models import OrgRoleBinding, SystemRoleBinding, Role
from ..models import User
from rbac.permissions import RBACPermission
from ..const import PasswordStrategy
from ..models import User
__all__ = [
"UserSerializer",
@ -25,19 +26,8 @@ logger = get_logger(__file__)
class RolesSerializerMixin(serializers.Serializer):
system_roles = serializers.ManyRelatedField(
child_relation=serializers.PrimaryKeyRelatedField(queryset=Role.system_roles),
label=_("System roles"),
)
org_roles = serializers.ManyRelatedField(
required=False,
child_relation=serializers.PrimaryKeyRelatedField(queryset=Role.org_roles),
label=_("Org roles"),
)
system_roles_display = serializers.SerializerMethodField(
label=_("System roles display")
)
org_roles_display = serializers.SerializerMethodField(label=_("Org roles display"))
system_roles = ObjectRelatedField(queryset=Role.system_roles, label=_("System roles"), many=True)
org_roles = ObjectRelatedField(queryset=Role.org_roles, label=_("Org roles"), many=True)
@staticmethod
def get_system_roles_display(user):
@ -60,8 +50,8 @@ class RolesSerializerMixin(serializers.Serializer):
if action in ("partial_bulk_update", "bulk_update", "partial_update", "update"):
action = "create"
model_cls_field_mapper = {
SystemRoleBinding: ["system_roles", "system_roles_display"],
OrgRoleBinding: ["org_roles", "system_roles_display"],
SystemRoleBinding: ["system_roles"],
OrgRoleBinding: ["org_roles"],
}
for model_cls, fields_names in model_cls_field_mapper.items():
@ -79,10 +69,8 @@ class RolesSerializerMixin(serializers.Serializer):
return fields
class UserSerializer(
RolesSerializerMixin, CommonBulkSerializerMixin, serializers.ModelSerializer
):
password_strategy = serializers.ChoiceField(
class UserSerializer(RolesSerializerMixin, CommonBulkSerializerMixin, serializers.ModelSerializer):
password_strategy = LabeledChoiceField(
choices=PasswordStrategy.choices,
default=PasswordStrategy.email,
required=False,
@ -93,9 +81,6 @@ class UserSerializer(
mfa_force_enabled = serializers.BooleanField(
read_only=True, label=_("MFA force enabled")
)
mfa_level_display = serializers.ReadOnlyField(
source="get_mfa_level_display", label=_("MFA level display")
)
login_blocked = serializers.BooleanField(read_only=True, label=_("Login blocked"))
is_expired = serializers.BooleanField(read_only=True, label=_("Is expired"))
can_public_key_auth = serializers.ReadOnlyField(
@ -108,9 +93,6 @@ class UserSerializer(
allow_null=True,
max_length=1024,
)
# Todo: 这里看看该怎么搞
# can_update = serializers.SerializerMethodField(label=_('Can update'))
# can_delete = serializers.SerializerMethodField(label=_('Can delete'))
custom_m2m_fields = {
"system_roles": [BuiltinRole.system_user],
"org_roles": [BuiltinRole.org_user],
@ -122,44 +104,22 @@ class UserSerializer(
fields_mini = ["id", "name", "username"]
# 只能写的字段, 这个虽然无法在框架上生效,但是更多对我们是提醒
fields_write_only = [
"password",
"public_key",
"password", "public_key",
]
# small 指的是 不需要计算的直接能从一张表中获取到的数据
fields_small = (
fields_mini
+ fields_write_only
+ [
"email",
"wechat",
"phone",
"mfa_level",
"source",
"source_display",
"can_public_key_auth",
"need_update_password",
"mfa_enabled",
"is_service_account",
"is_valid",
"is_expired",
"is_active", # 布尔字段
"date_expired",
"date_joined",
"last_login", # 日期字段
"created_by",
"comment", # 通用字段
"is_wecom_bound",
"is_dingtalk_bound",
"is_feishu_bound",
"is_otp_secret_key_bound",
"wecom_id",
"dingtalk_id",
"feishu_id",
]
)
fields_small = fields_mini + fields_write_only + [
"email", "wechat", "phone", "mfa_level", "source",
"need_update_password", "mfa_enabled",
"is_service_account", "is_valid",
"is_expired", "is_active", # 布尔字段
"is_otp_secret_key_bound", "can_public_key_auth",
"date_expired", "date_joined",
"last_login", # 日期字段
"created_by", "comment", # 通用字段
"wecom_id", "dingtalk_id", "feishu_id",
]
# 包含不太常用的字段,可以没有
fields_verbose = fields_small + [
"mfa_level_display",
"mfa_force_enabled",
"is_first_login",
"date_password_last_updated",
@ -168,25 +128,14 @@ class UserSerializer(
# 外键的字段
fields_fk = []
# 多对多字段
fields_m2m = [
"groups",
"groups_display",
"system_roles",
"org_roles",
"system_roles_display",
"org_roles_display",
]
fields_m2m = ["groups", "system_roles", "org_roles", ]
# 在serializer 上定义的字段
fields_custom = ["login_blocked", "password_strategy"]
fields = fields_verbose + fields_fk + fields_m2m + fields_custom
read_only_fields = [
"date_joined",
"last_login",
"created_by",
"is_first_login",
"wecom_id",
"dingtalk_id",
"date_joined", "last_login", "created_by",
"is_first_login", "wecom_id", "dingtalk_id",
"feishu_id",
]
disallow_self_update_fields = ["is_active"]
@ -205,18 +154,9 @@ class UserSerializer(
"is_expired": {"label": _("Is expired")},
"avatar_url": {"label": _("Avatar url")},
"created_by": {"read_only": True, "allow_blank": True},
"groups_display": {"label": _("Groups name")},
"source_display": {"label": _("Source name")},
"org_role_display": {"label": _("Organization role name")},
"role_display": {"label": _("Super role name")},
"total_role_display": {"label": _("Total role name")},
"role": {"default": "User"},
"is_wecom_bound": {"label": _("Is wecom bound")},
"is_dingtalk_bound": {"label": _("Is dingtalk bound")},
"is_feishu_bound": {"label": _("Is feishu bound")},
"is_otp_secret_key_bound": {"label": _("Is OTP bound")},
"phone": {"validators": [PhoneValidator()]},
"system_role_display": {"label": _("System role name")},
}
def validate_password(self, password):
@ -326,8 +266,6 @@ class InviteSerializer(RolesSerializerMixin, serializers.Serializer):
help_text=_("For security, only list several users"),
)
system_roles = None
system_roles_display = None
org_roles_display = None
class ServiceAccountSerializer(serializers.ModelSerializer):