Python Version 3 Logo

[Django]管理者サイトで CSV ファイルのインポート・エクスポートを行う

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.pyINSTALLED_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
...

上記のコードを追加するとユーザモデル一覧でインポート・エクスポート機能が利用できるようになります。

Django Import Export 1

動作確認

CSV ファイルをエクスポートしてみます。
画面の「エクスポート」をクリックします。

Django Import Export 2

すると、フォーマット選択画面へ移動するので、「 CSV 」を選択し、「確定」ボタンをクリックします。

Django Import Export 3

CSV` ファイルがエクスポートされました!
ちなみに、 CSV ファイル以外にも「 xlsx 」や「 json 」などの出力フォーマットも選択できます。

CSV ファイルのインポートも試してみます。
画面の「インポート」をクリックします。

Django Import Export 4

インポートファイル選択画面へ移動するので、ファイルを選択し、フォーマットに「 CSV 」を選択し、「確定」ボタンをクリックします。

Django Import Export 5

プレビュー画面が表示されるので、インポートの内容に問題がなければ「インポート実行」ボタンをクリックします。

Django Import Export 6

インポート機能の方でも 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):

Django Import Export 7

エクスポートのみ行いたい場合、「 ImportExportMixin 」ではなく、「 ExportMixin 」を利用することでエクスポート機能のみ使用できます。

from import_export.admin import ExportMixin

class UserAdmin(ExportMixin, admin.ModelAdmin):

Django Import Export 8

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から確認できますので、参考にしてもらえればと思います。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です