برنامه‌نویسی

آموزش ساخت داشبورد تجزیه و تحلیل در برنامه‌های Django

آموزش ساخت داشبورد تجزیه و تحلیل در برنامه‌های django

در این مقاله به visualization داده‌ها و برنامه‌نویسی با پایتون خواهیم پرداخت، اگر شما داده‌هایی را در بخش بک‌اند دارید که می‌خواهید آن‌ها را در جداول و نمودارهای فرانت‌اند نمایش دهید این مقاله می‌تواند به شما کمک کند زیرا پس از اتمام این مقاله، یک برنامه Django با جداول و نمودارهای تعاملی خواهید داشت.

پیش نیاز‌ها

شما برای شروع به درک کلی از فریم‌ورک Django و کمی خلاقیت نیاز خواهید داشت. همچنین قبل از شروع مقاله می‌توانید با این لینک به برنامه‌ی پایانی این آموزش در GitHub دسترسی داشته باشید و آن را دانلود کنید. ابزارهایی که می‌خواهیم از آنها استفاده کنیم، عبارتند از:

شروع کار با Django

ابتدا باید مطمئن شوید که Django را بر روی سیستم خود نصب کرده‌اید. قاعده کلی به این صورت است که شما Django را بر روی یک virtual environment که یک ابزار قدرتمند برای جداسازی وابستگی‌های پروژه‌هایتان است، نصب کنید. حال کنسول سیستم خود را باز کرده و اطمینان حاصل کنید که محیط مجازی‌ای (virtual env) که تازه ایجاد کرده‌اید را فعال کنید و در انتها با دستور زیر یک پروژه Django راه‌اندازی کنید:

django-admin startproject analytics_project

پس از اجرای این دستور یک پوشه با نام analytics_project ایجاد خواهد شد و برای کسب اطمینان از درست انجام شدن مراحل قبل، در کنسول خود وارد این پوشه شوید و سپس دستور زیر را وارد کنید:

python manage.py runserver

حال آدرس http://127.0.0.1:8000/ را در مرورگر خود باز کنید. اگر شما یک موشک مانند تصویر زیر می‌بینید، همه مراحل به خوبی انجام شده است.

ظاهر اولیه برنامه django

در مرحله بعد باید یک app با نام dashboard ایجاد کنید که این کار را می‌توانید با دستور زیر انجام دهید:

python manage.py startapp dashboard

اگر تفاوت app و project‌ را در Django نمی‌دانید، کمی وقت بگذارید تا هر کدام را درک کنید زیرا به این صورت تصور واضح‌تری از چگونگی سازماندهی پروژه‌های Django خواهید داشت.

حال با اجرای دستور بالا یک پوشه جدید با فایل‌های زیر خواهیم داشت:

  • __init__.py: تا پایتون با آن مانند یک پکیج رفتار کند.
  • admin.py: تنظیمات صفحه مدیریت Django را شامل می‌شود.
  • apps.py: تنظیمات پیکربندی برنامه در این فایل قرار می‌گیرد.
  • models.py: کلاس‌هایی که توسط Django ORM به جداول دیتابیس تبدیل می‌شوند، در این فایل قرار می‌گیرد.
  • tests.py: کلاس‌های تست در این فایل قرار می‌گیرند.
  • views.py: توابع و کلاس‌هایی که داده‌ها را در template به نمایش درمی‌آورند در این فایل قرار می‌گیرند.

حال به سراغ ثبت app در پروژه Django می‌رویم. فایل analytics_project/settings.py را در ویرایشگر باز کنید و نام app را در لیست INSTALLED_APPS اضافه کنید:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'dashboard',
]

اکنون پروژه ما از وجود برنامه آگاه است.

Views

تابعی در فایل dashboard/views.py ایجاد خواهیم کرد تا کاربر را به یک template تعریف شده در پوشه dashboard/templates هدایت کند. البته شما می‌توانید از کلاس‌ها نیز استفاده کنید.

from django.http import JsonResponse
from django.shortcuts import render
from dashboard.models import Order
from django.core import serializers

def dashboard_with_pivot(request):
    return render(request, 'dashboard_with_pivot.html', {})

پس از فراخوانی این تابع، فایل dashboard_with_pivot.html رندر می‌شود و شامل اجزای جداول و نمودارها خواهد بود که البته به زودی این موارد را به این فایل اضافه می‌کنیم.

