fix(users): 用户接口添加`org_roles`字段

pull/4517/head
xinwen 2020-08-19 17:38:21 +08:00 committed by 老广
parent 11493b9f3d
commit 64d093e677
7 changed files with 187 additions and 101 deletions

Binary file not shown.

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-08-14 16:50+0800\n"
"POT-Creation-Date: 2020-08-19 17:34+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: JumpServer team<ibuler@qq.com>\n"
@ -29,7 +29,7 @@ msgstr "自定义"
#: orgs/models.py:22 perms/models/base.py:48 settings/models.py:27
#: terminal/models.py:27 terminal/models.py:344 terminal/models.py:376
#: terminal/models.py:413 users/forms/profile.py:20 users/models/group.py:15
#: users/models/user.py:489 users/templates/users/_select_user_modal.html:13
#: users/models/user.py:495 users/templates/users/_select_user_modal.html:13
#: users/templates/users/user_asset_permission.html:37
#: users/templates/users/user_asset_permission.html:154
#: users/templates/users/user_database_app_permission.html:36
@ -79,7 +79,7 @@ msgstr "数据库"
#: assets/models/label.py:23 ops/models/adhoc.py:37 orgs/models.py:25
#: perms/models/base.py:56 settings/models.py:32 terminal/models.py:37
#: terminal/models.py:383 terminal/models.py:420 users/models/group.py:16
#: users/models/user.py:522 users/templates/users/user_detail.html:115
#: users/models/user.py:528 users/templates/users/user_detail.html:115
#: users/templates/users/user_granted_database_app.html:38
#: users/templates/users/user_granted_remote_app.html:37
#: users/templates/users/user_group_detail.html:62
@ -146,8 +146,8 @@ msgstr "参数"
#: assets/models/base.py:240 assets/models/cluster.py:28
#: assets/models/cmd_filter.py:26 assets/models/cmd_filter.py:60
#: assets/models/group.py:21 common/db/models.py:67 common/mixins/models.py:49
#: orgs/models.py:23 orgs/models.py:326 perms/models/base.py:54
#: users/models/user.py:530 users/serializers/group.py:35
#: orgs/models.py:23 orgs/models.py:374 perms/models/base.py:54
#: users/models/user.py:536 users/serializers/group.py:35
#: users/templates/users/user_detail.html:97
#: xpack/plugins/change_auth_plan/models.py:81 xpack/plugins/cloud/models.py:56
#: xpack/plugins/cloud/models.py:146 xpack/plugins/gathered_user/models.py:30
@ -161,7 +161,7 @@ msgstr "创建者"
#: assets/models/domain.py:23 assets/models/gathered_user.py:19
#: assets/models/group.py:22 assets/models/label.py:25 common/db/models.py:69
#: common/mixins/models.py:50 ops/models/adhoc.py:38 ops/models/command.py:27
#: orgs/models.py:24 orgs/models.py:324 perms/models/base.py:55
#: orgs/models.py:24 orgs/models.py:372 perms/models/base.py:55
#: users/models/group.py:18 users/templates/users/user_group_detail.html:58
#: xpack/plugins/cloud/models.py:59 xpack/plugins/cloud/models.py:149
msgid "Date created"
@ -354,7 +354,7 @@ msgstr ""
#: audits/models.py:99 authentication/forms.py:11
#: authentication/templates/authentication/login.html:21
#: authentication/templates/authentication/xpack_login.html:101
#: ops/models/adhoc.py:148 users/forms/profile.py:19 users/models/user.py:487
#: ops/models/adhoc.py:148 users/forms/profile.py:19 users/models/user.py:493
#: users/templates/users/_select_user_modal.html:14
#: users/templates/users/user_detail.html:53
#: users/templates/users/user_list.html:15
@ -395,7 +395,7 @@ msgstr "SSH公钥"
#: assets/models/base.py:239 assets/models/gathered_user.py:20
#: common/db/models.py:70 common/mixins/models.py:51 ops/models/adhoc.py:39
#: orgs/models.py:325
#: orgs/models.py:373
msgid "Date updated"
msgstr "更新日期"
@ -407,7 +407,7 @@ msgstr "带宽"
msgid "Contact"
msgstr "联系人"
#: assets/models/cluster.py:22 users/models/user.py:508
#: assets/models/cluster.py:22 users/models/user.py:514
#: users/templates/users/user_detail.html:62
msgid "Phone"
msgstr "手机"
@ -433,7 +433,7 @@ msgid "Default"
msgstr "默认"
#: assets/models/cluster.py:36 assets/models/label.py:14
#: users/models/user.py:655
#: users/models/user.py:661
msgid "System"
msgstr "系统"
@ -547,7 +547,7 @@ msgstr "默认资产组"
#: assets/models/label.py:15 audits/models.py:36 audits/models.py:56
#: audits/models.py:69 audits/serializers.py:77 authentication/models.py:46
#: authentication/models.py:90 orgs/models.py:16 orgs/models.py:322
#: authentication/models.py:90 orgs/models.py:370
#: perms/forms/asset_permission.py:83 perms/forms/database_app_permission.py:38
#: perms/forms/remote_app_permission.py:40 perms/models/base.py:49
#: templates/index.html:78 terminal/backends/command/models.py:18
@ -555,8 +555,7 @@ msgstr "默认资产组"
#: tickets/models/ticket.py:30 tickets/models/ticket.py:137
#: tickets/serializers/request_asset_perm.py:65
#: tickets/serializers/ticket.py:31 users/forms/group.py:15
#: users/models/user.py:157 users/models/user.py:643
#: users/serializers/group.py:20
#: users/models/user.py:649 users/serializers/group.py:20
#: users/templates/users/user_asset_permission.html:38
#: users/templates/users/user_asset_permission.html:64
#: users/templates/users/user_database_app_permission.html:37
@ -733,14 +732,14 @@ msgid "Backend"
msgstr "后端"
#: assets/serializers/asset_user.py:75 users/forms/profile.py:148
#: users/models/user.py:519 users/templates/users/user_password_update.html:48
#: users/models/user.py:525 users/templates/users/user_password_update.html:48
#: users/templates/users/user_profile.html:69
#: users/templates/users/user_profile_update.html:46
#: users/templates/users/user_pubkey_update.html:46
msgid "Public key"
msgstr "SSH公钥"
#: assets/serializers/asset_user.py:79 users/models/user.py:516
#: assets/serializers/asset_user.py:79 users/models/user.py:522
msgid "Private key"
msgstr "ssh私钥"
@ -1025,7 +1024,7 @@ msgstr "Agent"
#: audits/models.py:104
#: authentication/templates/authentication/_mfa_confirm_modal.html:14
#: authentication/templates/authentication/login_otp.html:6
#: users/forms/profile.py:52 users/models/user.py:511
#: users/forms/profile.py:52 users/models/user.py:517
#: users/serializers/user.py:240 users/templates/users/user_detail.html:77
#: users/templates/users/user_profile.html:87
msgid "MFA"
@ -1265,7 +1264,7 @@ msgid "Show"
msgstr "显示"
#: authentication/templates/authentication/_access_key_modal.html:66
#: users/models/user.py:409 users/serializers/user.py:237
#: users/models/user.py:415 users/serializers/user.py:237
#: users/templates/users/user_profile.html:94
#: users/templates/users/user_profile.html:163
#: users/templates/users/user_profile.html:166
@ -1274,7 +1273,7 @@ msgid "Disable"
msgstr "禁用"
#: authentication/templates/authentication/_access_key_modal.html:67
#: users/models/user.py:410 users/serializers/user.py:238
#: users/models/user.py:416 users/serializers/user.py:238
#: users/templates/users/user_profile.html:92
#: users/templates/users/user_profile.html:170
msgid "Enable"
@ -1685,7 +1684,7 @@ msgid "The current organization cannot be deleted"
msgstr ""
#: orgs/mixins/models.py:56 orgs/mixins/serializers.py:25 orgs/models.py:40
#: orgs/models.py:321
#: orgs/models.py:369
msgid "Organization"
msgstr "组织"
@ -1693,11 +1692,15 @@ msgstr "组织"
msgid "Organization administrator"
msgstr "组织管理员"
#: orgs/models.py:16
msgid "Organization User"
msgstr "组织用户"
#: orgs/models.py:17
msgid "Organization auditor"
msgstr "组织审计员"
#: orgs/models.py:323 users/forms/user.py:27 users/models/user.py:499
#: orgs/models.py:371 users/forms/user.py:27 users/models/user.py:505
#: users/templates/users/_select_user_modal.html:15
#: users/templates/users/user_detail.html:73
#: users/templates/users/user_list.html:16
@ -1722,7 +1725,7 @@ msgstr "提示RDP 协议不支持单独控制上传或下载文件"
#: perms/forms/asset_permission.py:86 perms/forms/database_app_permission.py:41
#: perms/forms/remote_app_permission.py:43 perms/models/base.py:50
#: templates/_nav.html:21 users/forms/user.py:168 users/models/group.py:31
#: users/models/user.py:495 users/serializers/user.py:49
#: users/models/user.py:501 users/serializers/user.py:48
#: users/templates/users/_select_user_modal.html:16
#: users/templates/users/user_asset_permission.html:39
#: users/templates/users/user_asset_permission.html:67
@ -1789,7 +1792,7 @@ msgid "Asset permission"
msgstr "资产授权"
#: perms/models/base.py:53 tickets/serializers/request_asset_perm.py:31
#: users/models/user.py:527 users/templates/users/user_detail.html:93
#: users/models/user.py:533 users/templates/users/user_detail.html:93
#: users/templates/users/user_profile.html:120
msgid "Date expired"
msgstr "失效日期"
@ -2537,36 +2540,37 @@ msgstr "结束日期"
msgid "Args"
msgstr "参数"
#: tickets/api/request_asset_perm.py:45
#: tickets/api/request_asset_perm.py:46
#, python-format
msgid "Ticket has %s"
msgstr "工单已%s"
#: tickets/api/request_asset_perm.py:90
#: tickets/api/request_asset_perm.py:91
msgid "Confirm assets first"
msgstr "请先确认资产"
#: tickets/api/request_asset_perm.py:93
#: tickets/api/request_asset_perm.py:94
msgid "Confirmed assets changed"
msgstr "确认的资产变更了"
#: tickets/api/request_asset_perm.py:97
#: tickets/api/request_asset_perm.py:98
msgid "Confirm system-user first"
msgstr "请先确认系统用户"
#: tickets/api/request_asset_perm.py:101
#: tickets/api/request_asset_perm.py:102
msgid "Confirmed system-user changed"
msgstr "确认的系统用户变更了"
#: tickets/api/request_asset_perm.py:104 xpack/plugins/cloud/models.py:202
#: tickets/api/request_asset_perm.py:105 tickets/api/request_asset_perm.py:112
#: xpack/plugins/cloud/models.py:202
msgid "Succeed"
msgstr "成功"
#: tickets/api/request_asset_perm.py:112
#: tickets/api/request_asset_perm.py:120
msgid "From request ticket: {} {}"
msgstr "来自工单申请: {} {}"
#: tickets/api/request_asset_perm.py:114
#: tickets/api/request_asset_perm.py:122
msgid "{} request assets, approved by {}"
msgstr "{} 申请资产,通过人 {}"
@ -2749,7 +2753,7 @@ msgstr ""
" </div>\n"
" "
#: users/api/user.py:147
#: users/api/user.py:158
msgid "Could not reset self otp, use profile reset instead"
msgstr "不能在该页面重置多因子认证, 请去个人信息页面重置"
@ -2795,7 +2799,7 @@ msgstr "确认密码"
msgid "Password does not match"
msgstr "密码不一致"
#: users/forms/profile.py:89 users/models/user.py:491
#: users/forms/profile.py:89 users/models/user.py:497
#: users/templates/users/user_detail.html:57
#: users/templates/users/user_profile.html:59
msgid "Email"
@ -2836,7 +2840,7 @@ msgstr "不能和原来的密钥相同"
msgid "Not a valid ssh public key"
msgstr "SSH密钥不合法"
#: users/forms/user.py:31 users/models/user.py:534
#: users/forms/user.py:31 users/models/user.py:540
#: users/templates/users/user_detail.html:89
#: users/templates/users/user_list.html:18
#: users/templates/users/user_profile.html:102
@ -2856,15 +2860,15 @@ msgstr "添加到用户组"
msgid "* Your password does not meet the requirements"
msgstr "* 您的密码不符合要求"
#: users/forms/user.py:124 users/serializers/user.py:37
#: users/forms/user.py:124 users/serializers/user.py:36
msgid "Reset link will be generated and sent to the user"
msgstr "生成重置密码链接,通过邮件发送给用户"
#: users/forms/user.py:125 users/serializers/user.py:38
#: users/forms/user.py:125 users/serializers/user.py:37
msgid "Set password"
msgstr "设置密码"
#: users/forms/user.py:132 users/serializers/user.py:45
#: users/forms/user.py:132 users/serializers/user.py:44
#: xpack/plugins/change_auth_plan/models.py:61
#: xpack/plugins/change_auth_plan/serializers.py:30
msgid "Password strategy"
@ -2874,6 +2878,10 @@ msgstr "密码策略"
msgid "System administrator"
msgstr "系统管理员"
#: users/models/user.py:157
msgid "System User"
msgstr "系统用户"
#: users/models/user.py:158
msgid "System auditor"
msgstr "系统审计员"
@ -2882,67 +2890,67 @@ msgstr "系统审计员"
msgid "Application"
msgstr "应用程序"
#: users/models/user.py:411 users/templates/users/user_profile.html:90
#: users/models/user.py:417 users/templates/users/user_profile.html:90
msgid "Force enable"
msgstr "强制启用"
#: users/models/user.py:478
#: users/models/user.py:484
msgid "Local"
msgstr "数据库"
#: users/models/user.py:502
#: users/models/user.py:508
msgid "Avatar"
msgstr "头像"
#: users/models/user.py:505 users/templates/users/user_detail.html:68
#: users/models/user.py:511 users/templates/users/user_detail.html:68
msgid "Wechat"
msgstr "微信"
#: users/models/user.py:538
#: users/models/user.py:544
msgid "Date password last updated"
msgstr "最后更新密码日期"
#: users/models/user.py:651
#: users/models/user.py:657
msgid "Administrator"
msgstr "管理员"
#: users/models/user.py:654
#: users/models/user.py:660
msgid "Administrator is the super user of system"
msgstr "Administrator是初始的超级管理员"
#: users/serializers/user.py:55 users/serializers/user.py:93
#: users/serializers/user.py:53 users/serializers/user.py:88
msgid "Organization role name"
msgstr "组织角色名称"
#: users/serializers/user.py:59
#: users/serializers/user.py:55
msgid "Total role name"
msgstr "汇总角色名称"
#: users/serializers/user.py:84 users/serializers/user.py:253
#: users/serializers/user.py:79 users/serializers/user.py:253
msgid "Is first login"
msgstr "首次登录"
#: users/serializers/user.py:85
#: users/serializers/user.py:80
msgid "Is valid"
msgstr "账户是否有效"
#: users/serializers/user.py:86
#: users/serializers/user.py:81
msgid "Is expired"
msgstr " 是否过期"
#: users/serializers/user.py:87
#: users/serializers/user.py:82
msgid "Avatar url"
msgstr "头像路径"
#: users/serializers/user.py:91
#: users/serializers/user.py:86
msgid "Groups name"
msgstr "用户组名"
#: users/serializers/user.py:92
#: users/serializers/user.py:87
msgid "Source name"
msgstr "用户来源名"
#: users/serializers/user.py:94
#: users/serializers/user.py:89
msgid "Super role name"
msgstr "超级角色名称"

