Djangoとplotly expressでデータ分析ダッシュボードを作成するレシピ
このレシピではDjangoとplotly expressを使って以下のようなデータ分析ダッシュボードを作成する方法を学ぶことができます。
1.事前準備
まず、開発に必要な事前準備を行います。
仮想環境の作成、Djangoプロジェクトの作成、アプリケーションの作成まで行います。
任意のディレクトリ上で以下のコマンドを実行して、アプリケーション作成まで完了させてください。
仮想環境の作成とアクティベート
python -m venv plotly
plotly\scripts\activate
次に、今回利用するモジュール群をインストールします。
pip install django plotly faker django-pandas pandas
以下のモジュールをインストールします。
Djangoプロジェクトの作成
以下のコマンドを実行してプロジェクトを作成します。
django-admin startproject config .
アプリケーションの作成
以下のコマンドを実行してapp1という名称のアプリケーションを作成します。
python manage.py startapp app1
config/settings.pyに作成したアプリケーション(app1)を追加します。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app1.apps.App1Config', #追加
]
また日本語にするためconfig\settings.pyの言語とタイムゾーンを以下の通り変更しておきます。
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
2.モデルの定義
次に、データ分析対象のデータモデルを定義します。
今回は、商品の販売状況を分析する事例で説明していきますので、製品テーブル(Product)と販売データテーブル(Order)を定義することにします。
app1\models.pyに以下のコードを定義します。
from django.db import models
from datetime import datetime
class Product(models.Model):
class Meta:
verbose_name = '商品'
verbose_name_plural = "商品"
name = models.CharField(verbose_name = '製品名', max_length=150, null = False, blank=False)
price = models.IntegerField(verbose_name = '価格' ,null= True, blank=True)
def __str__(self):
return self.name
class OrderItem(models.Model):
class Meta:
verbose_name = '注文データ'
verbose_name_plural = '注文データ'
created_date = models.DateField("注文日",default=datetime.now)
product = models.ForeignKey(Product, on_delete = models.PROTECT,verbose_name ="製品名")
def __str__(self):
return f'注文: {self.created_date.strftime("%Y-%m-%d")}'
話をシンプルにするため、ここでは1回の注文で1つの商品を購入するという前提で上記のようなモデルを定義します。
製品の価格はProductテーブル側にpriceという名称で定義しておきます。
一旦マイグレーションを行いテーブルを作成しておきます。
python manage.py makemigrations
Migrations for 'app1':
app1\migrations\0001_initial.py
- Create model Product
- Create model OrderItem
python manage.py migrate
Operations to perform:
Apply all migrations: admin, app1, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying app1.0001_initial... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying sessions.0001_initial... OK
3.デモデータの生成
続いて、データ分析の元となる売上データを作成します。
まず、以下のコマンドを実行して管理者ユーザを作成しましょう。
python manage.py createsuperuser
次に、adminサイトにモデルを表示させるためapp1\admin.pyに以下のコードを追加します。
from django.contrib import admin
from .models import Product, OrderItem
class ProductAdmin(admin.ModelAdmin):
list_display=('pk','name', 'price')
class OrderItemAdmin(admin.ModelAdmin):
list_display=('pk','created_date', 'product')
admin.site.register(Product, ProductAdmin)
admin.site.register(OrderItem, OrderItemAdmin)
開発サーバを起動して、http://127.0.0.1:8000/admin/にアクセスし先ほど作成した管理者ユーザでログオンしましょう。
python manage.py runserver
以下のように「商品、注文データ」が表示されます。
「商品」をクリックして、マニュアルでいくつか商品情報を登録しておきましょう。
このレシピでは、以下の用に8つの製品名と価格を登録しましょう。
注文データについてはマニュアルで作成するのは大変ですので、自動でデモデータを生成するコードを作成します。
config\create_demo_data.pyを作成して以下のコードを記載します。
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
import django
django.setup()
import random
from faker import Factory
from app1.models import Product, OrderItem
from random import randint
from datetime import datetime
fakegen = Factory.create('ja_JP')
def select_product():
count = Product.objects.count()
product = Product.objects.all()[randint(0, count - 1)]
return product
def auto_gen_demo_data(num):
for _ in range(num):
# 製品をランダムに選択
product = select_product()
# 2021/4/1~2022/4/30までの間の日付をランダムに生成
date = fakegen.date_between_dates(date_start=datetime(2021,4,1), date_end=datetime(2022,4,30))
# 注文データを生成
order_item = OrderItem.objects.get_or_create(
product=product, created_date=date)
# コードの実行
if __name__ == "__main__":
print('Start create demo data ...')
auto_gen_demo_data(300)
print('Demo data generation is complete.')
上記コードでは、pythonのランダムなデータを生成するFactoryライブラリーを活用してOrderItemのレコードを自動生成します。
def select_product():
count = Product.objects.count()
product = Product.objects.all()[randint(0, count - 1)]
return product
上記が事前に登録しておいた製品テーブル(Product)からランダムで1つレコードを選択するコードです。
auto_gen_demo_data関数では、まずselect_product関数を使ってランダムに製品レコードを1つ選択します。
また、注文データ(OrderItem)に設定する注文日(created_date)は以下のコードで2021/4/1~2022/4/30の任意の日付を選択するようにしています。
# 2021/4/1~2022/4/30までの間の日付をランダムに生成
date = fakegen.date_between_dates(date_start=datetime(2021,4,1), date_end=datetime(2022,4,30))
以下のコードで注文データを生成します。
order_item = OrderItem.objects.get_or_create(
product=product, created_date=date)
それでは、以下のコマンドを実行して、注文データを生成しましょう。
今回は300件のデータを生成します。
python create_demo_data.py
Start create demo data ...
Demo data generation is complete.
処理が完了したら、adminサイト(http://127.0.0.1:8000/admin)にアクセス後に注文データをクリックしましょう。
以下の通り、自動で大量のテストデータが生成されていることが確認できればOKです。
4.URLパターンの設定
分析データ用のURLパターンを定義していきます。
ます、プロジェクト直下のurls.pyに以下のコードを定義します。
from django.contrib import admin
from django.urls import path, include #修正
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('app1.urls')), #追加
]
続いてapp1\urls.pyを作成して分析ダッシュボードを表示するためのURLパターンを以下の通り定義します。
from django.urls import path
from .views import *
urlpatterns = [
path('dashboard/', Dashboard.as_view(), name='dashboard'),
]
Dashboardクラスはこの後定義します。
5.円グラフ(製品毎の売上)の描画
まずは、以下のような製品毎の売上金額割合を表す円グラフを描画していきます。
ここから先は
¥ 1,000
主にITテクノロジー系に興味があります。 【現在興味があるもの】 python、Django,統計学、機械学習、ディープラーニングなど。 技術系ブログもやってます。 https://sinyblog.com/