入門¶
例えば、シンプルな書籍アプリを使用します。ここに 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.py
に ModelResource
を作成し、このリソースをどのようにインポートまたはエクスポート出来るようにするか記述します:
# 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行目では、 id
と name
および一つの書籍エントリを持つ 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_import
、 post_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
adminアクションによるエクスポート¶
データをエクスポートするもう一つのアプローチは、adminアクションとしてエクスポートを実装する ImportExportActionModelAdmin
をサブクラス化することです。結果として、変更リストページで選択されたオブジェクトのリストをエクスポートすることが出来ます:
# app/admin.py
from import_export.admin import ImportExportActionModelAdmin
class BookAdmin(ImportExportActionModelAdmin):
pass
参考
- Admin
- 利用可能なミックスインとオプション。