前言

之前写过两篇跟这个插件有关的文章,可以回顾一下:

最近有个朋友留言问我一个关于django-import-export插件的问题

为了形象表达这个问题,我举个书籍管理的例子来描述一下

数据库表

id name price
1 book1 10
2 book2 20
3 book3 30

要导入的Excel表

id name price tax
4 book4 40 5
5 book5 50 6
6 book6 60 7

可以看到,Excel里每本书都有价格和税两个属性,但数据库只有价格一个属性

导入的时候,需要把每本书的价格+税,才是要存入数据的最终价格

在以前,这种问题场景我会建议直接用pandas来处理数据然后导入,django-import-export插件只用来做数据导出,因为它的文档很简陋,给的例子很难解决实际问题,往往某个需求用pandas手动处理只需要很少时间,用这个插件还得去啃源码和简陋的文档,效率太低了。

不过本着折腾的精神,还是来研究一下这个用django-import-export到底能不能实现这个功能。(结果当然是可以的,不然也没有这篇文章了)

分析

首先是看官网文档,有一个节点叫import data workflow

地址:https://django-import-export.readthedocs.io/en/latest/import_workflow.html

import_data(dataset, dry_run=False, raise_errors=False)

The import_data() method of Resource is responsible for importing data from a given dataset.

dataset is required and expected to be a tablib.Dataset with a header row.

dry_run is a Boolean which determines if changes to the database are made or if the import is only simulated. It defaults to False.

raise_errors is a Boolean. If True, import should raise errors. The default is False, which means that eventual errors and traceback will be saved in Result instance.

根据文档,在导入数据的时候,我们可以通过import_data这个hook来对要导入的数据进行处理

然后这个hook有个参数,dataset,这个是tablib的东西

关于这个tablib,我之前没用过,查了一下,是requests作者做的库,那想来应该不会差

官网文档是:https://tablib.readthedocs.io/en/stable/tutorial.html

写代码

直接把官方的代码例子拿来用

代码仓库:https://github.com/django-import-export/django-import-export

同样是这个书籍管理的

Models代码

来看看它的model设计

class Book(models.Model):
name = models.CharField('Book name', max_length=100)
author = models.ForeignKey(Author, blank=True, null=True, on_delete=models.CASCADE)
author_email = models.EmailField('Author email', max_length=75, blank=True)
imported = models.BooleanField(default=False)
published = models.DateField('Published', blank=True, null=True)
published_time = models.TimeField('Time published', blank=True, null=True)
price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
added = models.DateTimeField(blank=True, null=True) categories = models.ManyToManyField(Category, blank=True) def __str__(self):
return self.name

很多字段

要导入的数据

依然是官方提供的,各种格式都有,我选csv的,比较方便

id,name,author_email
1,Some book,test@example.com

转换成表格长这样

id name author_email
1 Some book test@example.com

可以看到字段比model定义的少很多

我们要在导入的时候,给dataset加上价格(price)属性

Resources代码

这是原本的代码

