Appearance
导入导出功能
导入功能
上一章CRUD功能开发时,创建了my_demo
应用,在此基础上开发导入功能。
开发后端
编写序列化器
进入目录django-vue3-admin\backend\my_demo
,编辑文件serializers.py
。添加:
python
class CrudDemoModelImportSerializer(CustomModelSerializer):
"""导入序列化器"""
class Meta:
model = CrudDemoModel
fields = "__all__"
编写视图层
进入目录django-vue3-admin\backend\my_demo
,编辑文件views.py
。
python
from django.shortcuts import render
# Create your views here.
from my_demo.models import CrudDemoModel
from my_demo.serializers import (
CurdDemoModelSerializer,
CrudDemoModelCreateUpdateSerializer,
CrudDemoModelImportSerializer,
)
from dvadmin.utils.viewset import CustomModelViewSet
class CrudDemoModelViewSet(CustomModelViewSet):
queryset = CrudDemoModel.objects.all()
serializer_class = CurdDemoModelSerializer
create_serializer_class = CrudDemoModelCreateUpdateSerializer
update_serializer_class = CrudDemoModelCreateUpdateSerializer
# 导入配置
import_field_dict = {
"goods": "商品",
"inventory": "库存量",
"goods_price": "商品价格",
"purchase_goods_date": "进货日期",
}
# 导入序列化器
import_serializer_class = CrudDemoModelImportSerializer
开发前端
进入目录django-vue3-admin\web\src\views\MyDemo\CrudDemoModelViewSet\
,编辑文件index.vue
。
typescript
<template>
<fs-page class="PageFeatureSearchMulti">
<fs-crud ref="crudRef" v-bind="crudBinding">
<template #cell_url="scope">
<el-tag size="small">{{ scope.row.url }}</el-tag>
</template>
<!-- 注释编号: django-vue3-admin-index442216: -->
<!-- 注释编号:django-vue3-admin-index39263917:代码开始行-->
<!-- 功能说明:使用导入组件,并且修改api地址为当前对应的api,当前是demo的api="api/CrudDemoModelViewSet/"-->
<template #actionbar-right>
<importExcel api="api/CrudDemoModelViewSet/" v-auth="'user:Import'">导入</importExcel>
</template>
<!-- 注释编号:django-vue3-admin-index263917:代码结束行-->
</fs-crud>
</fs-page>
</template>
<script lang="ts">
import { onMounted, getCurrentInstance, defineComponent } from 'vue';
import { useFs } from '@fast-crud/fast-crud';
import createCrudOptions from './crud';
// 注释编号: django-vue3-admin-index192316:导入组件
import importExcel from '/@/components/importExcel/index.vue'
export default defineComponent({ //这里配置defineComponent
name: "CrudDemoModelViewSet", //把name放在这里进行配置了
components: { importExcel }, //注释编号: django-vue3-admin-index552416: 注册组件,把importExcel组件放在这里,这样<template></template>中才能正确的引用到组件
setup() { //这里配置了setup()
const instance = getCurrentInstance();
const context: any = {
componentName: instance?.type.name
};
const { crudBinding, crudRef, crudExpose, resetCrudOptions } = useFs({ createCrudOptions, context });
// 页面打开后获取列表数据
onMounted(() => {
crudExpose.doRefresh();
});
return {
//增加了return把需要给上面<template>内调用的<fs-crud ref="crudRef" v-bind="crudBinding">
crudBinding,
crudRef,
};
} //这里关闭setup()
}); //关闭defineComponent
</script>
配置按钮权限
运行项目,以超级管理员登录系统,选择系统管理--菜单管理,选择菜单“商品管理--商品信息”,右侧按钮权限配置中,点击添加按钮,依次添加如下权限。(如果已存在,不用重复添加)
序号 | 权限名称 | 权限值 | 请求方式 | 接口地址 |
---|---|---|---|---|
1 | 导出 | CrudDemoModelViewSet:Export | POST | /api/CrudDemoModelViewSet/export_data/ |
2 | 导入 | CrudDemoModelViewSet:Import | POST | /api/CrudDemoModelViewSet/import_data/ |
测试导入功能
退出再重新用超级管理员登录系统,点击菜单:商品管理--商品信息,点击导入--下载导入模板。
在下载的EXCEL模板中,填写数据,然后上传--确定。注意:
- 日期字段:设置单元格格式--日期--类型选择2001/3/7
- 不要填写其它无关数据
导出功能
开发后端
编写序列化器
进入目录django-vue3-admin\backend\my_demo
,编辑文件serializers.py
。添加:
python
class ExportCrudDemoSerializer(CustomModelSerializer):
"""导出序列化器"""
class Meta:
model = CrudDemoModel
fields = "__all__"
编写视图层
进入目录django-vue3-admin\backend\my_demo
,编辑文件views.py
。
python
from django.shortcuts import render
# Create your views here.
from my_demo.models import CrudDemoModel
from my_demo.serializers import (
CurdDemoModelSerializer,
CrudDemoModelCreateUpdateSerializer,
CrudDemoModelImportSerializer,
ExportCrudDemoSerializer,
)
from dvadmin.utils.viewset import CustomModelViewSet
class CrudDemoModelViewSet(CustomModelViewSet):
queryset = CrudDemoModel.objects.all()
serializer_class = CurdDemoModelSerializer
create_serializer_class = CrudDemoModelCreateUpdateSerializer
update_serializer_class = CrudDemoModelCreateUpdateSerializer
# 导入配置
import_field_dict = {
"goods": "商品",
"inventory": "库存量",
"goods_price": "商品价格",
"purchase_goods_date": "进货日期",
}
# 导入序列化器
import_serializer_class = CrudDemoModelImportSerializer
# 导出配置
export_field_dict = {
"goods": "商品",
"inventory": "库存量",
"goods_price": "商品价格",
"purchase_goods_date": "进货日期",
}
# 导出序列化器
export_serializer_class = ExportCrudDemoSerializer
开发前端
进入目录django-vue3-admin\web\src\views\MyDemo\CrudDemoModelViewSet\
,编辑文件crud.tsx
,添加如下代码。
typescript
actionbar: {
buttons: {
export: {
// 注释编号:django-vue3-admin-crud210716:注意这个auth里面的值,最好是使用index.vue文件里面的name值并加上请求动作的单词
show: auth('CrudDemoModelViewSet:Export'),
text: '导出', //按钮文字
title: '导出', //鼠标停留显示的信息
click() {
return exportRequest(crudExpose.getSearchFormData());
// return exportRequest(crudExpose!.getSearchFormData()) // 注意这个crudExpose!.getSearchFormData(),一些低版本的环境是需要添加!的
},
},
add: {
show: auth('CrudDemoModelViewSet:Create'),
},
},
},
配置按钮权限
运行项目,以超级管理员登录系统,选择系统管理--菜单管理,选择菜单“商品管理--商品信息”,右侧按钮权限配置中,点击添加按钮,依次添加如下权限。(如果已存在,不用重复添加)
序号 | 权限名称 | 权限值 | 请求方式 | 接口地址 |
---|---|---|---|---|
1 | 导出 | CrudDemoModelViewSet:Export | POST | /api/CrudDemoModelViewSet/export_data/ |
2 | 导入 | CrudDemoModelViewSet:Import | POST | /api/CrudDemoModelViewSet/import_data/ |
测试导出功能
退出再重新用超级管理员登录系统,点击菜单:商品管理--商品信息,点击导出--另存为。
排错指南
导入失败,日期格式错误
错误描述:测试导入功能失败,提示:【进货日期:期望为日期,获得的是日期时间。: api/CrudDemoModelViewSet/import_data/】
错误分析:
进入目录django-vue3-admin\backend\dvadmin\utils
,打开文件import_export_mixin.py
。找到import_data()
方法。该方法会调用import_export.py
中的import_to_data()
方法,将excel数据转换为字典列表。
打开EXCEL导入模板文件,设置单元格格式为日期。如下所示
经检查,import_to_data()
方法会将该日期识别为datetiem.datetime
类型,而不是models中定义的datetime.date
类型,所以报错。
解决方法:
在import_export.py
中的import_to_data()
方法,增加下面语句。
python
for index, item in enumerate(field_data.items()): # 遍历每一列
items = list(item)
key = items[0]
values = items[1]
value_type = "str"
if isinstance(values, dict):
value_type = values.get("type", "str")
cell_value = table.cell(row=row + 1, column=index + 2).value
# 添加这句
if isinstance(cell_value, datetime) and str(cell_value.time()) == "00:00:00":
在import_export.py
中的import_to_data()
方法,修改最后的语句 return tables
python
# 删除tables中的空字典
# return tables
data = [i for i in tables if len(i) != 0]
return data
导出失败,点击无反应
错误描述:查看后端日志,提示如下
sh
[2024-09-18 17:31:08][dvadmin.utils.exception.CustomExceptionHandler():68] [ERROR] Traceback (most recent call
last):
File "E:\python_workspace\django\dvadmin\venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "E:\python_workspace\django\dvadmin\django-vue3-admin\backend\dvadmin\utils\import_export_mixin.py", line 335, in export_data
assert self.export_field_label, (
AssertionError: 'CrudDemoModelViewSet' 请配置对应的导出模板字段。
Traceback (most recent call last):
File "E:\python_workspace\django\dvadmin\venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "E:\python_workspace\django\dvadmin\django-vue3-admin\backend\dvadmin\utils\import_export_mixin.py", line 335, in export_data
assert self.export_field_label, (
AssertionError: 'CrudDemoModelViewSet' 请配置对应的导出模板字段。
错误分析:经检查,后端文件django-vue3-admin\backend\my_demo\views.py
中的export_field_label
误写为export_field_dict
解决方法:后端文件django-vue3-admin\backend\my_demo\views.py
,填写正确的export_field_label
python
# 导出配置
export_field_label = {
"goods": "商品",
"inventory": "库存量",
"goods_price": "商品价格",
"purchase_goods_date": "进货日期",
}
参考资料
TIP
有任何疑问,欢迎在技术交流区留下您的见解,一起交流成长!