View File

@ -0,0 +1,18 @@
# Generated by Django 2.2.13 on 2020-08-19 09:32
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('orgs', '0007_auto_20200728_1805'),
]
operations = [
migrations.AlterField(
model_name='organizationmember',
name='role',
field=models.CharField(choices=[('Admin', 'Organization administrator'), ('User', 'Organization User'), ('Auditor', 'Organization auditor')], default='User', max_length=16, verbose_name='Role'),
),
]

View File

@ -13,7 +13,7 @@ from common.db.models import ChoiceSet
class ROLE(ChoiceSet):
ADMIN = choices.ADMIN, _('Organization administrator')
USER = choices.USER, _('User')
USER = choices.USER, _('Organization User')
AUDITOR = choices.AUDITOR, _("Organization auditor")
@ -229,15 +229,29 @@ def _none2list(*args):
return ([] if v is None else v for v in args)
class UserRoleMapper(dict):
def __init__(self, container=set):
super().__init__()
self.users = container()
self.admins = container()
self.auditors = container()
self[ROLE.USER] = self.users
self[ROLE.ADMIN] = self.admins
self[ROLE.AUDITOR] = self.auditors
class OrgMemeberManager(models.Manager):
def remove_users_by_role(self, org, users=None, admins=None, auditors=None):
from users.models import User
if not any((users, admins, auditors)):
return
users, admins, auditors = _none2list(users, admins, auditors)
send = partial(signals.m2m_changed.send, sender=self.model, instance=org, reverse=False,
model=Organization, pk_set=[*users, *admins, *auditors], using=self.db)
model=User, pk_set=[*users, *admins, *auditors], using=self.db)
send(action="pre_remove")
self.filter(org_id=org.id).filter(
@ -248,6 +262,8 @@ class OrgMemeberManager(models.Manager):
send(action="post_remove")
def add_users_by_role(self, org, users=None, admins=None, auditors=None):
from users.models import User
if not any((users, admins, auditors)):
return
users, admins, auditors = _none2list(users, admins, auditors)
@ -266,7 +282,7 @@ class OrgMemeberManager(models.Manager):
oms_add.append(self.model(org_id=org.id, user_id=user, role=role))
send = partial(signals.m2m_changed.send, sender=self.model, instance=org, reverse=False,
model=Organization, pk_set=[*users, *admins, *auditors], using=self.db)
model=User, pk_set=[*users, *admins, *auditors], using=self.db)
send(action='pre_add')
self.bulk_create(oms_add)
@ -278,24 +294,56 @@ class OrgMemeberManager(models.Manager):
new_users = _convert_to_uuid_set(new_users)
return (old_users - new_users), (new_users - old_users)
def set_user_roles(self, org, user, roles):
"""
设置某个用户在某个组织里的角色
"""
old_roles = set(self.filter(org_id=org.id, user=user).values_list('role', flat=True))
new_roles = set(roles)
roles_remove = old_roles - new_roles
roles_add = new_roles - old_roles
to_remove = UserRoleMapper()
to_add = UserRoleMapper()
for role in roles_remove:
if role in to_remove:
to_remove[role].add(user)
for role in roles_add:
if role in to_add:
to_add[role].add(user)
self.remove_users_by_role(
org,
to_remove.users,
to_remove.admins,
to_remove.auditors
)
self.add_users_by_role(
org,
to_add.users,
to_add.admins,
to_add.auditors
)
def set_users_by_role(self, org, users=None, admins=None, auditors=None):
"""
给组织设置带角色的用户
"""
oms = self.filter(org_id=org.id).values_list('role', 'user_id')
old_users, old_admins, old_auditors = set(), set(), set()
mapper = {
ROLE.USER: old_users,
ROLE.ADMIN: old_admins,
ROLE.AUDITOR: old_auditors
}
old_mapper = UserRoleMapper()
for role, user_id in oms:
if role in mapper:
mapper[role].add(user_id)
if role in old_mapper:
old_mapper[role].add(user_id)
users_remove, users_add = self._get_remove_add_set(users, old_users)
admins_remove, admins_add = self._get_remove_add_set(admins, old_admins)
auditors_remove, auditors_add = self._get_remove_add_set(auditors, old_auditors)
users_remove, users_add = self._get_remove_add_set(users, old_mapper.users)
admins_remove, admins_add = self._get_remove_add_set(admins, old_mapper.admins)
auditors_remove, auditors_add = self._get_remove_add_set(auditors, old_mapper.auditors)
self.remove_users_by_role(
org,

View File

@ -56,31 +56,25 @@ class UserViewSet(CommonApiMixin, UserQuerysetMixin, BulkModelViewSet):
def perform_create(self, serializer):
validated_data = serializer.validated_data
if isinstance(validated_data, list):
org_roles = [item.pop('org_role', None) for item in validated_data]
else:
org_roles = [validated_data.pop('org_role', None)]
# `org_roles` 先 `pop`
if isinstance(validated_data, list):
org_roles = [item.pop('org_roles', []) for item in validated_data]
else:
org_roles = [validated_data.pop('org_roles', [])]
# 创建用户
users = serializer.save()
if isinstance(users, User):
users = [users]
if current_org and current_org.is_real():
mapper = {
ORG_ROLE.USER: [],
ORG_ROLE.ADMIN: [],
ORG_ROLE.AUDITOR: []
}
for user, role in zip(users, org_roles):
if role in mapper:
mapper[role].append(user)
else:
mapper[ORG_ROLE.USER].append(user)
OrganizationMember.objects.set_users_by_role(
current_org, users=mapper[ORG_ROLE.USER],
admins=mapper[ORG_ROLE.ADMIN],
auditors=mapper[ORG_ROLE.AUDITOR]
)
# 只有真实存在的组织才真正关联用户
if current_org and current_org.is_real():
for user, roles in zip(users, org_roles):
if not roles:
# 当前组织创建的用户,至少是该组织的`User`
roles.append(ORG_ROLE.USER)
OrganizationMember.objects.set_user_roles(current_org, user, roles)
self.send_created_signal(users)
def get_permissions(self):
@ -101,6 +95,23 @@ class UserViewSet(CommonApiMixin, UserQuerysetMixin, BulkModelViewSet):
self.check_object_permissions(self.request, obj)
self.perform_destroy(obj)
def perform_update(self, serializer):
validated_data = serializer.validated_data
# `org_roles` 先 `pop`
if isinstance(validated_data, list):
org_roles = [item.pop('org_roles', None) for item in validated_data]
else:
org_roles = [validated_data.pop('org_roles', None)]
users = serializer.save()
if isinstance(users, User):
users = [users]
if current_org and current_org.is_real():
for user, roles in zip(users, org_roles):
if roles is not None:
# roles 是 `Node` 表明不需要更新
OrganizationMember.objects.set_user_roles(current_org, user, roles)
def perform_bulk_update(self, serializer):
# TODO: 需要测试
users_ids = [

View File

@ -154,7 +154,7 @@ class AuthMixin:
class RoleMixin:
class ROLE(ChoiceSet):
ADMIN = choices.ADMIN, _('System administrator')
USER = choices.USER, _('User')
USER = choices.USER, _('System User')
AUDITOR = choices.AUDITOR, _('System auditor')
APP = 'App', _('Application')
@ -164,15 +164,15 @@ class RoleMixin:
def role_display(self):
return self.get_role_display()
@property
def org_role_display(self):
@lazyproperty
def org_roles(self):
from orgs.models import ROLE as ORG_ROLE
if not current_org.is_real():
if self.is_superuser:
return ORG_ROLE.ADMIN.label
return [ORG_ROLE.ADMIN]
else:
return ORG_ROLE.USER.label
return [ORG_ROLE.USER]
if hasattr(self, 'gc_m2m_org_members__role'):
names = self.gc_m2m_org_members__role
@ -184,8 +184,14 @@ class RoleMixin:
roles = set(self.m2m_org_members.filter(
org_id=current_org.id
).values_list('role', flat=True))
roles = list(roles)
roles.sort()
return roles
return ' | '.join([str(ORG_ROLE[role]) for role in roles if role in ORG_ROLE])
@lazyproperty
def org_role_display(self):
from orgs.models import ROLE as ORG_ROLE
return ' | '.join([str(ORG_ROLE[role]) for role in self.org_roles if role in ORG_ROLE])
def current_org_roles(self):
from orgs.models import OrganizationMember, ROLE as ORG_ROLE

View File

@ -7,7 +7,6 @@ from rest_framework import serializers
from common.utils import validate_ssh_public_key
from common.mixins import CommonBulkSerializerMixin
from common.serializers import AdaptedBulkListSerializer
from common.permissions import CanUpdateDeleteUser
from common.drf.fields import GroupConcatedPrimaryKeyRelatedField
from orgs.models import ROLE as ORG_ROLE
@ -51,17 +50,13 @@ class UserSerializer(CommonBulkSerializerMixin, serializers.ModelSerializer):
login_blocked = serializers.SerializerMethodField()
can_update = serializers.SerializerMethodField()
can_delete = serializers.SerializerMethodField()
org_role = serializers.ChoiceField(
label=_('Organization role name'), write_only=True,
allow_null=True, required=False, allow_blank=True,
choices=ORG_ROLE.choices
)
org_roles = serializers.ListField(label=_('Organization role name'), allow_null=True, required=False,
child=serializers.ChoiceField(choices=ORG_ROLE.choices))
total_role_display = serializers.SerializerMethodField(label=_('Total role name'))
key_prefix_block = "_LOGIN_BLOCK_{}"
class Meta:
model = User
list_serializer_class = AdaptedBulkListSerializer
# mini 是指能识别对象的最小单元
fields_mini = ['id', 'name', 'username']
# small 指的是 不需要计算的直接能从一张表中获取到的数据
@ -75,7 +70,7 @@ class UserSerializer(CommonBulkSerializerMixin, serializers.ModelSerializer):
]
fields = fields_small + [
'groups', 'role', 'groups_display', 'role_display',
'can_update', 'can_delete', 'login_blocked', 'org_role'
'can_update', 'can_delete', 'login_blocked', 'org_roles'
]
extra_kwargs = {