DjangoとFlaskはそれぞれPythonのWebサービスを作るためのフレームワーク。
Flaskはシンプルで使いやすいけど、DBが絡んでくるとDjangoの便利なAdmin管理画面を使いたくなる。
こんな記事を見つけた。普段はFlaskのAPIサーバだけ立ち上げて、DBの中身を触りたい時だけDjangoを立ち上げるという事をやってみたくなった。
要件
- Ubuntu
環境構築
$ sudo apt install virtualenv
$ virtualenv env -p python3
$ source env/bin/activate
$ pip install django flask
Django構築
$ django-admin startproject djangoflask
$ ./manage.py migrate
$ ./manage.py createsuperuser
起動確認。以下のコマンドでテストサーバを立ち上げてhttp://127.0.0.1:8000/admin
で管理画面にアクセスできるか。
$ ./manage.py runserver
アプリケーションの追加。
$ django-admin startapp flaskapp
INSTALLED_APPS = [
...
'flaskapp',
]
適当にモデルを作ってみる例。
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=100, default='')
body = models.TextField(max_length=500, default='')
def __str__(self):
return self.title
$ ./manage.py makemigrations flaskapp
$ ./manage.py migrate
from django.contrib import admin
from .models import Post
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
pass
管理画面にアクセスしてPostを編集出来るか。
Flask構築
Djangoのモデルクラスが使えるように先頭でごにょごにょする。
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djangoflask.settings")
from django.apps import apps
from django.conf import settings
apps.populate(settings.INSTALLED_APPS)
from flask import Flask, jsonify
from .models import Post
def create_app():
app = Flask(__name__)
return app
app = create_app()
@app.route('/')
def index():
return "THIS IS FLASK INDEX PAGE."
@app.route('/<int:post_id>')
def post(post_id):
post = Post.objects.filter(id=post_id).values().first()
return jsonify(post)
$ ./manage.py runserver
でDjangoのテストサーバが立ち上がるので、$ ./manage.py flask
でFlaskのテストサーバが立ち上がるようにしてみる。
#!/usr/bin/env python
import os
import sys
def exec_django():
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djangoflask.settings")
if len(sys.argv) > 1 and sys.argv[1] == "flask":
from flaskapp.flask import app
app.run()
else:
exec_django()
Flaskのテストサーバを起動してhttp://127.0.0.1:5000/1
でPostデータにアクセス出来るか。
$ ./manage.py flask
違うターミナルでDjangoのテストサーバも立ち上げて異なるポートでDB管理画面を開きながらAPIサーバにアクセスできるか。
本番サーバ(nginx+uWSGI)の準備
本番サーバの公開にはnginxとuWSGIを使う。
$ sudo apt install nginx
$ pip install uwsgi
もしuWSGIのインストールでException: you need a C compiler to build uWSGI
と言われた場合は、
$ sudo apt install build-essential
もしuWSGIのインストールでfatal error: Python.h: そのようなファイルやディレクトリはありません
と言われた場合は、
sudo apt install python3-dev
起動ファイルの作成。
[uwsgi]
module = djangoflask.wsgi:application
master = true
processes = 1
socket = /tmp/django_uwsgi.sock
chmod-socket = 666
vacuum = true
die-on-term = true
[uwsgi]
module = flaskapp.flask:app
master = true
processes = 1
socket = /tmp/flask_uwsgi.sock
chmod-socket = 666
vacuum = true
die-on-term = true
設定の追加。
...
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
nginxの設定。
server {
listen 80;
listen [::]:80;
server_name example.wakin.site;
location / {
include uwsgi_params;
uwsgi_pass unix:///tmp/flask_uwsgi.sock;
}
location /admin {
include uwsgi_params;
uwsgi_pass unix:///tmp/django_uwsgi.sock;
}
location /static/ {
alias /path/to/djangoflask/static/;
}
}
nginxの再起動
$ sudo systemctl restart nginx
各本番サーバを起動してアクセスしてみる。
$ uwsgi --ini django_uwsgi.ini
$ uwsgi --ini flask_uwsgi.ini
アクセス出来れば、ひとまずタイトルの題目は完了。
supervisorでデーモン化
本番サーバの起動をデーモン化しておく。
$ sudo apt install supervisor
設定ファイルの作成。
[program:django] ; プロセスの名前
directory=/path/to/djangoflask ; 作業ディレクトリ
command=/path/to/env/bin/uwsgi --ini django_uwsgi.ini ; 起動コマンド
numprocs=1 ; 起動インスタンス数?
autostart=true ; autostartする
autorestart=true ; 自動で再起動させる
user=*** ; 起動ユーザ
redirect_stderr=true ; 標準エラーを出力する
stdout_logfile=/var/log/supervisor/django.log ; ログファイルの出力先
[program:flask] ; プロセスの名前
directory=/path/tp/djangoflask ; 作業ディレクトリ
command=/path/to/env/bin/uwsgi --ini flask_uwsgi.ini ; 起動コマンド
numprocs=1 ; 起動インスタンス数?
autostart=true ; autostartする
autorestart=true ; 自動で再起動させる
user=*** ; 起動ユーザ
redirect_stderr=true ; 標準エラーを出力する
stdout_logfile=/var/log/supervisor/flask.log ; ログファイルの出力先
設定ファイルの再読み込み。
$ sudo supervisorctl reload
プロセスの確認。
$ sudo supervisorctl status
止めるときは、
$ sudo supervisorctl stop <プロセス名>
立ち上げるときは、
$ sudo supervisorctl start <プロセス名>
アクセスログ等は/var/log/supervisor/*.log
に書き込まれる。
普段はdjango
は止めておき、DBの管理画面を開きたい時だけ立ち上げる運用が出来る。