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 等可獲取相關技術文章和資料,同時有任何問題均可以在公衆號後臺留言~