見出し画像

Djangoとplotly expressでデータ分析ダッシュボードを作成するレシピ

このレシピではDjangoplotly 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.円グラフ(製品毎の売上)の描画

まずは、以下のような製品毎の売上金額割合を表す円グラフを描画していきます。


ここから先は

12,440字 / 4画像

¥ 1,000

主にITテクノロジー系に興味があります。 【現在興味があるもの】 python、Django,統計学、機械学習、ディープラーニングなど。 技術系ブログもやってます。 https://sinyblog.com/