管理画面からデータを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エクスポート機能を追加できる。