くろねこ日記

ソフトウェアに関する技術メモが多いです.

フレームワーク素人がFlask触ってみた

こんにちは

昨夜に引き続きブログを更新してみます. 前回の内容はこちら(http://kuroneko0208.hatenablog.com/entry/2013/11/26/034323)

今日は,昨晩更新したSinatraと同じ内容をPythonのFlaskで書きなおしてみました.

昨日と同じ流れで進めていきますね.

まずはHelloWorld

#coding:utf-8
from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "helloworld"

app.run()

flaskを利用するため最初の行で呼びだしてきております. 次に@という形でデコレータを表現しております. Sinatraとは若干書きかたが違うもののルートを示していることはおそらくSinatraをお使いのかたはわかるかと思います. Rubyの場合はreturnをつけなくても最後に記述した内容がreturnされるらしいのですが, Pythonにはそのような機能は無いはずですので(?)明示的に示しております. app.run()で実行を示しております.

ちゃんとしたhtmlページに表示させたい

昨夜見せた内容をPythonでディレクトリを構成すると次のようになります.

.
├── main.py
└── templates
    ├── index.html
    └── layout.html

実はPythonではMVCモデルと呼ばずにMVTモデルと言います. MVCでいうViewにあたるものがPythonではTemplatesなのです. ちょっとややこしいのですが,このようになっております. layout.htmlやindex.htmlはsinatra同様,共通部品を集めたものをlayout.htmlへ index.htmlが呼びだされたときだけに基本出力したいときにはindex.htmlへ記述します.

以下にmain.pyがlayout.htmlとindex.htmlを利用してウェブアプリケーションを立ち上げるコードを示します.

main.py

#coding:utf-8

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html',titlename="helloworld")

app.run()

layout.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>{{ title }}</title>
</head>
{% block body %}
{% endblock %}
</html>

index.html

{% extends "layout.html" %}
{% block body %}
<h2> テスト </h2>
{% endblock %}

まずmain.pyから説明していきますと,importやindex関数の中にreturn render_template('index.html',title="helloworld")があるかと思います. こちらの関数でtemplateエンジンのhtmlをレンダリングするように命令しています. 今回呼びたいのがindex.htmlで,タイトルが"helloworld"としたのでこのようになりました.

では次はlayout.htmlについて見ていきます. こちらは{{ title }}{% blockbody %}'から'{% endblock %}があるかと思います. こちらがテンプレートエンジンの書き方になっておりまして,{{ なにかの変数 }}という形で書くことでmain.pyで渡した変数を呼びだせます. {% blockbody %}{% endblock %}についてはsinatraでいうところのyieldと言ったところです.ようするにmain.pyの書き方ではindex.htmlが呼ばれておりますから,この場合index.htmlの内容が出力されます.

index.htmlについて見ていきましょう. {% extends "layout.html" %}で共通化部品(親のこと)を指定しています. {% block body %}{% endblock %}で囲ったところが呼び出されるようになっておりますから,main.pyを実行するとh2要素タグのサイズの「テスト」という文字列が画面に出てきます.

htmlからテキストボックスの内容をPythonに送信

次に昨日もやったテキストボックスの内容をpostでpythonに渡して処理させるコードを書きます. 昨日と同様にタイトルを逐一書きかえるというものとしました.

では以下コード main.py

#coding:utf-8

from flask import Flask, render_template,request

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html',title="helloworld")


@app.route('/sendtext', methods=['POST'])
def sendtext():
    return render_template('index.html',title=request.form['message'])

app.run()

index.html

{% extends "layout.html" %}
{% block body %}
<h2> テスト </h2>
<form method="post" action="/sendtext">
    <input type="text" name="message"><input type="submit" value="Send">
</form>
{% endblock %}

layout.html

先程と同様なので省略

main.pyから見ていきますと,postで受けとるのに@app.route('/sendtext', methods=['POST'])としていますね.実は第二引数としてmethods=['POST']を書けばポストの処理となります. それをrequest.form['message']という形でindex.htmlから送られてくるだろう'message'を受けとってtitleに代入して再びレンダリングしています.

一応最後に,index.htmlを見ますと通常のhtmlらしく"message"というテキストボックスとSendというボタンがあります.テキストボックスで書いた内容を/sendtextに向けてpostで送信するというものとなっております.

少し感想

RubySinatraPythonのFlaskの二つを試した感想として,Sinatraのほうがウェブ上での文献の数が非常に多く,Rubyをお使いのかたはFlaskを触る利点があまりないかもしれません.僕自身もPythonばかり使ってきましたが,Sinatraの文献の多さやとっつきやすさで2日に分けた記事を書くことができました.

Flaskの場合はまだまだ日本語記事が少ないことなどがありまして,調べにくいのですが,機能面で言えば,基本的にはSinatraに見劣りしないくらいのフレームワークだと思います.Pythonを書いてきた人にとっては重要なリソースもあるでしょうから,わざわざSinatraを触る必要がないかもしれません.ただ,僕のようにフレームワーク初心者にとっては,Sinatraの文献の数に助けられ,結果的にFlaskで簡単なアプリケーションを作るまでいけましたので,Sinatraもおすすめです.

そのようなわけで結論として,Ruby使いはFlaskを使う利点が見あたらないが,Python使いにとってはどちらも学んだほうが良いと言ったところでしょうか.