حال اگر بخواهیم کمی تابع بالا را توضیح دهیم، باید گفت که یک آرگومان request از نوع آبجکت‌های HttpRequestObject است که شامل اطلاعاتی در رابطه با درخواست‌های ارسال شده به سمت این متد است و از متدهای HTTP که شامل GET و POST است، استفاده می‌کند. متد render در پوشه templates به دنبال HTML templateها می‌گردد.

همچنین ما به یک تابع کمکی برای ارسال داده‌ها به جداول موجود فرانت‌اند برنامه نیاز داریم و آن را pivot_data می‌نامیم:

def pivot_data(request):
    dataset = Order.objects.all()
    data = serializers.serialize('json', dataset)
    return JsonResponse(data, safe=False)

به احتمال زیاد، IDE به شما می‌گوید که نمی‌تواند Order را در models.py پیدا کند، به آن توجه نکنید زیرا این مسئه را بعدا حل خواهیم کرد.

Templates

در حال حاضر ما از Django template system استفاده می‌کنیم. پس یک پوشه با نام templates در پوشه dashboard ایجاد می‌کنیم و سپس یک فایل HTML با نام dashboard_with_pivot.html در آن پوشه می‌سازیم. این فایل در پاسخ به درخواست کاربر نمایش داده می‌شود بنابراین اسکریپت‌ها و سایر موارد که برای نمایش داده‌ها احتیاج داریم را به این فایل اضافه می‌کنیم.

<head>
  <meta charset="UTF-8">
  <title>Dashboard with Flexmonster</title>
  <script src="https://cdn.flexmonster.com/flexmonster.js"></script>
  <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
  <link rel="stylesheet" href="https://cdn.flexmonster.com/demo.css">
</head>
<body>
<div id="pivot-table-container" data-url="{% url 'pivot_data' %}"></div>
<div id="pivot-chart-container"></div>
</body>

اتصال توابع views.py به URLها

برای اجرای توابع موجود در فایل view.py و نمایش فایل‌های رندر شده HTML به کاربران نیاز است تا Viewها را به URLها متصل کنیم.

نکته‌ای که در این قسمت وجود دارد و می‌بایست به آن توجه داشته باشید، ایجاد URLهایی با نامی متفاوت از نام توابع است، همچنین برای اطلاعات بیشتر می‌توانید به مستندات رسمی این فریم‌ورک را مطالعه کنید.

به فایل analytics_app/urls.py بروید و پیکربندی‌های مربوط به برنامه‌ی dashboard را اضافه کنید.

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('dashboard/', include('dashboard.urls')),
]

اکنون می‌توانید به URLهای برنامه dashboard دسترسی پیدا کنید اما تنها در صورتی که از dashboard قبل از الگوهای موجود در فایل dashboard/urls.py استفاده کنید.

حال به فایل dashboard/urls.py بروید، اگر وجود ندارد خودتان آن را بسازید و لیستی از URL patternها که به توابع موجود در views.py متصل شده‌اند را در این فایل قرار دهید:

from django.urls import path
from . import views

urlpatterns = [
    path('', views.dashboard_with_pivot, name='dashboard_with_pivot'),
    path('data', views.pivot_data, name='pivot_data'),
]

Model

سرانجام به مدل سازی داده‌ها رسیدیم. همان‌طور که می‌دانید منظورمان از مدل سازی داده، نمایش مفهومی داده‌های ذخیره شده در دیتابیس است.

از آنجا که هدف این مقاله آموزش ساخت یک برنامه برای visualization داده‌ها درون برنامه است، در انتخاب دیتابیس زیاد مشکلی نخواهیم داشت. ما از SQLite که یک دیتابیس سبک است و توسط وب‌سروری که توسط Django در اختیار ما قرار داده می‌شود، استفاده می‌کنیم.

اما یادتان باشد که این دیتابیس برای برنامه‌های تجاری و بسیار بزرگ، گزینه مناسبی نیست. شما توسط Django ORM می‌تواند از دیتابیس‌های مبتنی بر SQL مانند PostgreSQL یا MySQL استفاده کنید.

