Log for everything - Day

Django 프로젝트 Heroku에 릴리즈하기

|

기존 Django 프로젝트 Heroku에 릴리즈

Heroku CLI 설치

brew install heroku

gunicorn을 추가

pip3 install gunicorn

gunicorn 설정시 폴더구조는
메인 -
       |- 프로젝트
       |- 다른 앱
폴더 구조가 다르면 gunicorn module 임포트를 적절히 수정해 줘야 한다.

Procfile 추가

프로젝트 루트에 Procfile을 추가하고 다음 내용을 저장한다.
web: gunicorn myproject.wsgi --log-file -

runtime.txt 추가

프로젝트 루트에 runtime.txt을 추가하고 다음 내용을 저장한다. (파이썬 3.# 일 경우)
python-3.6.1

dj-database-url 추가

pip3 install dj-database-url

이후 프로젝트의 settings.py파일에

import dj_database_url
db_from_env = dj_database_url.config(conn_max_age=500)
DATABASES['default'].update(db_from_env)

를 추가한다.

whitenoise 추가

장고는 기본적으로 프로덕션에서 스태틱 파일을 제공하지 않는다.
whitenoise는 개발 환경 그대로 스태틱 파일을 제공하게 해준다.
pip install whitenoise

settings.py에 다음 내용을 추가한다.

# Simplified static file serving.
# https://warehouse.python.org/project/whitenoise/

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'

wsgi.py에 다음 내용을 추가한다.

from django.core.wsgi import get_wsgi_application
from whitenoise.django import DjangoWhiteNoise

application = get_wsgi_application()
application = DjangoWhiteNoise(application)

requirements.txt 생성

pip freeze > requirements.txt를 입력하여 사용된 패키지를 추출한다.

ALLOWED Host 추가

settings.py에서 ALLOWED_HOSTS = ['*']를 추가한다.

추가사항

DEBUG=False 일때 Whitenoise와 Heroku의 충돌이 있다.
해결방법은 Django를 이용한 건물주 평판 조회 서비스 제작 (5) - Heroku 업로드 여기서 확인

Heroku에 로그인

heroku login

Heroku 앱 생성

heroku create

heroku create
Creating app... done, ⬢ calm-basin-17299
https://calm-basin-17299.herokuapp.com/ | https://git.heroku.com/calm-basin-17299.git

Git remote heroku added

Heroku를 git remote로 추가

git remote add heroku https://git.heroku.com/calm-basin-17299.git

db가 생성되어 있지 않다면 생성

heroku run python manage.py migrate
간혹 dev와 production 환경의 db가 다를 경우 db 생성이 되지 않은 상태라 push가 제대로 되지 않는다.

슈퍼유저 생성

heroku run python manage.py createsuperuser

commit하고 Heroku에 push

git push heroku master

만약 matpolib을 쓴다면… 헤로쿠와 충돌이 일어난다

import matplotlib
matplotlib.use('Agg')

import matplotlib.pyplot as plt, mpld3 전에 추가한다.

Django를 이용한 스케쥴러 제작 (2) - 구현

|

구현

Todolist

Django의 Generic view를 이용해 구현했다.
TodayArchiveView/DayArchiveView를 이용해 해당 날짜의 할일들을 보여주었다.

Calendar

Python standard library의 HTMLCalendar를 이용해 구현했다.
지난달/다음달로 이동할 수 있는 화살표를 추가하고, Workout 테이블을 조회하여 리스트를 해당 날짜에 뿌려주었다.

Stats

id create_date workout_done owner_id workout_id duration workout_date
PK 생성일 운동 수행여부 소유자 FK(List) 수행시간(분) 수행 날짜

Workout 테이블에서 owner를 필터로 쿼리셋을 뽑아낸 후, duration의 평균을 구해 matplotlib으로 출력하였다.
별도의 DB 테이블에 각각의 평균값을 운동 수행 결과 표시 시마다 계산하여 저장하고,
해당 테이블을 조회하는 것이 훨씬 빠르겠지만, 일단은 나 혼자 쓰는 서비스니까 그냥 전체 DB를 검색하기로 결정.
Django 철학에도 있지않은가.. Simple is better than complex 이럴때 쓰란말은 아니지만…
여러 종류의 그래프를 통해 다양한 그래프를 출력하고 싶었지만, 막상 데이터가 여러 방법으로 보여줄 것이 없었다.
워낙 DB 구성이 단순하니까… 나중에 더 생각나면 추가하기로 했다.

로그인/관리자 기능

Django의 기본 Auth와 Admin을 이용했다.
혼자 쓰는 서비스이지만 결국 웹에 올려놓을 테니.. 로그인 기능이 필요하긴 했다.

스크린샷

Todolist

할일목록

Calendar

캘린더

Stats

그래프

모바일 대응 메뉴

모바일 대응

마무리

간단히 시작한 프로젝트였지만, 막상 너무 간단한게 아닌가하는 생각이 들어 무엇인가를 추가하려 했다.
하지만 기능은 추가하고 싶고 마땅히 추가할 기능은 없고… 점점 본질에서 멀어져가며 흥미가 떨어지는 것을 느끼고,
이러다가는 프로젝트를 완성하지도 못할 것 같아 다시 초심으로 돌아가 간단히 마무리했다.
일단은 이것으로 프로젝트 구현을 마치고, 스스로 사용해보고 마음에 들면 개선하고 추가해 볼 생각이다.

추후 계획

  1. 각종 버그 수정… (귀찮지 않다면…)
  2. 데이터 분석 및 그래프 기능 확장
  3. 데이터 입력 기능 편하게 만들기 (현재는 혼자 쓰니 그냥 어드민으로 넣음..)
  4. 간단한 소셜 기능 (옵션)

서비스 링크

간단히 무료 Dyno를 통해 Heroku에 올려두었다.
DB row도 10000줄까지 밖에 지원하지 않지만 혼자쓰니 문제없겠지..

https://workoutcal.herokuapp.com

Django를 이용한 스케쥴러 제작 (1) - 정의 및 구성

|

발단

1일 1커밋을 생활화하기 위해 Django를 이용한 간단한 서비스를 만들기로 했다.
운동을 좋아하는 만큼 운동 스케쥴러를 작성하기로 했고, 프로젝트 목표와 개발 방향을 설정했다.

목표

  1. 스스로 사용할 만한 서비스 구축
  2. 깔끔한 디자인
  3. 확장성(?)

요구사항

  1. 일정을 추가할 수 있고, 일별/월별 보기가 가능할 것
  2. 당일 해야할 운동 종류를 표시하며, 해당 Todo 리스트에서 수행 여부를 표시할 수 있을 것
  3. 수행한 항목의 수행 시간에 비율을 그래프로 출력할 것

DB 구성

크게 운동 종류를 나타낸 Category 테이블을 만들고, 카테고리 테이블을 Foreign key로 이용한 List 테이블,
마지막으로 각각의 개별 운동을 나타내는 Workout 테이블을 생성했다.
테이블 상세 구성은 아래와 같다.

Workout List 테이블

id workout_title category_id
PK 개별 운동 이름 FK(Category)

Workout Category 테이블

id category_name
PK 운동 카테고리 이름

Workout 테이블

id create_date workout_done owner_id workout_id duration workout_date
PK 생성일 운동 수행여부 소유자 FK(List) 수행시간(분) 수행 날짜


App 구성 및 외부 라이브러리

App은 할일을 출력하는 todolist, 월별 목록을 출력하는 calendar,
그래프를 출력하는 stats의 세 부분으로 구성되어 있다.

전체적인 Look&Feel은 심플한 Material Design 형태로 가기로 하고, Materialize를 이용했다.
그래프를 출력하기 위해서는 PlotlyMatplotlib을 고민하다 최종적으로 matplotlib으로 결정하였다.

Django를 이용한 스케쥴러 제작 (2) - 구현

Python 가상환경 옮기기

|

발단

가상환경을 이용한 로컬 프로젝트에서 matplotlib을 임포트 하려니 임포트 에러가 발생했다.

(tensorflow_venv) My-MacBook-Pro:tensorflow_demo mymacpro$ python3 linearregression.py 
Traceback (most recent call last):
File "linearregression.py", line 14, in <module>
import matplotlib.pyplot as plt
File "/Users/mymacpro/Documents/Python_workspace/tensorflow_demo/tensorflow_venv/lib/python3.6/site-packages/matplotlib/pyplot.py", line 115, in <module>
_backend_mod, new_figure_manager, draw_if_interactive, _show = pylab_setup()
File "/Users/mymacpro/Documents/Python_workspace/tensorflow_demo/tensorflow_venv/lib/python3.6/site-packages/matplotlib/backends/__init__.py", line 32, in pylab_setup
globals(),locals(),[backend_name],0)
File "/Users/mymacpro/Documents/Python_workspace/tensorflow_demo/tensorflow_venv/lib/python3.6/site-packages/matplotlib/backends/backend_macosx.py", line 19, in <module>
from matplotlib.backends import _macosx
RuntimeError: Python is not installed as a framework. The Mac OS X backend will not be able to function correctly if Python is not installed as a framework. See the Python documentation for more information on installing Python as a framework on Mac OS X. Please either reinstall Python as a framework, or try one of the other backends. If you are using (Ana)Conda please install python.app and replace the use of 'python' with 'pythonw'. See 'Working with Matplotlib on OSX' in the Matplotlib FAQ for more information.

