Django + Matplotlib

김주언·2022년 8월 13일
0

Django

목록 보기
8/9
post-thumbnail

장고 웹 애플리케이션에서 Matplotlib을 이용하여 데이터 시각화하기


프로젝트 생성

  1. 프로젝트 생성
django-admin startproject SALES

생성 후 프로젝트 구조는 아래와 같다.

├── db.sqlite3
├── manage.py
├── SALES
│   ├── asgi.py
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── static
│   ├── book.jpg
│   ├── bootstrap-5.0.0-beta1-dist
│   │   ├── css
│   │   │   ├── bootstrap.css
│   │   │   ├── bootstrap.css.map
│   │   │   ├── bootstrap-grid.css
│   ├── style.css

  1. 앱 생성
python manage.py startapp sales

  1. settings.py에 앱 추가 & static 파일 설정
INSTALLED_APPS = [
    'sales',
    'crispy_forms'	# 스타일링 하기 위한 앱
]
CRISPY_TEMPLATE_PACK = 'bootstrap4'
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

static 파일은 /static폴더 밑에 있음을 알려준다.
/media 폴더에 업로드된 미디어 파일을 저장한다.


  1. 설정을 라우팅하기 위해 urls.py 을 수정한다.
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include

urlpatterns = [path('admin/', admin.site.urls)]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)



모델 생성

models.py 파일에 내용을 추가한다.

from django.contrib.auth.models import User
from django.db import models

# Create your models here.
from django.utils import timezone
from sales.utils import generate_code

# Customer class to keep track of name and image
class Customer(models.Model):
    name = models.CharField(max_length=120)
    logo = models.ImageField(upload_to='customers')

    def __str__(self):
        return self.name