class BookResource(ModelResource):
class Meta:
model = Book def for_delete(self, row, instance):
return self.fields['name'].clean(row) == '' return super(BookResource, self).import_data(
dataset, dry_run, raise_errors, use_transactions,
collect_failed_rows, rollback_on_validation_errors, **kwargs

现在我们要加一个hook来处理导入的数据

代码如下

def import_data(self, dataset: tablib.Dataset, dry_run=False, raise_errors=False,
use_transactions=None, collect_failed_rows=False,
rollback_on_validation_errors=False, **kwargs):
cols = []
for item in dataset['id']:
cols.append(int(item) * 99) dataset.append_col(cols, header='price')
print(dataset) return super(BookResource, self).import_data(
dataset, dry_run, raise_errors, use_transactions,
collect_failed_rows, rollback_on_validation_errors, **kwargs
)

使用DataSetappend_col方法来添加一个新的列

关于这个DataSet的更多操作请参考Tablib的文档

这部分的具体操作可以根据实际需求来做修改,这里我直接简单粗暴的把ID乘以99

处理完DataSet之后记得要执行父类的import_data,完成数据导入的操作。

效果

在admin后台执行导入,可以得到以下的结果

可以看到price属性变成99

ID NAME AUTHOR AUTHOR_EMAIL IMPORTED PUBLISHED PUBLISHED_TIME PRICE ADDED CATEGORIES
New 1 Some book test@example.com 0 99

就OK了,搞定~

其实还挺简单的,只是官方文档太简陋了,连个例子的没有,只能自己摸索一下

参考资料

虽然前面都有链接,这里再总结一下吧

Django-Import-Export插件控制数据导入流程的更多相关文章

  1. Django import / export实现数据库导入导出

    使用django-import-export库,导入导出数据,支持csv.xls.json.html等格式 官网:http://django-import-export.readthedocs.io/ ...

  2. sqlite3 import/export db sqlite 导入 导出 数据

    export: $ sqlite3 xxx.db3 > .output xxx.sql >.dump > .q import: $ sqlite3 xxx.db3 > .rea ...

  3. [转] ES6 import/export:模块导入导出方式

    export导出语法 // default exports export default 42; export default {}; export default []; export defaul ...

  4. django开发环境搭建(参考流程)

    django开发环境搭建(参考流程) 2013-08-08 01:09:06 分类: LINUX 原文地址:django开发环境搭建(参考流程) 作者:bailiangcn 对于一个初学者,在实际的开 ...

  5. 总账:日记账导入流程(文档 ID 1591640.1)

    文档内容   概要   历史记录   详细信息   GL_INTERFACE_CONTROL   GL_INTERFACE_HISTORY   GL_IMPORT_REFERENCES   摘要   ...

  6. 前端 高级 (二十五)vue2.0项目实战一 配置简要说明、代码简要说明、Import/Export、轮播和列表例子

    一.启动服务自动打开浏览器运行 二.配置简要说明 1.node_modules 安装好的依赖文件,中间件等,所在位置 2.package.jason 配置当前项目要安装的中间件和依赖文件 { &quo ...

  7. require/exports 与 import/export 的区别?

    文章作者:寸志链接:https://www.zhihu.com/question/56820346/answer/150724784来源:知乎 遵循的模块化规范不一样 模块化规范:即为 JavaScr ...

  8. 探讨ES6的import export default 和CommonJS的require module.exports

    今天来扒一扒在node和ES6中的module,主要是为了区分node和ES6中的不同意义,避免概念上的混淆,同时也分享一下,自己在这个坑里获得的心得. 在ES6之前 模块的概念是在ES6发布之前就出 ...

  9. django admin后台插件:django-suit入门

    去年9月底开始用django来做公司内部项目,开始对django有了一些了解,感觉django真的蛮强大的(也有很多人推荐flask,将来有空的话我会试试).今天的话只是介绍一个小东西,django管 ...

随机推荐

  1. ShardingSphere 异构迁移最佳实践:将3.5亿量级的顾客系统 RTO 减少60倍

    Apache ShardingSphere 助力当当 3.5 亿用户量级顾客系统重构,由 PHP+SQL Server 技术栈无缝转型为 Java+ShardingSphere+MySQL,性能.可用 ...

  2. H2-Table CATALOGS not found

    在使用 IntelliJ IDEA 2021.1.3 版本,使用默认配置连接 H2 数据库的时候,出现下面错误,项目里 H2 使用的版本为 2.0.202 . [42S02][42102] org.h ...

  3. 基于JavaFX图形界面演示的迷宫创建与路径寻找

    事情的起因是收到了一位网友的请求,他的java课设需要设计实现迷宫相关的程序--如标题概括. 我这边不方便透露相关信息,就只把任务要求写出来. 演示视频指路: 视频过审后就更新链接 完整代码链接: 网 ...

  4. rhel安装程序

    Linux下软件分类     rpm软件包,包管理器 yum     deb软件包,包管理器 apt     源代码软件包            一般为".tar.gz".&quo ...

  5. docker删除镜像报错 Error response from daemon: conflict: unable to delete f73fe6298efc (cannot be forced) - image has dependent child images

    方法1 docker rmi 镜像ID 方法2 docker rmi -f 镜像ID 方法3 docker rmi 镜像仓库名:tag

  6. NC24017 [USACO 2016 Jan S]Angry Cows

    NC24017 [USACO 2016 Jan S]Angry Cows 题目 题目描述 Bessie the cow has designed what she thinks will be the ...

  7. 跨模态语义关联对齐检索-图像文本匹配(Image-Text Matching)

    论文介绍:Negative-Aware Attention Framework for Image-Text Matching (基于负感知注意力的图文匹配,CVPR2022) 代码主页:https: ...

  8. 字节输入流_InputStream类&FileInputStream类介绍和字节输入流读取字节数据

    java.io.InputStream:字节输入流 此抽象类是表示字节输入流的所有类的超类 定义了所有子类共性的方法: int read()从输入流中读取数据的下一个字节 int read(byte[ ...

  9. Solution -「原创」Destiny

    题目背景 题目背景与题目描述无关.签到愉快. 「冷」 他半靠在床沿,一缕感伤在透亮的眼眸间荡漾. 冷见惆怅而四散逃去.经历嘈杂喧嚣,感官早已麻木.冷又见空洞而乘隙而入.从里向外,这不是感官的范畴. 他 ...

  10. CD 从抓轨到搭建流媒体服务器 —— 以《月临寐乡》为例

    2022-07-19 v0.0.1 由于某些原因,进了 Static World 的群并入坑了 月临寐乡 ,梦开始了.作为幻想乡的新人,也算是有了自己喜欢的社团.但是更细节的东西,狐狐脑子一下子塞不下 ...