概要
Flask で Controller (view) をクラスで管理してあとからルーティングルールに追加する方法を紹介します コントローラごとにクラスファイルを作成できるので管理が楽になることがあります
環境
- macOS 11.3.1
- Python 3.8.7
flask オブジェクトの作成とメインスクリプト
まずは flask オブジェクトの作成とそれを run するメインスクリプトを作成します flask app オブジェクトへの設定投入などは flask_app.py で行うようにします
vim main/__init__.py
from main.flask_app import FlaskApp
app = FlaskApp().create_flask_app()
- vim main/flask_app.py
from flask import Flask
from views.html_view import HtmlView
class FlaskApp():
def create_flask_app(self):
app = Flask(__name__)
return app
HTML を返却するコントローラをクラスで作成する
まずは単純な HTML を返却する View を作成します クラスとしてコントローラを作成する際のポイントは flask.views.View を継承したクラスを作成し dispatch_request を実装する必要がある点です
- vim views/html_view.py
from flask.views import View
class HtmlView(View):
def dispatch_request(self):
return "<html><body>hello</body></html>"
この View を flask app に登録します 登録する際は add_url_rule を使います
- vim main/flask_app.py
from flask import Flask
from views.html_view import HtmlView
class FlaskApp():
def create_flask_app(self):
app = Flask(__name__)
app.add_url_rule('/html', view_func=HtmlView.as_view('html_view'))
return app
これで OK です
動作確認
アプリを起動して確認してみます
- FLASK_APP=main pipenv run flask run
curl で確認すると html が返ってくることが確認できます
- curl -v localhost:5000/html
RESTful API のようなコントローラを作成する場合は
flask.views.View ではなく flask.views.MethodView を継承してクラスを作成します そうすることで dispatch_request ではなく get/post といった HTTP メソッド名で関数を定義することでそのメソッドごとのハンドラを定義することができます
- vim views/json_view.py
from flask.views import MethodView
from flask import jsonify
class JsonView(MethodView):
def get(self):
return jsonify({"method":"get"})
def post(self):
return jsonify({"method":"post"})
これを add_url_rule で登録します メソッドは複数登録できますがパスと View は 1対1 の関係なので注意してください
- vim main/flask_app.py
from flask import Flask
from views.html_view import HtmlView
from views.json_view import JsonView
class FlaskApp():
def create_flask_app(self):
app = Flask(__name__)
app.add_url_rule('/html', view_func=HtmlView.as_view('html_view'))
app.add_url_rule('/json', view_func=JsonView.as_view('json_view'))
return app
動作確認
先程同様にアプリを起動して動作確認しましょう
- FLASK_APP=main pipenv run flask run
curl で確認します
- curl -XGET localhost:5000/json
- curl -XPOST localhost:5000/json
View 生成時にコンストラクタを使って DI することもできる
単純に View に引数付きで __init__
を実装しましょう
そして as_view で渡したい値を指定することで View のクラスのフィールドとして扱うことができます
- vim views/json_view.py
from flask.views import MethodView
from flask import jsonify
class JsonView(MethodView):
def __init__(self, method_name):
self.method_name = method_name
def get(self):
return jsonify({"method":self.method_name})
def post(self):
return jsonify({"method":self.method_name})
- vim main/flask_app.py
from flask import Flask
from views.html_view import HtmlView
from views.json_view import JsonView
class FlaskApp():
def create_flask_app(self):
app = Flask(__name__)
app.add_url_rule('/html', view_func=HtmlView.as_view('html_view'))
method_name = "HOGE"
app.add_url_rule('/json', view_func=JsonView.as_view('json_view', method_name))
return app
先ほどと同じように動作確認すれば値が変わっていることが確認できると思います
最後に
app.route を使う方法がメジャーだとは思いますが正直 View を使うほうが実用性はあると思います
flask の GettingStarted が app.route を使う方法なのでなかなかこの方法にたどり着かないのが悲しい感じです
0 件のコメント:
コメントを投稿