入門

例えば、シンプルな書籍アプリを使用します。ここに model.py があります:

# app/models.py

class Author(models.Model):
    name = models.CharField(max_length=100)

    def __unicode__(self):
        return self.name


class Category(models.Model):
    name = models.CharField(max_length=100)

    def __unicode__(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 __unicode__(self):
        return self.name

インポート・エクスポートのリソースを作成

Book モデルに django-import-export を統合するために、 admin.pyModelResource を作成し、このリソースをどのようにインポートまたはエクスポート出来るようにするか記述します:

# app/admin.py

from import_export import resources
from core.models import Book

class BookResource(resources.ModelResource):

    class Meta:
        model = Book

データのエクスポート

ModelResource クラスを定義したので書籍をエクスポートすることが出来ます:

>>> from app.admin import BookResource
>>> dataset = BookResource().export()
>>> print dataset.csv
id,name,author,author_email,imported,published,price,categories
2,Some book,1,,0,2012-12-05,8.85,1

リソースオプションのカスタマイズ

デフォルトで ModelResource はモデルフィールドをイントロスペクトし、各フィールドに適切な Widget を持つ:class:~import_export.fields.Field 属性を作成します。

インポート・エクスポートリソースに含めるモデルフィールドを変更するには、 field オプションをホワイトリストに追加します:

class BookResource(resources.ModelResource):

    class Meta:
        model = Book
        fields = ('id', 'name', 'price',)

除外したい場合は、 eclude オプションにブラックリストを追加します:

class BookResource(resources.ModelResource):

    class Meta:
        model = Book
        exclude = ('imported', )

エクスポートするフィールドの順序を明示的にするには、 export_order オプションを使用して設定します:

class BookResource(resources.ModelResource):

    class Meta:
        model = Book
        fields = ('id', 'name', 'author', 'price',)
        export_order = ('id', 'price', 'author', 'name')

オブジェクトを識別するデフォルトのフィールドは id です。インポート時に id として使用するフィールドをオプションで設定出来ます:

class BookResource(resources.ModelResource):

    class Meta:
        model = Book
        import_id_fields = ('isbn',)
        fields = ('isbn', 'name', 'author', 'price',)

ModelResource フィールドを定義する時、モデルの関連に従うことが可能です:

class BookResource(resources.ModelResource):

    class Meta:
        model = Book
        fields = ('author__name',)

注釈

次の関連フィールドは読み込み専用の field に設定します。つまり、データのインポート時にこのフィールドはスキップされます。

変更が検出されなくても、デフォルトではすべてのレコードがインポートされます。これは skip_unchanged オプションを設定することで変更出来ます。また、 report_skipped` オプションはスキップされたレコードがインポートの Result オブジェクトに表示されるかを制御し、もしadminを使っていたらスキップされたレコードがインポートプレビューページに表示するかどうかを制御します:

class BookResource(resources.ModelResource):

    class Meta:
        model = Book
        skip_unchanged = True
        report_skipped = False
        fields = ('id', 'name', 'price',)

参考

リソース

フィールドの宣言

オプションを変更してリソースフィールドを上書きすることは可能です:

from import_export import fields

class BookResource(resources.ModelResource):
    published = fields.Field(column_name='published_date')

    class Meta:
        model = Book

ターゲットモデルに存在しない他のフィールを追加することが出来ます:

from import_export import fields

class BookResource(resources.ModelResource):
    myfield = fields.Field(column_name='myfield')

    class Meta:
        model = Book

参考

フィールド
利用可能なフィールドタイプとオプション。

高度なデータ操作

すべてのデータをオブジェクト/モデル属性から簡単に抽出することは出来ません。複雑なデータモデルを処理されたデータ構造(一般的にはよりシンプル)に変換するには、 dehydrate_<fieldname> メソッドを定義する必要があります:

from import_export import fields

class BookResource(resources.ModelResource):
    full_title = fields.Field()

    class Meta:
        model = Book

    def dehydrate_full_title(self, book):
        return '%s by %s' % (book.name, book.author.name)

ウィジェットのカスタマイズ

ModelResource は、与えられたフィールドタイプのデフォルトウィジェットでフィールドを作成します。もしウィジェットを異なる引数で初期化する必要がある場合、 widgets 辞書を設定します。

このサンプルウィジェットでは、 published フィールドが異なる日付形式を使うよう上書きされています。この形式はインポートとエクスポートリソースの両方で使用されます。

class BookResource(resources.ModelResource):

    class Meta:
        model = Book
        widgets = {
                'published': {'format': '%d.%m.%Y'},
                }

参考

ウィジェット
利用可能なウィジェットタイプとオプション。

データのインポート

いくつかのデータをインポートしましょう!

1
2
3
4
5
6
7
8
9
>>> import tablib
>>> from import_export import resources
>>> from core.models import Book
>>> book_resource = resources.modelresource_factory(model=Book)()
>>> dataset = tablib.Dataset(['', 'New book'], headers=['id', 'name'])
>>> result = book_resource.import_data(dataset, dry_run=True)
>>> print result.has_errors()
False
>>> result = book_resource.import_data(dataset, dry_run=False)

4行目では、 modelresource_factory() を使用してデフォルトの ModelResource を作成します。この方法で作成されたModelResourceクラスは、 インポート・エクスポートのリソースを作成 セクションの例で示されているものと同じです。

5行目では、 idname および一つの書籍エントリを持つ Dataset が作成されます。主キーフィールド(この場合は、 id )のフィールドは、常に存在する必要があります。

コードの残りの部分では、最初に import_data()dry_run を使ってインポートして、エラーチェックをしてから実際にデータをインポートします。

参考

インポートデータのワークフロー
インポートのワークフローとそのカスタマイズオプションの詳細について。

データの削除

インポート中にオブジェクトを削除するには、 Resource クラスに for_delete() を実装します。

以下は、データセットに delete フィールドが存在するリソースの例です。このリソースを使用してインポートすると、 delete カラムが 1 にセットされている行のモデルインスタンスが削除されます:

class BookResource(resources.ModelResource):
    delete = fields.Field(widget=widgets.BooleanWidget())

    def for_delete(self, row, instance):
        return self.fields['delete'].clean(row)

    class Meta:
        model = Book

シグナル

インポート・エクスポートのワークフローをフックするため、 post_importpost_export に接続出来ます:

from django.dispatch import receiver from import_export.signals import post_import, post_export

@receiver(post_import, dispatch_uid=』balabala…』) def _post_import(model, **kwargs):

# model is the actual model instance which after import pass

@receiver(post_export, dispatch_uid=』balabala…』) def _post_export(model, **kwargs):

# model is the actual model instance which after export pass

Adminとの統合

リストフィルタによるエクスポート

adminの統合は、 ImportExportModelAdmin または利用なミックスイン(ImportMixin, ExportMixin, ImportExportMixin) のサブクラス化で実現されます:

# app/admin.py
from import_export.admin import ImportExportModelAdmin

class BookAdmin(ImportExportModelAdmin):
    resource_class = BookResource
_images/django-import-export-change.png

インポートとエクスポートボタンを持つ変更ビューのスクリーンショット。

_images/django-import-export-import.png

インポートビューのスクリーンショット。

_images/django-import-export-import-confirm.png

インポート確認ビューのスクリーンショット。

adminアクションによるエクスポート

データをエクスポートするもう一つのアプローチは、adminアクションとしてエクスポートを実装する ImportExportActionModelAdmin をサブクラス化することです。結果として、変更リストページで選択されたオブジェクトのリストをエクスポートすることが出来ます:

# app/admin.py
from import_export.admin import ImportExportActionModelAdmin

class BookAdmin(ImportExportActionModelAdmin):
    pass
_images/django-import-export-action.png

adminアクションのインポートとエクスポートを持つ変更ビューのスクリーンショット。

参考

Admin
利用可能なミックスインとオプション。