Django
の管理者サイトでCSV
ファイルのインポート・エクスポートを行う方法を説明したいと思います。
「django-import-export
」というプラグインを使用してCSVのインポート・エクスポート機能を実装していきます。
前提条件
- Python:3.6.2
- Django:3.0.5
- django-import-export:2.5.0
こちらのソースをベースに実装していきたいと思います。
プラグインのインストール
まず、「django-import-export
」プラグインをインストールします。
$ pip install django-import-export
settings.py
のINSTALLED_APPS
にインストールしたプラグインを追加します。
INSTALLED_APPS = [
...
'import_export',
...
]
admin.pyへ実装
accounts
アプリケーションのadmin.py
へインポート・エクスポート機能を実装していきます。
...
from import_export import resources
from import_export.admin import ImportExportMixin
...
class UserResource(resources.ModelResource):
class Meta:
model = User
@admin.register(User)
class UserAdmin(ImportExportMixin, admin.ModelAdmin):
...
resource_class = UserResource
...
上記のコードを追加するとユーザモデル一覧でインポート・エクスポート機能が利用できるようになります。
動作確認
CSV
ファイルをエクスポートしてみます。
画面の「エクスポート」をクリックします。
すると、フォーマット選択画面へ移動するので、「CSV
」を選択し、「確定」ボタンをクリックします。
CSV
ファイルがエクスポートされました!
ちなみに、CSV
以外にも「xlsx
」や「json
」などの出力フォーマットも選択できます。
CSV
ファイルをインポートしてみます。
画面の「インポート」をクリックします。
インポートファイル選択画面へ移動するので、ファイルを選択し、フォーマットに「CSV
」を選択し、「確定」ボタンをクリックします。
プレビュー画面が表示されるので、インポートの内容に問題がなければ「インポート実行」ボタンをクリックします。
インポート機能の方でもCSV
以外に「xlsx
」や「json
」などをフォーマットに指定できます。
小技いろいろ
フォーマットをCSVで固定する
フォーマットがいろいろ選べるのはありがたいのですが、実際の開発でいろいろなフォーマットでデータの入出力ができてしまうと、エラー発生時の対応や使用方法の説明など工数が余計にかかってしまう可能性があるので、できればフォーマットは1つで固定したいといった場合、下記のコードを追加すればフォーマットをCSV
のみに固定できます。
...
from import_export.formats import base_formats
@admin.register(User)
class UserAdmin(ImportExportMixin, admin.ModelAdmin):
...
formats = [base_formats.CSV]
...
これでフォーマット選択時にCSV
しか選べないようにできます。
インポートのみエクスポートのみ行いたい
インポートのみ行いたい場合、「ImportExportMixin
」ではなく、「ImportMixin
」を利用することでインポート機能のみ使用できます。
from import_export.admin import ImportMixin
class UserAdmin(ImportMixin, admin.ModelAdmin):
エクスポートのみ行いたい場合、「ImportExportMixin
」ではなく、「ExportMixin
」を利用することでエクスポート機能のみ使用できます。
from import_export.admin import ExportMixin
class UserAdmin(ExportMixin, admin.ModelAdmin):
CSVのヘッダーを出力しない
場合によってはCSV
ファイルのヘッダー部を出力したくないことがあると思います。そういった場合は下記のように実装すればヘッダー部を出力せずにCSV
ファイルを出力することができます。
class UserResource(resources.ModelResource):
def after_export(self, queryset, data, *args, **kwargs):
data.headers = []
カスタムフィールドを出力する
本来ならモデルに基づくデータを出力するんですが、カスタムフィールドを作成してデータを出力することも可能です。
from import_export import fields
class UserResource(resources.ModelResource):
custom_field = fields.Field(column_name='カスタムフィールド')
def dehydrate_custom_field(self, data: User):
return '{0:%Y/%-m/%-d}'.format(data.date_joined)
class Meta:
model = User
fields = ['custom_field']
dehydrate_<fieldname>
という関数でカスタムフィールドが出力する値を設定することができます。dehydrate_
の部分はプラグインの命名規則となっているので間違いのないよう関数の定義を行いましょう。
文字コードを変更する
デフォルトだとCSV
出力時の文字コードはUTF-8
になっているんですが、これだとエクセルで開くと文字化けするので文字コードを「CP932
」に変更したいと思います。
class UserAdmin(ExportMixin, admin.ModelAdmin):
...
base_formats.CSV.CONTENT_TYPE = 'text/csv; charset=CP932'
...
「CP932
」の部分を他の文字コードに変更すれば任意の文字コードでCSV
ファイルを出力することができます。
ファイル名を変更する
デフォルトだとCSV
ファイル出力時のファイル名は「モデル名-日付.csv」となっているんですが、これも変更可能です。
class UserAdmin(ExportMixin, admin.ModelAdmin):
...
def get_export_filename(self, request, queryset, file_format):
filename = "%s.%s" % ("Sample",
file_format.get_extension())
return filename
...
こうすると、「Sample.csv
」というファイル名でCSV
ファイルが出力されます。
最後に
CSV
出力機能はシステム開発しているとかなりの頻度で実装することがあるので、今回利用した「django-import-export
」プラグインの使い方をしっかり理解しておきたいですね。
今回利用したソースコードは下記URLから確認できますので、参考にしてもらえればと思います。
コメント