Django以快速开发闻名,可是若是处理数据的导出导入还须要本身写脚本,那就有违“Python之禅”了……html
并且导数据一般须要不一样的格式,Excel、csv、json等,每种格式的数据就要写一个脚本太麻烦了,这时直接祭出django-import-export这个神器,官方一句话介绍:django-import-export is a Django application and library for importing and exporting data with included admin integration.java
特色:python
反正好用就完事了,下面我开始上使用介绍linux
pip install django-import-export
而后得添加到INSTALLED_APPS
里面android
# settings.py INSTALLED_APPS = ( ... 'import_export', )
不得不说,这很Djangogit
Resource的写法与Model、Form相似,就是定义你要导入或者导出的数据格式。github
这里借用一下官方的例子,首先上Model代码数据库
class Author(models.Model): name = models.CharField(max_length=100) def __str__(self): return self.name class Category(models.Model): name = models.CharField(max_length=100) def __str__(self): return self.name class Book(models.Model): name = models.CharField('Book name', max_length=100) author = models.ForeignKey(Author, blank=True, null=True) author_email = models.EmailField('Author email', max_length=75, blank=True) imported = models.BooleanField(default=False) published = models.DateField('Published', blank=True, null=True) price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True) categories = models.ManyToManyField(Category, blank=True) def __str__(self): return self.name
如今要导入数据到Book表,开始编写咱们的Resource,我是在app所在目录下建立一个resource.py
来放Resource定义代码django
from import_export import resources from core.models import Book class BookResource(resources.ModelResource): class Meta: model = Book
这样一个最简单的Resource就定义好了,可使用代码进行数据导出,但如今我不想用,由于我要把导出功能放在DjangoAdmin后台里面json
修改admin.py
,修改的地方就是把咱们定义的Admin类本来继承的admin.ModelAdmin
改为ImportExportModelAdmin
,代码以下
from .models import Book from import_export.admin import ImportExportModelAdmin class BookAdmin(ImportExportModelAdmin): resource_class = BookResource admin.site.register(Book, BookAdmin)
这样就能够在后台看到有导出和导入的按钮了。
只想导出不想有导入功能咋办,改为这样:
from .models import Book from django.contrib import admin from import_export.admin import ExportMixin class BookAdmin(ExportMixin, admin.ModelAdmin): resource_class = BookResource admin.site.register(Book, BookAdmin)
只导入不导出也行,把ExportMixin
换成ImportMixin
就行。
固然这些只是最简单的用法,实际需求是比较复杂的,接下来我列举几个我用到的。
要导入的数据(Excel、csv这些),可能字段顺序和Model定义的字段顺序不同,这时就得在Resource里手动调整一下
因为我本身写的代码涉及到公司业务,因此继续借用官网的代码例子:
class BookResource(resources.ModelResource): class Meta: model = Book fields = ('id', 'name', 'author', 'price',) export_order = ('id', 'price', 'author', 'name')
其中export_order
是导出的字段顺序,fields
是指定哪些字段须要导入,导入的时候是根据数据文件的列名来导入的,因此Excel、csv或者json文件里面字段名就要和fields
里的或者是Model里的字段名同样,才能够进行导入。
顾名思义,就拿那个Book
的模型来讲,Model定义里没有指定主键,那Django会安排一个默认的主键字段id,可是咱们导入数据的Excel里应该是没有这个id的,这样就无法导入,因而咱们得把这个id字段排除了,很简单,在Meta
里这行代码
exclude = ['id']
也是顾名思义,假如咱们数据库原本就有不少书了,如今须要经过导入一个Excel来更新这批书的数据,那我就得把找一个字段来设置成主键字段,否则导入就变成新增了,跟前面提到的同样,通常Excel里不会有数据库主键id的,因此这里我选择了书名(假设咱们这是一个小书店,书名都不重复的)
代码:
import_id_fields = ['name']
按照前文配置导出来的Excel,列名全是字段名,也就是英文的,但我想中文列名啊,也能够,就是须要花一点代码(这里就再也不借用官网代码了,我本身手打)
from import_export.fields import Field class BookResource(resources.ModelResource): id = Field(attribute='id', column_name='编号') name = Field(attribute='name', column_name='书籍名称') class Meta: model = Book export_order = ('id', 'name', 'author', 'price',)
这样就实现了,so easy。其中Field
里的attribute
是指这个字段对应Model里的属性也就是字段名,column_name
顾名思义就是列名。
而后可能有同窗要问,Model里已经给每一个字段都设置了verbose_name
了,这里还要在column_name
里再写一遍是否是重复了?
别急,也很简单,既然有verbose_name
,那直接拿来用就完事啦~
name = Field(attribute='name', column_name=Book.name.field.verbose_name)
这就完事美滋滋啦~
最后一个,若是想在导出的数据中加入Model里不存在的字段,行不?
那确定行啊,也很简单,直接代码:
from import_export.fields import Field class BookResource(resources.ModelResource): id = Field(attribute='id', column_name='编号') name = Field(attribute='name', column_name='书籍名称') new_field = Field(column_name='一个新的字段') class Meta: model = Book export_order = ('id', 'name', 'author', 'price', 'new_field') @staticmethod def dehydrate_new_field(instance: Book): return '新字段内容'
能够看到就是先在export_order
里添加这个字段,而后再加这行new_field = Field(column_name='一个新的字段')
,而后下面加一个类方法来实现生成这个字段的值,这个方法是以dehydrate_字段名
这样的格式来命名的,具体能够根据实际来写。
django-import-export 这个插件还有不少其余的功能,不过现阶段已经知足了个人工做须要,因此我也没有再去深刻,还有什么功能须要能够直接翻文档吧。
目前我用到的仍是以导出为主,导入的就是更新和新增这一块,没多少花样,若是接下来遇到其余新的需求,我会再更新一篇文章来介绍更新这个插件的功能~
程序设计实验室专一于互联网热门新技术探索与团队敏捷开发实践,在公众号「程序设计实验室」后台回复 linux、flutter、c#、netcore、android、kotlin、java、python 等可获取相关技术文章和资料,同时有任何问题均可以在公众号后台留言~