From c7103f89705bcec6c98a3a5e890933ed13cc4ec9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BC=BA?= <1206709430@qq.com> Date: Wed, 15 Jun 2022 00:45:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=8F=98=E5=8C=96:=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=95=B0=E6=8D=AE=E5=AF=BC=E5=85=A5=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/dvadmin/system/views/user.py | 89 ++++++++------------ backend/dvadmin/utils/import_export.py | 32 +++++-- backend/dvadmin/utils/import_export_mixin.py | 14 +-- 3 files changed, 72 insertions(+), 63 deletions(-) diff --git a/backend/dvadmin/system/views/user.py b/backend/dvadmin/system/views/user.py index d5e5c87..a3d8a38 100644 --- a/backend/dvadmin/system/views/user.py +++ b/backend/dvadmin/system/views/user.py @@ -19,8 +19,7 @@ class UserSerializer(CustomModelSerializer): """ 用户管理-序列化器 """ - - dept_name = serializers.CharField(source="dept.name", read_only=True) + dept_name = serializers.CharField(source='dept.name', read_only=True) role_info = DynamicSerializerMethodField() class Meta: @@ -37,7 +36,11 @@ class UserSerializer(CustomModelSerializer): # You can do what ever you want in here # `parsed_query` param is passed to BookSerializer to allow further querying - serializer = RoleSerializer(roles, many=True, parsed_query=parsed_query) + serializer = RoleSerializer( + roles, + many=True, + parsed_query=parsed_query + ) return serializer.data @@ -48,29 +51,14 @@ class UsersInitSerializer(CustomModelSerializer): class Meta: model = Users - fields = [ - "username", - "email", - "mobile", - "avatar", - "name", - "gender", - "user_type", - "dept", - "user_type", - "first_name", - "last_name", - "email", - "is_staff", - "is_active", - "creator", - "dept_belong_id", - "password", - "last_login", - "is_superuser", - ] - read_only_fields = ["id"] - extra_kwargs = {"creator": {"write_only": True}, "dept_belong_id": {"write_only": True}} + fields = ["username", "email", 'mobile', 'avatar', "name", 'gender', 'user_type', "dept", 'user_type', + 'first_name', 'last_name', 'email', 'is_staff', 'is_active', 'creator', 'dept_belong_id', + 'password', 'last_login', 'is_superuser'] + read_only_fields = ['id'] + extra_kwargs = { + 'creator': {'write_only': True}, + 'dept_belong_id': {'write_only': True} + } class UserCreateSerializer(CustomModelSerializer): @@ -80,7 +68,9 @@ class UserCreateSerializer(CustomModelSerializer): username = serializers.CharField( max_length=50, - validators=[CustomUniqueValidator(queryset=Users.objects.all(), message="账号必须唯一")], + validators=[ + CustomUniqueValidator(queryset=Users.objects.all(), message="账号必须唯一") + ], ) password = serializers.CharField( required=False, @@ -118,13 +108,17 @@ class UserUpdateSerializer(CustomModelSerializer): username = serializers.CharField( max_length=50, - validators=[CustomUniqueValidator(queryset=Users.objects.all(), message="账号必须唯一")], + validators=[ + CustomUniqueValidator(queryset=Users.objects.all(), message="账号必须唯一") + ], ) # password = serializers.CharField(required=False, allow_blank=True) mobile = serializers.CharField( max_length=50, - validators=[CustomUniqueValidator(queryset=Users.objects.all(), message="手机号必须唯一")], - allow_blank=True, + validators=[ + CustomUniqueValidator(queryset=Users.objects.all(), message="手机号必须唯一") + ], + allow_blank=True ) def save(self, **kwargs): @@ -148,15 +142,13 @@ class ExportUserProfileSerializer(CustomModelSerializer): 用户导出 序列化器 """ - last_login = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True) - is_active = serializers.SerializerMethodField(read_only=True) - dept__deptName = serializers.CharField(source="dept.name", default="") + last_login = serializers.DateTimeField( + format="%Y-%m-%d %H:%M:%S", required=False, read_only=True + ) + dept__deptName = serializers.CharField(source="dept.deptName", default="") dept__owner = serializers.CharField(source="dept.owner", default="") gender = serializers.CharField(source="get_gender_display", read_only=True) - def get_is_active(self, instance): - return "启用" if instance.is_active else "停用" - class Meta: model = Users fields = ( @@ -175,20 +167,13 @@ class ExportUserProfileSerializer(CustomModelSerializer): class UserProfileImportSerializer(CustomModelSerializer): def save(self, **kwargs): data = super().save(**kwargs) - password = hashlib.new("md5", str(self.initial_data.get("password", "")).encode(encoding="UTF-8")).hexdigest() + password = hashlib.new( + "md5", str(self.initial_data.get("password", "")).encode(encoding="UTF-8") + ).hexdigest() data.set_password(password) data.save() return data - def run_validation(self, data={}): - # 把excel 数据进行格式转换 - if type(data) is dict: - data["role"] = str(data["role"]).split(",") - data["dept_id"] = str(data["dept"]).split(",") - data["gender"] = {"男": "1", "女": "0", "未知": "2"}.get(data["gender"]) - data["is_active"] = {"启用": True, "禁用": False}.get(data["is_active"]) - return super().run_validation(data) - class Meta: model = Users exclude = ( @@ -248,18 +233,18 @@ class UserViewSet(CustomModelViewSet): "gender": { "title": "用户性别", "choices": { - "data": [{"未知": 2}, {"男": 1}, {"女": 0}], - }, + "data": {"未知": 2, "男": 1, "女": 0}, + } }, "is_active": { "title": "帐号状态", "choices": { - "data": [{"启用": True}, {"禁用": False}], - }, + "data": {"启用": True, "禁用": False}, + } }, "password": "登录密码", - "dept": {"title": "部门", "choices": {"queryset": Dept.objects.filter(status=True), "values_list": "name"}}, - "role": {"title": "角色", "choices": {"queryset": Role.objects.filter(status=True), "values_list": "name"}}, + "dept": {"title": "部门", "choices": {"queryset": Dept.objects.filter(status=True), "values_name": "name"}}, + "role": {"title": "角色", "choices": {"queryset": Role.objects.filter(status=True), "values_name": "name"}}, } @action(methods=["GET"], detail=False, permission_classes=[IsAuthenticated]) diff --git a/backend/dvadmin/utils/import_export.py b/backend/dvadmin/utils/import_export.py index 7b9a68b..e71a4b2 100644 --- a/backend/dvadmin/utils/import_export.py +++ b/backend/dvadmin/utils/import_export.py @@ -5,32 +5,52 @@ import openpyxl from django.conf import settings -def import_to_data(file_url, field_data): +def import_to_data(file_url, field_data, m2m_fields=None): """ 读取导入的excel文件 - :param request: + :param file_url: :param field_data: 首行数据源 - :param data: 数据源 - :param FilName: 文件名 + :param m2m_fields: 多对多字段 :return: """ # 读取excel 文件 file_path_dir = os.path.join(settings.BASE_DIR, file_url) workbook = openpyxl.load_workbook(file_path_dir) table = workbook[workbook.sheetnames[0]] + # 获取参数映射 + validation_data_dict = {} + for key, value in field_data.items(): + if isinstance(value, dict): + choices = value.get('choices', {}) + data_dict = {} + if choices.get('data'): + for k, v in choices.get('data').items(): + data_dict[k] = v + elif choices.get('queryset') and choices.get('values_name'): + data_list = choices.get('queryset').values(choices.get('values_name'), 'id') + for ele in data_list: + data_dict[ele.get(choices.get('values_name'))] = ele.get('id') + else: + continue + validation_data_dict[key] = data_dict # 创建一个空列表,存储Excel的数据 tables = [] for i, row in enumerate(range(table.max_row)): if i == 0: continue array = {} - for index, ele in enumerate(field_data.keys()): + for index, key in enumerate(field_data.keys()): cell_value = table.cell(row=row + 1, column=index + 2).value # 由于excel导入数字类型后,会出现数字加 .0 的,进行处理 if type(cell_value) is float and str(cell_value).split(".")[1] == "0": cell_value = int(str(cell_value).split(".")[0]) if type(cell_value) is str: cell_value = cell_value.strip(" \t\n\r") - array[ele] = cell_value + if key in validation_data_dict: + array[key] = validation_data_dict.get(key, {}).get(cell_value, None) + if key in m2m_fields: + array[key] = [array[key]] + else: + array[key] = cell_value tables.append(array) return tables diff --git a/backend/dvadmin/utils/import_export_mixin.py b/backend/dvadmin/utils/import_export_mixin.py index 1b60318..5a6d49d 100644 --- a/backend/dvadmin/utils/import_export_mixin.py +++ b/backend/dvadmin/utils/import_export_mixin.py @@ -73,11 +73,10 @@ class ImportSerializerMixin: choices = ele.get('choices', {}) if choices.get('data'): data_list = [] - for data in choices.get('data'): - data_list.extend(data.keys()) + data_list.extend(choices.get('data').keys()) validation_data_dict[ele.get('title')] = data_list - elif choices.get('queryset') and choices.get('values_list'): - data_list = choices.get('queryset').values_list(choices.get('values_list'), flat=True) + elif choices.get('queryset') and choices.get('values_name'): + data_list = choices.get('queryset').values_list(choices.get('values_name'), flat=True) validation_data_dict[ele.get('title')] = list(data_list) else: continue @@ -115,8 +114,13 @@ class ImportSerializerMixin: updateSupport = request.data.get("updateSupport") # 从excel中组织对应的数据结构,然后使用序列化器保存 - data = import_to_data(request.data.get("url"), self.import_field_dict) queryset = self.filter_queryset(self.get_queryset()) + # 获取多对多字段 + m2m_fields = [ + ele.attname for ele in queryset.model._meta.get_fields() if + hasattr(ele, "many_to_many") and ele.many_to_many == True + ] + data = import_to_data(request.data.get("url"), self.import_field_dict, m2m_fields) unique_list = [ ele.attname for ele in queryset.model._meta.get_fields() if hasattr(ele, "unique") and ele.unique == True ]