
目次
こんにちは。sinyです。
この記事では、DjangoでPandas(DataFrame)を活用する方法についてご紹介します。
django-pandasを利用する。
下記リンクのdjango-pandasを利用すると、Djangoのモデルクラス(テーブルに格納されているデータ)を簡単にDataFrame形式に変換することができます。
まずは、基本的な使い方を具体例で説明します。
以下のような家計簿テーブルとカテゴリテーブルを例に説明します。
class Category(models.Model):
class Meta:
#カテゴリ
verbose_name ="カテゴリ"
verbose_name_plural ="カテゴリ"
#カラム名の定義
category_name = models.CharField(max_length=255,unique=True)
def __str__(self):
return self.category_name
class Kakeibo(models.Model):
class Meta:
verbose_name ="家計簿"
verbose_name_plural ="家計簿"
#カラムの定義
date = models.DateField("日付",default=datetime.now)
category = models.ForeignKey(Category, on_delete = models.PROTECT, verbose_name="カテゴリ")
money = models.IntegerField("金額", help_text="単位は日本円")
quantity = models.IntegerField(verbose_name="数量",default=0)
memo = models.CharField(verbose_name="メモ", max_length=500)
regist_date = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.memo
この家計簿テーブルには以下のようなデータが登録されているとします。

普通に全レコードを取得する場合は以下のコードで取得できます。
from .models import Kakeibo kakeibo_data = Kakeibo.objects.all()
kakeibo_dataはQuerySet形式のデータですが、django-pandasのread_frameを使うことで一発でDataFrame形式に変換することができます。
使い方はめちゃくちゃ簡単で以下の通り。
from django_pandas.io import read_frame df = read_frame(kakeibo_data, fieldnames=['date', 'category', 'money', 'quantity', 'memo'])
read_frameの第1引数にQuerSetデータを指定し、fieldnamesに取得したいテーブルクラスのカラム(属性)をリスト形式で指定するだけです。
dfを表示してみると、以下の通りDataFrame形式に変換されていることが確認できます。
>>> df
date category money quantity memo
0 2018-12-04 食費 1500 5 ラーメン
1 2018-12-05 食費 1200 2 ファミレス
2 2018-12-06 食費 5000 1 焼肉
3 2018-12-04 交通費 380 3 新宿
4 2018-12-04 交通費 400 2 セミナー参加
5 2018-12-04 雑費 3000 2 書籍購入
6 2018-12-04 雑費 3000 1 飲み会
7 2018-11-19 交通費 14000 2 品川⇔大阪(修正)
8 2018-11-22 交通費 8000 2 出張
9 2018-12-04 雑費 2800 3 書籍購入
10 2018-11-29 雑費 3000 1 書籍購入
11 2019-01-02 食費 480 11 牛丼
12 2019-05-18 食費 3000 1 焼肉
13 2018-10-01 食費 500 5 牛丼
14 2019-05-17 食費 3000 1 焼肉
15 2018-10-31 食費 3000 1 焼肉
16 2018-10-08 交通費 600 2 通勤
17 2018-10-16 交通費 354 3 遊び
18 2018-10-11 雑費 10000 1 パチンコ
19 2018-10-31 電話代 5500 1 携帯
20 2018-11-30 電話代 6500 1 携帯
21 2018-12-31 電話代 7500 1 携帯
22 2019-01-31 電話代 5000 1 携帯
23 2018-12-08 食費 3000 1 食費
24 2018-12-09 食費 390 2 牛肉
25 2019-05-16 食費 500 3 吉牛
django-pandasの応用事例
CSV生成用のボタンを定義する。
<form action='{% url 'kakeibo:export_kakeibo' %}' method='GET' enctype="multipart/form-data">
<div class="btn-group">
<input type="submit" class="btn btn-primary" value="csvファイル生成" data-toggle="tooltip" data-placement="right"data-html="true">
</div>
</form>
urls.pyの設定
CSV生成ボタンが押された際にCALLされるURLパターンを定義します。
例えば、アプリケーション配下のurls.pyのurlpatternsに以下のような定義を追加しておきます。
path('export_kakeibo/', views.export_kakeibo, name='export_kakeibo'),
また、プロジェクト直下のurls.pyには以下を追加してCSVが生成されるメディアファイルパスを定義しておきます。
from django.contrib import admin
from django.urls import path
from django.conf.urls import include, url
from django.conf import settings
from django.conf.urls.static import static #add
urlpatterns = [
path('admin/', admin.site.urls),
url('kakeibo/', include('kakeibo.urls')),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)#add
ビューの設定
次にviews.pyの設定です。
CSV生成ボタンを押した際にCALLされるexport_kakeibo関数を定義します。
※エラー処理等は一切考慮していない簡単なコード例になってます。
from django.conf import settings
def export_kakeibo(request):
qs = Kakeibo.objects.all()
df = read_frame(qs, fieldnames=['date', 'category', 'money', 'quantity', 'memo'])
exp_path = settings.MEDIA_ROOT + "\\kakeibo_list.csv"
df.to_csv(exp_path, encoding='utf_8_sig',index=False)
return render(request, 'kakeibo/kakeibo_export.html')
django-pandasのread_frameでDataFrame形式に変換したデータ(qs)を、以下to_csvメソッドを使ってメディアファイルパスにcsv形式で保存しています。
df.to_csv(exp_path, encoding='utf_8_sig',index=False)
日本語文字化け対策のために「encoding='utf_8_sig'」、DataFrameのIndexを除外するために「index=False」を指定しています。
これで、メディアファイルパスにcsvファイルが生成されます。
settings.pyには以下のメディアファイルの設定をしておきます。
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_URL = '/media/'
テンプレートの設定
最後に、csvファイル生成ボタンを押した後に表示されるCSVダウンロード画面を定義します。
<div class="alert alert-success alert-dismissible" role="alert"> <a href="http://127.0.0.1:8000/media/kakeibo_list.csv">kakeibo_list.csv</a> </div>
非常に簡素に作っていますが、これで以下のような画面が表示されてkakeibo_list.csvをクリックするとメディアディレクトリ上からcsvファイルをダウンロードできるようになります。

一旦メディアディレクトリにcsvを格納しているのが微妙(手間をかけている)な気がしますが、突貫で作ったのでご了承ください。
(ほんとはメモリ内で完結させられれば良いと思いますが・・・)
あと、pandas自体はフィルタリングや集計処理なんかも簡単にできるので、その辺の機能をうまく組み合わせればほしい情報だけを
csvに落とすなんてこともできると思います。
以上、django-pandasの基本操作と活用事例についてでした。
少しでも参考になれば幸いです。

