이 글은 Django 사용한 간단한 데쉬보드 웹 어플리케이션 개발 이야기를 나눔한다.
웹 어플리케이션 개발 방법은 다양하지만, 몇 년 사이에 유행하고 있는 트랜드는 마이크로 서비스 개발이 가능한 플라스크 같은 플랫폼을 사용하는 것이다. 여기서는 개발자가 애용하고 있는 파이썬 기반 Django(장고) 플랫폼을 사용해 웹 서비스 개발 방법을 알아본다.
장고를 이용하면, 파이썬의 다양한 라이브러리를 사용한 웹 앱을 손쉽게 개발할 수 있다. 장고보다 경량의 플랫폼인 플라스크 사용법은 다음 링크를 참고한다.
이 글은 다음 레퍼런스를 참고한다.이 글의 소스코드는 다음 링크를 참고한다.
개발 환경 준비
다음과 같이 개발 환경을 준비한다.
- 데이터베이스 설치: Django 설치시 sqlite db가 설치된다. 만약, 다른 DB를 사용하고 싶다면, MariaDB, MySQL, PostgreDB 등을 설치한다.
- 데이터베이스 커넥터 설치: pip install mysqlclient 명령으로 커넥터 드라이버 설치한다.
- 장고 설치: pip install Django
제대로 설치되었다면, 다음 코드를 입력해 실행한다. 정상동작하면 성공한 것이다.
import django
print(django.get_version())
데쉬보드 개발해보기
터미널에서 다음 명령을 실행해본다.
django-admin startproject monitoring
cd monitoring
python manage.py runserver
이제, The install worked successfully! Congratulations!를 클릭해 본다. 다음과 같이 웹 앱이 실행되면 성공한 것이다.
python manage.py startapp dashboard
- __init__.py : 이 앱에 필요한 파이썬 패키지를 초기화하고, 임포트함
- admin.py : 장고 관리자 페이지를 위한 설정
- apps.py : app 설정
- models.py : 장고 ORM(Object Relationship Mapping)을 위한 클래스 정의
- tests.py : 테스트 클래스 정의
- views.py : 데이터가 웹 템플릿에 의해 보여지는 방식을 정의
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'dashboard'
]
from django.http import JsonResponse
from django.shortcuts import render
from dashboard.models import Order
from django.core import serializers
def dashboard(request): // 이 함수는 사용자가 URL 입력 시 호출됨
return render(request, 'dashboard.html', {}) // 이때 HTML 템플릿을 사용해 렌더링
def order_data(request): // HTML 렌더링 시 전달될 DB의 데이터는 JSON 형태로 변환 리턴
dataset = Order.objects.all()
data = serializers.serialize('json', dataset)
return JsonResponse(data, safe=False)
여기서, 데쉬보드에 렌더링될 템플릿 HTML파일을 리턴하는 dashboard..()함수, 보여질 데이터를 준비하는 pivot...() 함수를 준비해 놓았다. 참고로, 아직 구현되지 않은 HTML과 Order 모델은 이후 작업될 것이다.
URL-함수 맵핑
앞서 정의된 함수를 사용자 URL 입력 시 실행되도록 맵핑해야 한다.
이를 위해, monitoring/urls.py를 다음과 같이 편집한다.
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('dashboard/', include('dashboard.urls'))
]
위 코드에서 include에 urls.py를 사용하므로, 이 파일을 코딩해야 한다. dashboard/urls.py 파일을 다음같이 편집한다. 앞서 정의된 함수와 URL이 연결된 것을 알 수 있다.
from django.urls import path
from . import views
urlpatterns = [
path('', views.dashboard, name='dashboard'),
path('data', views.order_data, name='order_data'),
]
모델 개발
이제 보여줄 데이터를 가지고 있는 모델을 코딩한다. 여기서는 가벼운 SQLite를 데이터베이스로 사용한다.
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)
이제 정의된 모델 클래스를 데이터베이스 테이블로 생성해줘야 데이터를 저장할 수 있다. 이 처리를 위해, 다음 명령으로 마이그레이션을 한다.
python manage.py makemigrations dashboard
결과, 다음과 같이 자동으로 지정 폴더의 model을 읽어 ORM처리 하도록 설정된다.
python manage.py migrate dashboard
python manage.py shell
DB를 조작할 수 있는 터미널이 실행될 것이다. 여기서 파이썬 코드를 실행할 수 있다. 다음을 입력한다.
from dashboard.models import Order
o1 = Order(
product_category='Books',
payment_method='Credit Card',
shipping_cost=39,
unit_price=59
)
o1.save()
이런 방식으로 원하는 만큼 데이터 레코드를 INSERT할 수 있다.
데이터 생성 모습
참고로, 다음 명령으로 생성된 데이터를 리스트할 수 있다. 셀의 상세 기능은 여기를 참고한다.
for u in Order.objects.all():
print(u)
dic = u.__dict__
for f, v in dic.items():
print(f'{f}: {v}')
이제 준비된 데이터를 데쉬보드 UI에 연결해야 한다.
웹에서 UI 처리는 크게 '요청-응답' 방식, 비동기 요청 방식(AJAX)이 있다. 여기서는 AJAX 방식을 사용한다. 이를 위해 jQuery $.ajax 함수를 사용하였다. 관련된 상세 사용법은 아래 링크를 참고한다.
templates/dashboard...html 파일을 다음과 같이 편집한다. 데쉬보드는 Flexmonster UI로 만든 테이블, 원 차트 두개로 구성된다.
<script>
function processData(dataset) {
var result = []
dataset = JSON.parse(dataset);
dataset.forEach(item => result.push(item.fields));
return result;
}
$.ajax({ // 비동기 jQuery 호출. 데이터는 DB에 미리 준비됨. URL HTML 렌더링은 비동기.
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"
}
}
}
});
}
});
</script>
여기서 사용된 데쉬보드 UI인 Flexmonster는 ajax모드에서 pivot-table-container ID를 가진 div에 임베딩되도록 설정되어 있다.
여기서, processData는 URL질의 결과 리턴되는 JSON 텍스트를 파싱해, result 리스트에 각 아이템을 추가하는 역할을 한다. 이 함수는 Flexmonster란 데쉬보드 UI의 report의 datasource에 지정되어, UI와 데이터를 연결하는 역할을 한다.
Flexmonster 데쉬보드는 데이터소스 속성이 보여지는 방식을 설정할 수 있다. 다음과 같이 편집한다.
dataSource: {
type: "json",
data: processData(data),
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"
}
}
},
이제 다음 명령으로 개발한 웹 앱을 실행해 본다.
장고로 개발된 웹 앱 실행 결과
맵 연동
이제 맵과 연동해 본다. 다음은 리플릿과 Plotly을 이용한 간단한 장고 웹 앱 실행 결과이다.
코드 디버깅
장고로 개발한 코드를 디버깅할 수 있으면, 실행 상태에서 변수, 콜 스택 등을 쉽게 확인할 수 있다. 우선, 디버깅 버튼의 launch.json 생성 버튼을 클릭해, .vscode 폴더에 launch.json을 생성한다.
다음과 같이 launch.json를 수정한다. 보다시피, 디버깅할 programd의 args를 설정해 두었다. 본 실습에는 chrome대신 edge를 사용하였기에, 두번째 설정은 msedge로 타입을 지정하였다.
{
"version": "0.2.0",
"configurations": [
{
"name": "Django",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}\\manage.py",
"args": [
"runserver",
"--noreload"
],
"django": true,
"justMyCode": true
},
{
"name": "Edge",
"type": "msedge",
"request": "launch",
"url": "http://localhost:8000",
"webRoot": "${workspaceFolder}"
}
]
}
생성된 launch.json 파일
이제 manager.py를 선택하고 디버깅 버튼을 클릭하면 다음과 같이, 코드를 디버그할 수 있다.
로그는 settings.py에 다음 LOGGING 사전을 추가하고, 원하는 코드에 사용하면 된다.
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"handlers": {
"console": {"class": "logging.StreamHandler"},
},
"loggers": {
"django": {
"handlers": ["console"],
"level": "INFO",
},
}
}
코드는 다음과 같다.
import logging
import logging.config
logger = logging.getLogger('django')
logger.info('here goes your message')
def your_func():
logging.config.fileConfig('logging.conf')
logger = logging.getLogger('applog')
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
좀 더 상세한 디버깅 방법은 다음을 참고한다.
이 글을 통해, 간단히 장고로 만든 앱 앱을 코딩하고 실행해 보았다. 이와 같은 방식으로 다양한 웹 앱을 개발할 수 있을 것이다.
레퍼런스
- Make a Location-Based Web App With Django and GeoDjango – Real Python
- How to create an analytics dashboard in a Django app (freecodecamp.org)
- A Minimal Django Application (simpleisbetterthancomplex.com)
- Displaying a map in a Django Webapp (2/3): Develop a GIS webapp with GeoDjango | by Hakim Benoudjit | Medium
- Top 10 Data Visualization Tools with Node.js | by Code Everywhere | Jul, 2023 | Medium | Medium
- Query Your Data — MongoDB Compass
- Django logging - forget about 'print' when debugging - DEV Community
부록: Mongo 데이터베이스 연결
일반적으로, Django가 지원하는 database는 sqlite, mysql, postgresql 이다. 그러므로, mongo database를 settings.py에서 설정한 후 실행해보면, 다음과 같이 에러가 발생할 수 있다.
django.core.exceptions.ImproperlyConfigured: 'django_mongodb_engine' isn't an available database backend.
Try using 'django.db.backends.XXX', where XXX is one of:
u'base', u'mysql', u'oracle', u'postgresql_psycopg2', u'sqlite3'
Error was: cannot import name BaseDatabaseFeatures
이 경우, 다음과 같이 패키지를 설치한다. djongo는 mongodb와 django를 연결해 준다.
pip install djongo
pip install pytz
댓글 없음:
댓글 쓰기