# SalesPerson class to keep track of the the sales person's information
class SalesPerson(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    bio = models.TextField(default='No bio yet...')
    avatar = models.ImageField(upload_to='avatars')
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return f"Salesperson {self.user.username}"

# Sale class to keep track of the sales information
class Sale(models.Model):
    transaction_id = models.CharField(max_length=12, blank=True)
    total_price = models.FloatField(blank=True, null=True)
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
    salesman = models.ForeignKey(SalesPerson, on_delete=models.CASCADE)
    created = models.DateTimeField(blank=True)
    updated = models.DateTimeField(auto_now=True)

    def save(self, *args, **kwargs):
        if self.transaction_id == "":
            self.transaction_id = generate_code()
        if self.created is None:
            self.created = timezone.now()
        return super().save(*args, **kwargs)
   
    def __str__(self):
        return f"Sales for the amount of Kshs {self.total_price}"
  • 세일즈 데이터를 Sale 클래스를 이용하여 나타낸다
  • save 메소드를 오버라이드하여 사용한다.
    • transaction_id가 null이면 자동으로 생성한다.
    • created time가 정의되어 있지 않으면 현재시간으로 설정한다.

generate_code() 함수 생성

import uuid

def generate_code():
    return str(uuid.uuid4()).replace('-', '').upper()[:12]

12자리의 랜덤 알파벳 코드를 반환한다.


모델 등록 - admin site

  1. admin.py 파일에 코드를 작성한다
from django.contrib import admin
from .models import Customer, Sale, SalesPerson

# Register your models here.
admin.sites.register(Customer)
admin.sites.register(Sale)
admin.sites.register(SalesPerson)
  1. superuser를 생성한다.
python manage.py createsuperuser

관리자 계정을 생성한 후 관리자 페이지에 들어가보면 모델들이 등록되어 있다.


지금까지의 과정을 통해서 데이터를 데이터베이스에 추가하였다.

데이터 나타내기

유저가 특정 데이터를 찾을 수 있도록 검색하는 폼을 만들어준다
date, transaction, customer address, total price를 기반으로 정보를 필터링한다.

폼 작성

forms.py 파일을 만들고 폼 필드를 정의한다.

from django import forms

CHART_CHOICE = (
    ('#1', 'Bar Graph'),
    ('#2', 'Pie Chart'),
    ('#3', 'Line Graph')
)

RESULTS_CHOICES = (
    ('#1', 'Transaction'),
    ('#2', 'Sales Date'),
    ('#3', 'Customer ID'),
    ('#4', 'Total Price')
)

class SalesSearchForm(forms.Form):
    date_from = forms.DateField(widget=forms.DateInput(attrs={'type': 'date'}))
    date_to = forms.DateField(widget=forms.DateInput(attrs={'type': 'date'}))
    chart_type = forms.ChoiceField(choices=CHART_CHOICE)
    results_by = forms.ChoiceField(choices=RESULTS_CHOICES)
    

사용자가 날짜, 차트타입, 결과를 선택할 수 있는 폼이다.

뷰 작성

데이터를 웹페이지에 보내기 위해서 뷰를 작성한다

views.py파일을 수정한다.

import pandas as pd
from django.shortcuts import render
from django.views.generic import ListView
from .forms import SalesSearchForm


# Create your views here.
def sales(request):
    search_form = SalesSearchForm(request.POST or None)
    context = {'search_form' : search_form}
    return render(request, 'sales.html', context)

sales 함수는 검색 폼을 HTML 파일에 렌더한다.



템플릿 생성

템플릿 경로 설정

settings.py 파일의 템플릿 설정 수정하기

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

위 설정은 Django가 HTML 파일을 찾을 때 templates 라는 폴더로부터 찾도록한다.
manage.py 파일과 같은 레벨에 templates 폴더를 생성하고 HTML파일을 생성한다.

HTML 작성

base.HTML

<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="{% static 'style.css' %}">
    <link rel="stylesheet" href="{% static 'bootstrap-5.0.0-beta1-dist/css/bootstrap.css' %}">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/1.11.8/semantic.min.css"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/1.11.8/semantic.min.js"></script>
    <title>Report App | {% block title %} {% endblock title %}</title>
</head>
<body>
<div class="ui secondary menu">
    <a class="item"><img style="height:100px;width:100px;" src="{% static 'book.jpg' %}" alt=""></a>
    <a href="#" class="  active item">Home</a>
</div>
<div class="container mb-3 mt-3">
    {% block content %}
    {% endblock content %}
</div>
</body>
</html>

다른 파일들을 위해 사용될 베이스 HTML파일. 공통 스타일링이 정의되어 있다.

베이스 HTML 파일을 사용함으로써 같은 코드를 반복작성하지 않아도 된다. 다른 파일에서 베이스 파일을 사용하기 위해서 {% extends 'base.html' %} 를 작성하면 스타일링이 적용됨

위의 베이스 파일은 애플리케이션의 다른 루트들의 링크를 가지고 있다. HOME 루트는 데이터 표현 페이지로 네비게이트한다.

sales.html

{% extends 'base.html' %}
{% load static %}
{% load crispy_forms_tags %}
{% block scripts %}

{% endblock scripts %}
{% block title %}
    Home
{% endblock title %}
{% block content %}

    <form action="" method="post">
        {% csrf_token %}
        {{ search_form|crispy }}
        <button class="btn btn-primary mt-3" type="submit">Search</button>
    </form>
{% endblock content %}

위 페이지는 검색폼을 나타낸다.



뷰 라우팅 (urlConfig)

뷰가 실제로 동작하게 하기 위해서 루트를 설정해줘야한다. (url 경로 설정)

sales app url 설정

sales 앱 하위에 urls.py 파일을 새로 생성한다. 이 파일을 함수와 클래스로의 라우팅을 다룬다.

요청들은 이 파일에 의해서 처리되며 요청에 일치하는 함수와 클래스로 라우팅된다.

from django.urls import path
from . import views

urlpatterns = [
    path('', views.sales, name='sales')
]

project 단위 url 설정

sale 앱에 대한 라우팅을 처리하기 위해서 SALE 프로젝트의 url을 설정한다
SALES/urls.py 파일을 수정한다.

urlpatterns = [
    path('admin/', admin.site.urls),
               path('', include('sale.urls'))
               ]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

base.html 수정

뷰에 접근하기 위해서 파일을 수정한다.

 <a href="{{sales_home}}" class=" active item">Home</a>

profile
학생 점심을 좀 차리시길 바랍니다

0개의 댓글