라이브러리의 FAQ를 보니 virtualenv 대신에 venv를 이용하여 가상환경을 이용하란다.

해결 방법

  1. pip3 freeze > requirements.txt로 기존 가상환경의 패키지 리스트를 추출한다.
  2. python3 -m venv myvenv로 myenv라는 새로운 가상환경을 만든다.
  3. source myvenv/bin/activate로 myenv 가상환경을 실행한다.
  4. pip3 install -r requirements.txt를 통해 전에 있던 가상환경에서 추출한 패키지 리스트를 다시 설치한다.
  5. 필요하다면 (기존 가상환경을 삭제한다.)

결과

그래프

Git Merge 충돌 해결 원인 파악하기

|

발단

로컬의 프로젝트를 Github로 푸쉬하려는데 문제가 발생했다.

(workoutscheduler) My-MacBook-Pro:workoutscheduler mymacpro$ git push origin master
To https://github.com/MinyoungJung/workoutscheduler_project.git
! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/MinyoungJung/workoutscheduler_project.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

메시지를 보니 Github 브랜치 내용이 로컬의 브랜치 내용보다 최신이란다.

해결 방안

  1. git push -f를 통해 강제로 푸쉬한다.
    사실 혼자 로컬에서 작업하는 프로젝트다보니 Github 내용이 더 최신이 된 것 자체가 이상한 상황이고,
    로컬의 코드를 그냥 푸쉬해서 덮어씌워도 아무 문제 없으나 아무래도 찜찜한 것이 사실.

  2. gitk HEAD @{u} 명령어로 upstream branch와 현재 헤드의 차이를 확인한다. 머지 충돌 master와 origin 사이의 충돌이 생긴 이유가 명확해졌다.
    project setting에서 github page를 생성했더니, 그에 대한 파일이 변경된 것이 로컬에서는 반영되지 않은 것.
    원인을 파악했으니 편안한 맘으로 강제로 푸쉬할 수 있게 되었다.