Model ما برای حفظ سادگی از یک کلاس تشکیل می‌شود اما شما می‌توانید کلاس‌های بیشتری ایجاد کرده و روابط پیچیده‌تر یا ساده‌تری را میان آنها تعریف کنید. تصور کنید ما یک داشبورد برای بخش فروش طراحی می‌کنیم، پس یک کلاس با نام Order می‌سازیم و ویژگی‌های آن را به صورت زیر در فایل dashboard/models.py تعریف خواهیم کرد:

from django.db import models


class Order(models.Model):
    product_category = models.CharField(max_length=20)
    payment_method = models.CharField(max_length=50)
    shipping_cost = models.CharField(max_length=50)
    unit_price = models.DecimalField(max_digits=5, decimal_places=2)

کار با دیتابیس

حال ما باید یک دیتابیس ایجاد کرده و در آن چند رکورد قرار دهیم اما سوالی که به‌وجود می‌آید این است که چگونه Model خود را به دیتابیس تبدیل کنیم؟

در اینجاست که مفهوم migration مفید واقع می‌شود. migration را می‌توان فایلی دانست که توصیف می‌کند چه تغییرهایی باید در دیتابیس اعمال شود و هر زمان که نیاز به ایجاد یک دیتابیس بر اساس Model داشتیم از آن استفاده می‌کنیم.

داده‌ها می‌توانند به صورت آبجکت‌های Python، دیکشنری‌ها یا لیست‌ها باشند. این بار ما با استفاده از کلاس‌های Python موجود در فایل models، موجودیت‌های دیتابیس را نشان خواهیم داد.

با دستور زیر می‌توانیم یک migration برای برنامه خود ایجاد کنید:

python manage.py makemigrations dashboard

با استفاده از دستور بالا به Django دستور دادیم تا migrationها را برای Modelهای برنامه dashboard ایجاد کند. پس از ایجاد فایل migration، دستور زیر را اجرا کنید تا migrationهایی که در این فایل تعریف شدند تایید شوند و در نهایت دیتابیس ساخته شود.

python manage.py migrate dashboard

اگر فایل جدیدی با نام db.sqlite3 در پوشه پروژه‌تان مشاهده می‌کنید یعنی ما آماده کار با دیتابیس هستیم.

حال به سراغ ایجاد نمونه‌هایی از کلاس Order می‌رویم، به همین منظور از Django shell که مانند Python shell است و به ما اجازه دسترسی به دیتابیس را می‌دهد، استفاده می‌کنیم. با دستور زیر Django shell را start کنید:

python manage.py shell

و سپس کدها را به این صورت در آن بنویسید:

>>> from dashboard.models import Order

>>> o1 = Order(
... product_category='Books',
... payment_method='Credit Card',
... shipping_cost=39,
... unit_price=59
... )
>>> o1.save()

به همین ترتیب می‌توانید داده‌های جدیدی در دیتابیس ایجاد کنید.

اتصال داده‌ها به Flexmonster

تازه می‌توان گفت به جای اصلی این آموزش رسیده‌ایم. در این بخش می‌خواهیم بفهمیم که چگونه داده‌ها را از Model به ابزاری که در فرانت‌اند برای visualization داده استفاده می‌کنیم، انتقال دهیم.

برای ارتباط بک‌اند با Flexmonster می‌توانیم دو روش مختلف را دنبال کنیم:

  • استفاده از request-response cycle که به این منظور می‌توانیم از Python و Django template engine برای نوشتن کدهای JavaScript در template به صورت مستقیم استفاده کنیم.
  • از درخواست‌های async (ajax) که داده‌ها را به صورت JSON برمی‌گردانند استفاده کنیم.

به نظر می‌رسد روش دوم مناسب‌تر باشد زیرا آسان‌تر است و Flexmonster عملکرد بهتری با داده‌های JSON دارد. اگر بخواهید دقیق‌تر بدانید، این ابزار آرایه‌ای از آبجکت‌های JSON را به عنوان داده‌‌های ورودی، دریافت می‌کند. یکی دیگر از مزایای استفاده از درخواست‌های async، سرعت بهتر بارگیری صفحه و کدهایی با قابلیت نگه‌داری بالاتر است.

بیایید با هم چگونگی کارکرد آن را ببینیم. به فایل templates/dashboard_pivot.html بروید، در این فایل دو div ایجاد کرده‌‌ایم که در آن نمودارهای خود را نشان می‌دهیم.

ما درخواست‌‌هایی بر اساس URL موجود در data-URL توسط ajax ایجاد می‌کنیم که انتظار داریم که آبجکت JSON که توسط dataType تعریف شده، برگردانده شود.

