Skip to content

导入功能

上一章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:ExportPOST/api/CrudDemoModelViewSet/export_data/
2导入CrudDemoModelViewSet:ImportPOST/api/CrudDemoModelViewSet/import_data/

image-20240913153743092

测试导入功能

退出再重新用超级管理员登录系统,点击菜单:商品管理--商品信息,点击导入--下载导入模板。

image-20240913154059204

在下载的EXCEL模板中,填写数据,然后上传--确定。注意:

  • 日期字段:设置单元格格式--日期--类型选择2001/3/7 image-20240917174005826
  • 不要填写其它无关数据

导出功能

开发后端

编写序列化器

进入目录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:ExportPOST/api/CrudDemoModelViewSet/export_data/
2导入CrudDemoModelViewSet:ImportPOST/api/CrudDemoModelViewSet/import_data/

image-20240913153743092

测试导出功能

退出再重新用超级管理员登录系统,点击菜单:商品管理--商品信息,点击导出--另存为。

image-20240918174252412

排错指南

导入失败,日期格式错误

错误描述:测试导入功能失败,提示:【进货日期:期望为日期,获得的是日期时间。: api/CrudDemoModelViewSet/import_data/】

image-20240915162601213

错误分析:

进入目录django-vue3-admin\backend\dvadmin\utils,打开文件import_export_mixin.py。找到import_data()方法。该方法会调用import_export.py中的import_to_data()方法,将excel数据转换为字典列表。

打开EXCEL导入模板文件,设置单元格格式为日期。如下所示image-20240917174005826

经检查,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

有任何疑问,欢迎在技术交流区留下您的见解,一起交流成长!