Django AdminでCSVエクスポート機能を実装する方法

管理画面からデータをCSV形式でエクスポートする

Djangoの管理画面において、モデルオブジェクトをCSV形式でエクスポートしたいケースはよくある。ここでは、ProductモデルとOrderモデルを例にとって、カスタムアクションを追加する方法を解説する。

基本的なアプローチ

DjangoのAdminアクションは特定のシグネチャを持つメソッドとして実装する。シグネチャはdef admin_action(self, request, queryset):のように定義し、管理モデルにメソッドとして追加する。

class SomeModelAdmin(admin.ModelAdmin):
    def my_custom_action(self, request, queryset):
        # アクションのロジックを実装
        pass

CSVエクスポートの実装

ProductAdminにCSVエクスポート機能を追加するには、まずactionsリストにアクション名を追加し、メソッドを定義する。

actions = ['export_products_csv']

def export_products_csv(self, request, queryset):
    pass

export_products_csv.short_description = "選択項目をCSV出力"

これにより、管理画面に「選択項目をCSV出力」というアクションが追加される。

完全なCSVエクスポート処理

以下のコードは、選択されたオブジェクト全てのフィールド値をCSVとして出力する。

import csv
from django.http import HttpResponse

def export_products_csv(self, request, queryset):
    model_meta = self.model._meta
    field_names = [field.name for field in model_meta.fields]
    
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename={}.csv'.format(model_meta)
    
    writer = csv.writer(response)
    writer.writerow(field_names)
    
    for obj in queryset:
        row = [getattr(obj, field) for field in field_names]
        writer.writerow(row)
    
    return response

export_products_csv.short_description = "選択項目をCSV出力"

Mixinクラスによる再利用性の向上

上記のメソッドは特定のモデルに依存していないため、複数の管理モデルで再利用可能なMixinクラスとして抽出できる。

class CsvExportMixin:
    def export_as_csv(self, request, queryset):
        model_meta = self.model._meta
        field_names = [field.name for field in model_meta.fields]
        
        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename={}.csv'.format(model_meta)
        
        writer = csv.writer(response)
        writer.writerow(field_names)
        
        for obj in queryset:
            row = [getattr(obj, field) for field in field_names]
            writer.writerow(row)
        
        return response
    
    export_as_csv.short_description = "選択項目をCSV出力"


@admin.register(Product)
class ProductAdmin(admin.ModelAdmin, CsvExportMixin):
    list_display = ('name', 'price', 'category', 'created_at')
    list_filter = ('category', 'created_at')
    actions = ['export_as_csv']


@admin.register(Order)
class OrderAdmin(admin.ModelAdmin, CsvExportMixin):
    list_display = ('order_number', 'customer', 'total_amount', 'status')
    list_filter = ('status', 'created_at')
    actions = ['export_as_csv']

この方法により、CsvExportMixinを継承するだけで любой 管理モデルにCSVエクスポート機能を追加できる。

タグ: Django csv export admin django-admin

6月6日 23:02 投稿