功能变化: 优化数据导入功能

pull/64/head
李强 2022-06-15 00:45:27 +08:00
parent 5a23609ddd
commit c7103f8970
3 changed files with 72 additions and 63 deletions

View File

@ -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])

View File

@ -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

View File

@ -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
]