LoginSignup
12
18

More than 5 years have passed since last update.

DjangoとFlaskを合わせて使う

Posted at

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
djangoflask/djangoflask.py
INSTALLED_APPS = [
    ...
    'flaskapp',
]

適当にモデルを作ってみる例。

flaskapp/models.py
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
flaskapp/admin.py
from django.contrib import admin
from .models import Post

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
    pass

管理画面にアクセスしてPostを編集出来るか。

Flask構築

Djangoのモデルクラスが使えるように先頭でごにょごにょする。

flaskapp/flask.py
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のテストサーバが立ち上がるようにしてみる。

manage.py
#!/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

起動ファイルの作成。

django_uwsgi.ini
[uwsgi]
module = djangoflask.wsgi:application
master = true
processes = 1
socket = /tmp/django_uwsgi.sock
chmod-socket = 666
vacuum = true
die-on-term = true
flask_uwsgi.ini
[uwsgi]
module = flaskapp.flask:app
master = true
processes = 1
socket = /tmp/flask_uwsgi.sock
chmod-socket = 666
vacuum = true
die-on-term = true

設定の追加。

djangoflask/settings.py
...
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

nginxの設定。

/etc/nginx/conf.d/djangoflask.conf
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

設定ファイルの作成。

/etc/supervisor/conf.d/django.conf
[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  ; ログファイルの出力先
/etc/supervisor/conf.d/flask.conf
[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の管理画面を開きたい時だけ立ち上げる運用が出来る。

12
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
18