پس از تکمیل درخواست، یک پاسخ JSON از طرف سرور Django، به عنوان پارامتر data برگشت داده می‌شود که جدول توسط این مقدار پر، و در نهایت رندر می‌شود.

نتیجه کوئری که از نوع JSONResponse است یک string که حاوی آبجکتی آرایه‌ای با متادیتا‌های اضافی است، برمی‌گرداند. بنابراین باید یک تابع برای پردازش داده‌ها در فرانت‌اند اضافه کنیم تا آبجکت‌های تودرتو را extract کند و در یک آرایه واحد قرار دهد زیرا Flexmonster آرایه‌ای از آبجکت JSON را بدون سطوح تودرتو می‌پذیرد.

function processData(dataset) {
    var result = []
    dataset = JSON.parse(dataset);
    dataset.forEach(item => result.push(item.fields));
    return result;
}

بعد از پردازش داده‌ها در فرمت مناسب و دریافت آنها توسط کامپوننت، visualization داده‌ها انجام می‌شود. یک مزیت بزرگ این است که نیازی به دسته‌بندی یا جمع‌آوری دستی مقادیر آبجکت‌ها نیست. در زیر اسکریپت‌های template را مشاهده می‌کنید:

function processData(dataset) {
    var result = []
    dataset = JSON.parse(dataset);
    dataset.forEach(item => result.push(item.fields));
    return result;
}
$.ajax({
    url: $("#pivot-table-container").attr("data-url"),
    dataType: 'json',
    success: function(data) {
        new Flexmonster({
            container: "#pivot-table-container",
            componentFolder: "https://cdn.flexmonster.com/",
            width: "100%",
            height: 430,
            toolbar: true,
            report: {
                dataSource: {
                    type: "json",
                    data: processData(data)
                },
                slice: {}
            }
        });
        new Flexmonster({
            container: "#pivot-chart-container",
            componentFolder: "https://cdn.flexmonster.com/",
            width: "100%",
            height: 430,
            //toolbar: true,
            report: {
                dataSource: {
                    type: "json",
                    data: processData(data)
                },
                slice: {},
                "options": {
                    "viewType": "charts",
                    "chart": {
                        "type": "pie"
                    }
                }
            }
        });
    }
});

فراموش نکنید که اینها کدهای JavaScript هستند و می‌بایست تگ <script> را به آنها اضافه کنید.

شخصی‌سازی Fieldها

Flexmonster ویژگی‌های خاصی از Data source را که امکان تنظیم انواع داده‌ها، captionهای سفارشی و تعریف سلسله مراتب چند سطحی را فراهم می‌کند، ارائه می‌دهد.

این یک ویژگی خوب است که ما می‌توانیم داده‌ها و نمایش آنها را در بخش تنظیمات report، جداسازی کنیم. کد‌های زیر رو به ویژگی dataSource در report propertyاضافه کنید.

mapping: {
    "product_category": {
        "caption": "Product Category",
        "type": "string"
    },
    "payment_method": {
        "caption": "Payment Method",
        "type": "string"
    },
    "shipping_cost": {
        "caption": "Shipping Cost",
        "type": "number"
    },
    "unit_price": {
        "caption": "Unit Price",
        "type": "number"
    }
}

طراحی داشبورد

ما دو نمونه از Flexmonster را برای ساخت داشبورد رندر کرده‌ایم اما شما بسته به نیاز خود می‌توانید انواع مختلفی را ایجاد کنید. یکی برای جدول با داده‌های خلاصه و دیگری برای نمودار‌ها.

هر دو داده‌های مشابهی دارند، اگر می‌خواهید خود را به چالش بکشید می‌توانید آنها را با استفاده از event reportchange به صورت sync در بیاورید، به نحوی که تغییر یکی باعث تغییر دیگری شود.

همچنین می‌توانید عملکرد دکمه Export در نوار ابزار را بازنویسی کنید تا گزارشات را در سرور شما ذخیره کند.

برنامه نهایی

حال می‌توانید سرور Django خود را start کرده و آدرس http://127.0.0.1:8000/dashboard/ را در مرورگر باز کنید تا برنامه نهایی را ببینید.

برنامه نهایی

منبع: https://www.freecodecamp.org/news/how-to-create-an-analytics-dashboard-in-django-app