Django数据导入导出神器django-import-export使用教程

顾名思义,django-import-export是一个用于处理导入和导出数据的库。它支持多种格式,包括xls、csv、json、yaml以及tablib支持的所有其他格式。它还可以轻松与Django管理后台集成,使用起来非常方便。

安装插件

使用PIP安装

pip install django-import-export

更新settings.py:

INSTALLED_APPS = (
    ...
    'import_export',
)

还有一个可选的配置,我通常这样添加:

IMPORT_EXPORT_USE_TRANSACTIONS = True

默认值为False。它确定库是否会在数据导入中使用数据库事务,以确保安全。

编写资源Resources

django-import-export库使用Resource的概念,它的类定义非常类似于Django处理模型表单和管理类的方式。

在文档中,作者建议将与资源相关的代码放在admin.py文件。但是,如果实现与Django admin没有关系,我通常更喜欢在app文件夹里创建一个名为resources.py。

models.py

from django.db import models
class Person(models.Model):    name = models.CharField(max_length=30)    email = models.EmailField(blank=True)    birth_date = models.DateField()    location = models.CharField(max_length=100, blank=True)

resources.py

from import_export import resourcesfrom .models import Person
class PersonResource(resources.ModelResource):    class Meta:        model = Person

这是最简单的定义。您可以将几个配置传递给元类,fieldsexclude

导出数据

导出数据到CSV

from .resources import PersonResource
person_resource = PersonResource()
dataset = person_resource.export()
dataset.csv
id,name,email,birth_date,location
1,John,john@doe.com,2016-08-11,Helsinki
2,Peter,peter@example.com,2016-08-11,Helsinki
3,Maria,maria@gmail.com,2016-08-11,Barcelona
4,Vitor,vitor@freitas.com,2016-08-11,Oulu
5,Erica,erica@gmail.com,2016-08-11,Oulu

导出数据到JSON

dataset.json
[
  {"id"1"name""John""email""john@doe.com""birth_date""2016-08-11""location""Helsinki"},
  {"id"2"name""Peter""email""peter@example.com""birth_date""2016-08-11""location""Helsinki"},
  {"id"3"name""Maria""email""maria@gmail.com""birth_date""2016-08-11""location""Barcelona"},
  {"id"4"name""Vitor""email""vitor@freitas.com""birth_date""2016-08-11""location""Oulu"},
  {"id"5"name""Erica""email""erica@gmail.com""birth_date""2016-08-11""location""Oulu"}
]

导出数据到YAML

dataset.yaml
- {birth_date'2016-08-11', email: john@doe.com, id: 1, location: Helsinki, name: John}
- {birth_date'2016-08-11', email: peter@example.com, id: 2, location: Helsinki, name: Peter}
- {birth_date'2016-08-11', email: maria@gmail.com, id: 3, location: Barcelona, name: Maria}
- {birth_date'2016-08-11', email: vitor@freitas.com, id: 4, location: Oulu, name: Vitor}
- {birth_date'2016-08-11', email: erica@gmail.com, id: 5, location: Oulu, name: Erica}

过滤数据

from .resources import PersonResource
from .models import Person
person_resource = PersonResource()
queryset = Person.objects.filter(location='Helsinki')
dataset = person_resource.export(queryset)
dataset.yaml
- {birth_date'2016-08-11', email: john@doe.com, id: 1, location: Helsinki, name: John}
- {birth_date'2016-08-11', email: peter@example.com, id: 2, location: Helsinki, name: Peter}

导出到CSV视图

from django.http import HttpResponsefrom .resources import PersonResource
def export(request):    person_resource = PersonResource()    dataset = person_resource.export()    response = HttpResponse(dataset.csv, content_type='text/csv')    response['Content-Disposition'] = 'attachment; filename="persons.csv"'    return response

导出到Excel视图

from django.http import HttpResponsefrom .resources import PersonResource
def export(request):    person_resource = PersonResource()    dataset = person_resource.export()    response = HttpResponse(dataset.xls, content_type='application/vnd.ms-excel')    response['Content-Disposition'] = 'attachment; filename="persons.xls"'    return response

导入数据

查看new_persons.csv的数据

name,email,birth_date,location,id
Jessica,jessica@jones.com,2016-08-11,New York,
Mikko,mikko@suomi.com,2016-08-11,Jyväskyla,

id必须存在,因为它是主键。但是它会生成,所以我们不需要指定值。

import.html

{% extends 'base.html' %}
{% block content %}
  <form method="post" enctype="multipart/form-data">
    {% csrf_token %}
    <input type="file" name="myfile">
    <button type="submit">Upload</button>
  </form>
{% endblock %}

views.py

from tablib import Datasetdef simple_upload(request):    if request.method == 'POST':        person_resource = PersonResource()        dataset = Dataset()        new_persons = request.FILES['myfile']        imported_data = dataset.load(new_persons.read())        result = person_resource.import_data(dataset, dry_run=True)  # Test the data impor        if not result.has_errors():            person_resource.import_data(dataset, dry_run=False)  # Actually import now     return render(request, 'core/simple_upload.html')

Django后台管理集成

在admin.py里使用ImportExportModelAdmin,而不是ModelAdmin

from import_export.admin import ImportExportModelAdmin
from django.contrib import admin

from .models import Person

@admin.register(Person)
class PersonAdmin(ImportExportModelAdmin):
   pass

添加之后刷新页面你就会看到导入和导出按钮。

Django数据导入导出神器django-import-export使用教程

在导入现有项目时,导入功能具有良好的差异性:

Django数据导入导出神器django-import-export使用教程

这是一个强大的Django库,你可以用它做更多的事情。比如只想有导出功能,可以使用ExportMixin。

from .models import Personfrom django.contrib import adminfrom import_export.admin import ExportMixin
class PersonAdmin(ExportMixin, admin.ModelAdmin):    resource_class = PersonResource
admin.site.register(Person, BookAdmin)

详细文档地址:https://django-import-export.readthedocs.io/en/latest/

文章来源:Django中文网 作者:夜之舞。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注