10 Jun 2017
|
Django
Web service
Python
Heroku
whitenoise
기존 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
전에 추가한다.
09 Jun 2017
|
Django
Web service
Python
Scheduler
Material Design
구현
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
모바일 대응 메뉴
마무리
간단히 시작한 프로젝트였지만, 막상 너무 간단한게 아닌가하는 생각이 들어 무엇인가를 추가하려 했다.
하지만 기능은 추가하고 싶고 마땅히 추가할 기능은 없고… 점점 본질에서 멀어져가며 흥미가 떨어지는 것을 느끼고,
이러다가는 프로젝트를 완성하지도 못할 것 같아 다시 초심으로 돌아가 간단히 마무리했다.
일단은 이것으로 프로젝트 구현을 마치고, 스스로 사용해보고 마음에 들면 개선하고 추가해 볼 생각이다.
추후 계획
- 각종 버그 수정… (귀찮지 않다면…)
- 데이터 분석 및 그래프 기능 확장
- 데이터 입력 기능 편하게 만들기 (현재는 혼자 쓰니 그냥 어드민으로 넣음..)
- 간단한 소셜 기능 (옵션)
서비스 링크
간단히 무료 Dyno를 통해 Heroku에 올려두었다.
DB row도 10000줄까지 밖에 지원하지 않지만 혼자쓰니 문제없겠지..
https://workoutcal.herokuapp.com
08 Jun 2017
|
Django
Web service
Python
Scheduler
Material Design
발단
1일 1커밋을 생활화하기 위해 Django를 이용한 간단한 서비스를 만들기로 했다.
운동을 좋아하는 만큼 운동 스케쥴러를 작성하기로 했고, 프로젝트 목표와 개발 방향을 설정했다.
목표
- 스스로 사용할 만한 서비스 구축
- 깔끔한 디자인
- 확장성(?)
요구사항
- 일정을 추가할 수 있고, 일별/월별 보기가 가능할 것
- 당일 해야할 운동 종류를 표시하며, 해당 Todo 리스트에서 수행 여부를 표시할 수 있을 것
- 수행한 항목의 수행 시간에 비율을 그래프로 출력할 것
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를 이용했다.
그래프를 출력하기 위해서는 Plotly와 Matplotlib을 고민하다 최종적으로 matplotlib으로 결정하였다.
Django를 이용한 스케쥴러 제작 (2) - 구현
07 Jun 2017
|
Virtualenv
Python
Matplotlib
발단
가상환경을 이용한 로컬 프로젝트에서 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를 이용하여 가상환경을 이용하란다.
해결 방법
pip3 freeze > requirements.txt
로 기존 가상환경의 패키지 리스트를 추출한다.
python3 -m venv myvenv
로 myenv라는 새로운 가상환경을 만든다.
source myvenv/bin/activate
로 myenv 가상환경을 실행한다.
pip3 install -r requirements.txt
를 통해 전에 있던 가상환경에서 추출한 패키지 리스트를 다시 설치한다.
- 필요하다면 (기존 가상환경을 삭제한다.)
결과
06 Jun 2017
|
Github
Git
발단
로컬의 프로젝트를 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 브랜치 내용이 로컬의 브랜치 내용보다 최신이란다.
해결 방안
-
git push -f
를 통해 강제로 푸쉬한다.
사실 혼자 로컬에서 작업하는 프로젝트다보니 Github 내용이 더 최신이 된 것 자체가 이상한 상황이고,
로컬의 코드를 그냥 푸쉬해서 덮어씌워도 아무 문제 없으나 아무래도 찜찜한 것이 사실.
-
gitk HEAD @{u}
명령어로 upstream branch와 현재 헤드의 차이를 확인한다.
master와 origin 사이의 충돌이 생긴 이유가 명확해졌다.
project setting에서 github page를 생성했더니, 그에 대한 파일이 변경된 것이 로컬에서는 반영되지 않은 것.
원인을 파악했으니 편안한 맘으로 강제로 푸쉬할 수 있게 되었다.