Flask-quick-guide
フラスコ–概要
Web Frameworkとは何ですか?
Web Application Frameworkまたは単にWeb Frameworkは、プロトコルやスレッド管理などの低レベルの詳細を気にすることなく、Webアプリケーション開発者がアプリケーションを作成できるようにするライブラリとモジュールのコレクションを表します。
フラスコとは何ですか?
FlaskはPythonで書かれたWebアプリケーションフレームワークです。 Poccoという名前の国際的なPython愛好家グループを率いる Armin Ronacher によって開発されました。 Flaskは、Werkzeug WSGIツールキットとJinja2テンプレートエンジンに基づいています。 どちらもPoccoプロジェクトです。
WSGI
Web Server Gateway Interface(WSGI)は、Python Webアプリケーション開発の標準として採用されています。 WSGIは、WebサーバーとWebアプリケーション間のユニバーサルインターフェイスの仕様です。
ヴェルクゼウグ
これは、要求、応答オブジェクト、およびその他のユーティリティ機能を実装するWSGIツールキットです。 これにより、その上にWebフレームワークを構築できます。 Flaskフレームワークは、そのベースの1つとしてWerkzeugを使用します。
ジンジャ2
Jinja2は、Python用の人気のあるテンプレートエンジンです。 Webテンプレートシステムは、テンプレートを特定のデータソースと組み合わせて、動的なWebページをレンダリングします。
フラスコは、多くの場合、マイクロフレームワークと呼ばれます。 これは、アプリケーションのコアをシンプルかつ拡張可能にすることを目的としています。 Flaskには、データベース処理用の組み込み抽象化レイヤーがなく、検証サポートもありません。 代わりに、Flaskはそのような機能をアプリケーションに追加する拡張機能をサポートしています。 人気のあるFlask拡張機能の一部については、チュートリアルの後半で説明します。
フラスコ–環境
前提条件
通常、FlaskのインストールにはPython 2.6以降が必要です。 Flaskとその依存関係はPython 3(Python 3.3以降)で正常に機能しますが、多くのFlask拡張機能では適切にサポートされていません。 そのため、FlaskはPython 2.7にインストールすることをお勧めします。
開発環境のvirtualenvをインストールする
*virtualenv* は、仮想Python環境ビルダーです。 ユーザーが複数のPython環境を並べて作成するのに役立ちます。 これにより、異なるバージョンのライブラリ間の互換性の問題を回避できます。
次のコマンドは virtualenv をインストールします
pip install virtualenv
このコマンドには管理者権限が必要です。 Linux/Mac OSでは、 pip の前に sudo を追加します。 Windowsを使用している場合は、管理者としてログインします。 Ubuntuでは、パッケージマネージャーを使用して virtualenv をインストールできます。
Sudo apt-get install virtualenv
インストールすると、新しい仮想環境がフォルダーに作成されます。
mkdir newproj
cd newproj
virtualenv venv
対応する環境をアクティブにするには、 Linux/OS X で、次を使用します-
venv/bin/activate
*Windows* では、以下を使用できます
venv\scripts\activate
これで、Flaskをこの環境にインストールする準備が整いました。
pip install Flask
上記のコマンドは、システム全体のインストール用の仮想環境なしで直接実行できます。
フラスコ–アプリケーション
*Flask* インストールをテストするには、エディターで次のコードを *Hello.py* として入力します。
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World’
if __name__ == '__main__':
app.run()
プロジェクトへのフラスコモジュールのインポートは必須です。 Flaskクラスのオブジェクトは、 WSGI アプリケーションです。
Flaskコンストラクターは、* currentモジュール(name)*の名前を引数として取ります。
Flaskクラスの* route()*関数はデコレータであり、関連付けられた関数を呼び出すURLをアプリケーションに通知します。
app.route(rule, options)
- rule パラメーターは、関数とのURLバインディングを表します。
- options は、基になるRuleオブジェクトに転送されるパラメーターのリストです。
上記の例では、 ’/’ URLは* hello_world()*関数にバインドされています。 したがって、Webサーバーのホームページをブラウザーで開くと、この関数の出力がレンダリングされます。
最後に、Flaskクラスの* run()*メソッドは、ローカル開発サーバーでアプリケーションを実行します。
app.run(host, port, debug, options)
すべてのパラメーターはオプションです
Sr.No. | Parameters & Description |
---|---|
1 |
host リッスンするホスト名。 デフォルトは127.0.0.1(localhost)です。 サーバーを外部で使用できるようにするには、「0.0.0.0」に設定します |
2 |
port デフォルトは5000 |
3 |
debug デフォルトはfalseです。 trueに設定されている場合、デバッグ情報を提供します |
4 |
options 基礎となるWerkzeugサーバーに転送されます。 |
上記の Python スクリプトは、Pythonシェルから実行されます。
Python Hello.py
Pythonシェルのメッセージはそれを知らせます
*Running on http://127.0.0.1:5000/(Press CTRL+C to quit)
ブラウザで上記のURL* (localhost:5000)*を開きます。 *「Hello World」*メッセージが表示されます。
デバッグモード
*Flask* アプリケーションは、* run()*メソッドを呼び出すことにより開始されます。 ただし、アプリケーションの開発中は、コードの変更ごとに手動で再起動する必要があります。 この不便を避けるには、*デバッグサポート*を有効にしてください。 コードが変更されると、サーバーはそれ自体をリロードします。 また、アプリケーション内のエラーを追跡するための便利なデバッガも提供します。
デバッグ*モードを有効にするには、 *application オブジェクトの debug プロパティを True に設定してから、実行するか、デバッグパラメーターを* run()*メソッドに渡します。
app.debug = True
app.run()
app.run(debug = True)
フラスコ–ルーティング
最新のWebフレームワークでは、ルーティング手法を使用して、ユーザーがアプリケーションのURLを記憶できるようにします。 ホームページから移動することなく、目的のページに直接アクセスすると便利です。
Flaskの* route()*デコレータは、URLを関数にバインドするために使用されます。 たとえば-
@app.route(‘/hello’)
def hello_world():
return ‘hello world’
ここでは、URL ’/hello’ ルールが* hello_world()関数にバインドされています。 その結果、ユーザーが *http://localhost:5000/hello URLにアクセスすると、* hello_world()*関数の出力がブラウザーにレンダリングされます。
上記の例のように、アプリケーションオブジェクトの* add_url_rule()関数を使用してURLを関数にバインドすることもできます。 route()*が使用されます。
デコレータの目的は、次の表現によっても提供されます-
def hello_world():
return ‘hello world’
app.add_url_rule(‘/’, ‘hello’, hello_world)
フラスコ–可変ルール
ルールパラメータに変数部分を追加することにより、URLを動的に構築することができます。 この変数部分は、 <変数名> としてマークされます。 これは、ルールが関連付けられている関数にキーワード引数として渡されます。
次の例では、* route()デコレータのルールパラメータには、URL *’/hello’ に付加された <name> 変数部分が含まれています。 したがって、ブラウザで http://localhost:5000/hello/finddevguides が URL として入力されると、 'TutorialPoint' が引数として* hello()*関数に提供されます。
from flask import Flask
app = Flask(__name__)
@app.route('/hello/<name>')
def hello_name(name):
return 'Hello %s!' % name
if __name__ == '__main__':
app.run(debug = True)
上記のスクリプトを hello.py として保存し、Pythonシェルから実行します。 次に、ブラウザーを開き、URL * http://localhost:5000/hello/finddevguides。*を入力します。
次の出力がブラウザに表示されます。
Hello finddevguides!
デフォルトの文字列変数部分に加えて、次のコンバータを使用してルールを構築できます-
Sr.No. | Converters & Description |
---|---|
1 |
int 整数を受け入れます |
2 |
float 浮動小数点値の場合 |
3 |
path ディレクトリ区切り文字として使用されるスラッシュを受け入れます |
次のコードでは、これらすべてのコンストラクターが使用されています。
from flask import Flask
app = Flask(__name__)
@app.route('/blog/<int:postID>')
def show_blog(postID):
return 'Blog Number %d' % postID
@app.route('/rev/<float:revNo>')
def revision(revNo):
return 'Revision Number %f' % revNo
if __name__ == '__main__':
app.run()
Pythonシェルから上記のコードを実行します。 ブラウザーでURL http://localhost:5000/blog/11 にアクセスします。
指定された番号は、* show_blog()*関数の引数として使用されます。 ブラウザは次の出力を表示します-
Blog Number 11
ブラウザにこのURLを入力します- http://localhost:5000/rev/1.1
- revision()*関数は、引数として浮動小数点数を使用します。 次の結果がブラウザウィンドウに表示されます-
Revision Number 1.100000
FlaskのURLルールは、* Werkzeugの*ルーティングモジュールに基づいています。 これにより、形成されるURLが一意であり、Apacheが作成した先例に基づいていることが保証されます。
次のスクリプトで定義されたルールを考慮してください-
from flask import Flask
app = Flask(__name__)
@app.route('/flask')
def hello_flask():
return 'Hello Flask'
@app.route('/python/')
def hello_python():
return 'Hello Python'
if __name__ == '__main__':
app.run()
両方の規則は似ていますが、2番目の規則では、末尾のスラッシュ*(/)が使用されます。 その結果、それは正規のURLになります。 したがって、[。underline]# */python #または[.underline]# /python/ #を使用しても同じ出力が返されます。 ただし、最初のルールの場合、[。underline]# /flask/ #URLは[.underline]# 404 Not Found #ページになります。 Flask-url-building
Flask – HTTPメソッド
HTTPプロトコルは、World Wide Webでのデータ通信の基盤です。 このプロトコルでは、指定されたURLからデータを取得するさまざまな方法が定義されています。
次の表は、さまざまなhttpメソッドをまとめています-
Sr.No. | Methods & Description |
---|---|
1 |
GET 暗号化されていない形式でデータをサーバーに送信します。 最も一般的な方法。 |
2 |
HEAD GETと同じですが、応答本文はありません |
3 |
POST HTMLフォームデータをサーバーに送信するために使用されます。 POSTメソッドによって受信されたデータは、サーバーによってキャッシュされません。 |
4 |
PUT ターゲットリソースの現在のすべての表現を、アップロードされたコンテンツで置き換えます。 |
5 |
DELETE URLで指定されたターゲットリソースの現在の表現をすべて削除します |
デフォルトでは、Flaskルートは GET リクエストに応答します。 ただし、この設定は、* route()*デコレータにメソッド引数を提供することで変更できます。
URLルーティングでの POST メソッドの使用方法を示すために、最初にHTMLフォームを作成し、 POST メソッドを使用してフォームデータをURLに送信します。
次のスクリプトをloginlとして保存します
<html>
<body>
<form action = "http://localhost:5000/login" method = "post">
<p>Enter Name:</p>
<p><input type = "text" name = "nm"/></p>
<p><input type = "submit" value = "submit"/></p>
</form>
</body>
</html>
次に、Pythonシェルで次のスクリプトを入力します。
from flask import Flask, redirect, url_for, request
app = Flask(__name__)
@app.route('/success/<name>')
def success(name):
return 'welcome %s' % name
@app.route('/login',methods = ['POST', 'GET'])
def login():
if request.method == 'POST':
user = request.form['nm']
return redirect(url_for('success',name = user))
else:
user = request.args.get('nm')
return redirect(url_for('success',name = user))
if __name__ == '__main__':
app.run(debug = True)
開発サーバーの実行が開始されたら、ブラウザーで loginl を開き、テキストフィールドに名前を入力して、[送信]をクリックします。
フォームデータは、formタグのaction節のURLにPOSTされます。
*http://localhost/login* は* login()*関数にマッピングされます。 サーバーは *POST* メソッドによってデータを受信しているため、フォームデータから取得した「nm」パラメーターの値は次のように取得されます-
user = request.form['nm']
変数部分として ’/success’ URLに渡されます。 ブラウザのウィンドウに welcome メッセージが表示されます。
*loginl* でメソッドパラメータを *‘GET’* に変更し、ブラウザでもう一度開きます。 サーバーで受信されるデータは *GET* メソッドによるものです。 「nm」パラメータの値は次のように取得されます-
User = request.args.get(‘nm’)
ここで、 args は、フォームパラメータとそれに対応する値のペアのリストを含む辞書オブジェクトです。 「nm」パラメーターに対応する値は、以前と同様に「/success」URLに渡されます。
フラスコ–テンプレート
特定のURLにバインドされた関数の出力をHTML形式で返すことができます。 たとえば、次のスクリプトでは、* hello()関数は *'hello World' に <h1> タグを付加してレンダリングします。
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return '<html><body><h1>Hello World</h1></body></html>'
if __name__ == '__main__':
app.run(debug = True)
ただし、PythonコードからHTMLコンテンツを生成することは、特に変数データや条件やループなどのPython言語要素を配置する必要がある場合は面倒です。 これには、HTMLから頻繁にエスケープする必要があります。
ここで、Flaskのベースとなっている Jinja2 テンプレートエンジンを利用できます。 関数からハードコードHTMLを返す代わりに、* render_template()*関数によってHTMLファイルをレンダリングできます。
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return render_template(‘hellol’)
if __name__ == '__main__':
app.run(debug = True)
Flaskは、このスクリプトが存在するのと同じフォルダー内のテンプレートフォルダーでHTMLファイルを見つけようとします。
- アプリケーションフォルダー
- Hello.py
- テンプレート
- こんにちは
- 「ウェブテンプレートシステム」*という用語は、変数データを動的に挿入できるHTMLスクリプトの設計を指します。 Webテンプレートシステムは、テンプレートエンジン、ある種のデータソース、およびテンプレートプロセッサで構成されます。
Flaskは jinja2 テンプレートエンジンを使用します。 Webテンプレートには、変数と式(これらの場合はPython式)のHTML構文が散在するプレースホルダーが含まれており、テンプレートのレンダリング時に値が置き換えられます。
次のコードは、テンプレートフォルダーに hellol として保存されます。
<!doctype html>
<html>
<body>
<h1>Hello {{ name }}!</h1>
</body>
</html>
次に、Pythonシェルから次のスクリプトを実行します。
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/hello/<user>')
def hello_name(user):
return render_template('hellol', name = user)
if __name__ == '__main__':
app.run(debug = True)
開発サーバーの実行が開始されたら、ブラウザーを開いてURLを入力します- http://localhost:5000/hello/mvl
URLの*変数*部分は、 \ {\ {name}} プレースホルダーに挿入されます。
*jinja2* テンプレートエンジンは、HTMLからのエスケープに次の区切り文字を使用します。
- \ {%… ステートメントの%}
- \ {\ {… }}は、テンプレートの出力に出力する式
- \ {#… #}テンプレート出力に含まれないコメントの場合 *#… ##行ステートメント
次の例では、テンプレートでの条件ステートメントの使用を示しています。* hello()関数のURLルールは整数パラメーターを受け入れます。 *hellol テンプレートに渡されます。 その中で、受け取った数値(マーク)の値が比較され(50より大きいか小さい)、それに応じてHTMLが条件付きでレンダリングされます。
Pythonスクリプトは次のとおりです-
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/hello/<int:score>')
def hello_name(score):
return render_template('hellol', marks = score)
if __name__ == '__main__':
app.run(debug = True)
*hellol* のHTMLテンプレートスクリプトは次のとおりです-
<!doctype html>
<html>
<body>
{% if marks>50 %}
<h1> Your result is pass!</h1>
{% else %}
<h1>Your result is fail</h1>
{% endif %}
</body>
</html>
条件文 if-else および endif は、区切り文字 \ {%..%} で囲まれていることに注意してください。
Pythonスクリプトを実行し、URL http://localhost/hello/60 にアクセスしてから、 http://localhost/hello/30 にアクセスして、条件に応じて変化するHTMLの出力を確認します。
Pythonループ構造は、テンプレート内でも使用できます。 次のスクリプトでは、* result()関数は、ブラウザーでURL *http://localhost:5000/result が開かれると、テンプレート resultsl に辞書オブジェクトを送信します。
*resultl* のテンプレート部分では、* forループ*を使用して、辞書オブジェクト *result \ {}* のキーと値のペアをHTMLテーブルのセルとしてレンダリングします。
Pythonシェルから次のコードを実行します。
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/result')
def result():
dict = {'phy':50,'che':60,'maths':70}
return render_template('resultl', result = dict)
if __name__ == '__main__':
app.run(debug = True)
次のHTMLスクリプトを resultl としてテンプレートフォルダーに保存します。
<!doctype html>
<html>
<body>
<table border = 1>
{% for key, value in result.items() %}
<tr>
<th> {{ key }} </th>
<td> {{ value }} </td>
</tr>
{% endfor %}
</table>
</body>
</html>
ここでも、 For ループに対応するPythonステートメントは\ {%..%}で囲まれていますが、式 keyおよびvalue は \ {\ {}} 内に配置されています。
開発の実行が開始されたら、ブラウザーで http://localhost:5000/result を開き、次の出力を取得します。
フラスコ–静的ファイル
Webアプリケーションでは、多くの場合、Webページの表示をサポートする javascript ファイルや CSS ファイルなどの静的ファイルが必要です。 通常、Webサーバーはそれらを提供するように構成されていますが、開発中、これらのファイルはパッケージの_static_フォルダーまたはモジュールの隣から提供され、アプリケーションの /static で利用可能になります。
静的ファイルのURLを生成するために、特別なエンドポイント「静的」が使用されます。
次の例では、 hello.js で定義された javascript 関数が、Flaskアプリケーションの ‘/’ URLでレンダリングされる indexl のHTMLボタンの OnClick イベントで呼び出されます。
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index():
return render_template("indexl")
if __name__ == '__main__':
app.run(debug = True)
*indexl* のHTMLスクリプトを以下に示します。
<html>
<head>
<script type = "text/javascript"
src = "{{ url_for('static', filename = 'hello.js') }}" ></script>
</head>
<body>
<input type = "button" onclick = "sayHello()" value = "Say Hello"/>
</body>
</html>
*hello.js* には* sayHello()*関数が含まれています。
function sayHello() {
alert("Hello World")
}
フラスコ–リクエストオブジェクト
クライアントのWebページからのデータは、グローバルリクエストオブジェクトとしてサーバーに送信されます。 リクエストデータを処理するには、Flaskモジュールからインポートする必要があります。
リクエストオブジェクトの重要な属性は以下のとおりです-
- フォーム-フォームパラメータとその値のキーと値のペアを含む辞書オブジェクトです。
- args -疑問符(?)の後のURLの一部であるクエリ文字列の解析されたコンテンツ。
- * Cookies-Cookieの名前と値を保持する辞書オブジェクト。
- ファイル-アップロードされたファイルに関するデータ。
- method -現在のリクエストメソッド。
Flask –フォームデータをテンプレートに送信
httpメソッドがURLルールで指定できることはすでに見ました。 トリガーされた関数によって受信された Form データは、それを辞書オブジェクトの形式で収集し、テンプレートに転送して、対応するWebページでレンダリングできます。
次の例では、 ‘/’ URLはフォームを持つWebページ(studentl)をレンダリングします。 入力されたデータは* result()関数をトリガーする *’/result’ URLに投稿されます。
- results()関数は、辞書オブジェクトの *request.form に存在するフォームデータを収集し、レンダリングするために resultl に送信します。
このテンプレートは、*フォーム*データのHTMLテーブルを動的にレンダリングします。
以下は、アプリケーションのPythonコードです-
from flask import Flask, render_template, request
app = Flask(__name__)
@app.route('/')
def student():
return render_template('studentl')
@app.route('/result',methods = ['POST', 'GET'])
def result():
if request.method == 'POST':
result = request.form
return render_template("resultl",result = result)
if __name__ == '__main__':
app.run(debug = True)
以下は studentl のHTMLスクリプトです。
<html>
<body>
<form action = "http://localhost:5000/result" method = "POST">
<p>Name <input type = "text" name = "Name"/></p>
<p>Physics <input type = "text" name = "Physics"/></p>
<p>Chemistry <input type = "text" name = "chemistry"/></p>
<p>Maths <input type ="text" name = "Mathematics"/></p>
<p><input type = "submit" value = "submit"/></p>
</form>
</body>
</html>
テンプレート*(resultl)*のコードを以下に示します-
<!doctype html>
<html>
<body>
<table border = 1>
{% for key, value in result.items() %}
<tr>
<th> {{ key }} </th>
<td> {{ value }} </td>
</tr>
{% endfor %}
</table>
</body>
</html>
Pythonスクリプトを実行し、ブラウザーにURL http://localhost:5000/ を入力します。
[送信]ボタンをクリックすると、フォームデータがHTMLテーブルの形式で*結果*にレンダリングされます。
フラスコ–クッキー
Cookieは、テキストファイルの形式でクライアントのコンピューターに保存されます。 その目的は、クライアントの使用状況に関するデータを記憶して追跡し、訪問者のエクスペリエンスとサイトの統計を改善することです。
- リクエストオブジェクト*にはCookieの属性が含まれています。 これは、クライアントが送信したすべてのCookie変数とそれに対応する値の辞書オブジェクトです。 それに加えて、Cookieは、サイトの有効期限、パス、およびドメイン名も保存します。
Flaskでは、Cookieは応答オブジェクトに設定されます。 * make_response()関数を使用して、ビュー関数の戻り値から応答オブジェクトを取得します。 その後、応答オブジェクトの set_cookie()*関数を使用してCookieを保存します。
Cookieの読み取りは簡単です。 request.cookies 属性の* get()*メソッドは、Cookieの読み取りに使用されます。
次のFlaskアプリケーションでは、 ’/’ URLにアクセスすると簡単なフォームが開きます。
@app.route('/')
def index():
return render_template('indexl')
このHTMLページには1つのテキスト入力が含まれています。
<html>
<body>
<form action = "/setcookie" method = "POST">
<p><h3>Enter userID</h3></p>
<p><input type = 'text' name = 'nm'/></p>
<p><input type = 'submit' value = 'Login'/></p>
</form>
</body>
</html>
フォームは ’/setcookie’ URLに投稿されます。 関連するビュー関数は、Cookie名 userID を設定し、別のページをレンダリングします。
@app.route('/setcookie', methods = ['POST', 'GET'])
def setcookie():
if request.method == 'POST':
user = request.form['nm']
resp = make_response(render_template('readcookiel'))
resp.set_cookie('userID', user)
return resp
*‘readcookiel’* には、別のビュー関数* getcookie()*へのハイパーリンクが含まれています。この関数は、ブラウザーでCookie値を読み取って表示します。
@app.route('/getcookie')
def getcookie():
name = request.cookies.get('userID')
return '<h1>welcome '+name+'</h1>'
アプリケーションを実行し、 http://localhost:5000/ にアクセスします
クッキーを設定した結果はこのように表示されます-
リードバックCookieの出力を以下に示します。
フラスコ–セッション
Cookieと同様に、セッションデータはクライアントに保存されます。 セッションは、クライアントがサーバーにログインしてログアウトする時間間隔です。 このセッションで保持する必要があるデータは、クライアントブラウザーに保存されます。
各クライアントとのセッションには、セッションID *が割り当てられます。 セッションデータはCookieの上に保存され、サーバーはそれらに暗号的に署名します。 この暗号化のために、Flaskアプリケーションには定義済みの *SECRET_KEY が必要です。
セッションオブジェクトは、セッション変数と関連する値のキーと値のペアを含む辞書オブジェクトでもあります。
たとえば、 'username' セッション変数を設定するには、次のステートメントを使用します-
Session[‘username’] = ’admin’
セッション変数を解放するには、* pop()*メソッドを使用します。
session.pop('username', None)
次のコードは、Flaskでのセッション作業の簡単なデモです。 セッション変数 'username' が設定されていないため、URL ‘/’ はユーザーにログインを促すだけです。
@app.route('/')
def index():
if 'username' in session:
username = session['username']
return 'Logged in as ' + username + '<br>' + \
"<b><a href = '/logout'>click here to log out</a></b>"
return "You are not logged in <br><a href = '/login'></b>" + \
"click here to log in</b></a>"
ユーザーがGETメソッドを介して呼び出されるため、ユーザーがlogin()ビュー関数を「/login」に参照すると、ログインフォームが開きます。
フォームが ’/login’ にポストバックされ、セッション変数が設定されました。 アプリケーションは ’/’ にリダイレクトされます。 今回は、セッション変数 'username' が見つかりました。
@app.route('/login', methods = ['GET', 'POST'])
def login():
if request.method == 'POST':
session['username'] = request.form['username']
return redirect(url_for('index'))
return '''
<form action = "" method = "post">
<p><input type = text name = username/></p>
<p<<input type = submit value = Login/></p>
</form>
アプリケーションには、* logout()ビュー関数も含まれています。この関数は、セッション変数「ユーザー名」*をポップアウトします。 したがって、 *’/’ URLは再びオープニングページを表示します。
@app.route('/logout')
def logout():
# remove the username from the session if it is there
session.pop('username', None)
return redirect(url_for('index'))
アプリケーションを実行し、ホームページにアクセスします。 (アプリケーションの secret_key を設定してください)
from flask import Flask, session, redirect, url_for, escape, request
app = Flask(__name__)
app.secret_key = 'any random string’
出力は次のように表示されます。 リンク「*ここをクリックしてログイン」*をクリックします。
リンクは別の画面に送られます。 「admin」と入力します。
画面に*「管理者としてログイン」*というメッセージが表示されます。
フラスコ–リダイレクトとエラー
Flaskクラスには* redirect()*関数があります。 呼び出されると、応答オブジェクトを返し、指定されたステータスコードで別のターゲットの場所にユーザーをリダイレクトします。
- redirect()*関数のプロトタイプは以下のとおりです-
Flask.redirect(location, statuscode, response)
上記の機能では-
- location パラメーターは、応答をリダイレクトするURLです。
- statuscode はブラウザのヘッダーに送信され、デフォルトは302です。
- response パラメーターは、応答をインスタンス化するために使用されます。
次のステータスコードが標準化されています-
- HTTP_300_MULTIPLE_CHOICES
- HTTP_301_MOVED_PERMANENTLY
- HTTP_302_FOUND
- HTTP_303_SEE_OTHER
- HTTP_304_NOT_MODIFIED
- HTTP_305_USE_PROXY
- HTTP_306_RESERVED
- HTTP_307_TEMPORARY_REDIRECT
デフォルトのステータス*コードは *302 で、これは 'found' 用です。
次の例では、* redirect()*関数を使用して、ログイン試行が失敗したときにログインページを再度表示します。
from flask import Flask, redirect, url_for, render_template, request
# Initialize the Flask application
app = Flask(__name__)
@app.route('/')
def index():
return render_template('log_inl')
@app.route('/login',methods = ['POST', 'GET'])
def login():
if request.method == 'POST' and request.form['username'] == 'admin' :
return redirect(url_for('success'))
else:
return redirect(url_for('index'))
@app.route('/success')
def success():
return 'logged in successfully'
if __name__ == '__main__':
app.run(debug = True)
Flaskクラスには、エラーコード付きの* abort()*関数があります。
Flask.abort(code)
- コード*パラメータは、次の値のいずれかを取ります-
- 400 -不正なリクエストの場合
- 401 -認証されていない場合
- 403 -Forbiddenの場合
- 404 -見つかりません
- 406 -受け入れられない
- 415 -サポートされていないメディアタイプ
- 429 -リクエストが多すぎる
上記のコードの* login()関数に少し変更を加えましょう。 ログインページを再表示する代わりに、「非認証」ページを表示する場合は、 abort(401)*の呼び出しに置き換えます。
from flask import Flask, redirect, url_for, render_template, request, abort
app = Flask(__name__)
@app.route('/')
def index():
return render_template('log_inl')
@app.route('/login',methods = ['POST', 'GET'])
def login():
if request.method == 'POST':
if request.form['username'] == 'admin' :
return redirect(url_for('success'))
else:
abort(401)
else:
return redirect(url_for('index'))
@app.route('/success')
def success():
return 'logged in successfully'
if __name__ == '__main__':
app.run(debug = True)
フラスコ–メッセージの点滅
優れたGUIベースのアプリケーションは、相互作用に関するフィードバックをユーザーに提供します。 たとえば、デスクトップアプリケーションはダイアログまたはメッセージボックスを使用し、JavaScriptは同様の目的でアラートを使用します。
Flask Webアプリケーションでは、このような情報メッセージの生成は簡単です。 Flaskフレームワークのフラッシュシステムにより、1つのビューでメッセージを作成し、 next と呼ばれるビュー関数でレンダリングすることができます。
Flaskモジュールには* flash()*メソッドが含まれています。 通常はテンプレートである次のリクエストにメッセージを渡します。
flash(message, category)
ここに、
- message パラメータは、フラッシュされる実際のメッセージです。
- category パラメーターはオプションです。 「エラー」、「情報」または「警告」のいずれかです。
セッションからメッセージを削除するために、テンプレートは* get_flashed_messages()*を呼び出します。
get_flashed_messages(with_categories, category_filter)
両方のパラメーターはオプションです。 受信したメッセージにカテゴリがある場合、最初のパラメーターはタプルです。 2番目のパラメーターは、特定のメッセージのみを表示するのに役立ちます。
以下は、テンプレートで受信したメッセージをフラッシュします。
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
{{ message }}
{% endfor %}
{% endif %}
{% endwith %}
ここで、Flaskのフラッシュメカニズムを示す簡単な例を見てみましょう。 次のコードでは、 ’/’ URLがログインページへのリンクを表示し、フラッシュするメッセージはありません。
@app.route('/')
def index():
return render_template('indexl')
このリンクは、ログインフォームを表示する ’/login’ URLにユーザーを誘導します。 送信されると、* login()ビュー関数はユーザー名とパスワードを検証し、それに応じて「成功」メッセージを点滅させるか、「エラー」*変数を作成します。
@app.route('/login', methods = ['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != 'admin' or \
request.form['password'] != 'admin':
error = 'Invalid username or password. Please try again!'
else:
flash('You were successfully logged in')
return redirect(url_for('index'))
return render_template('loginl', error = error)
- エラー*の場合、ログインテンプレートはエラーメッセージとともに再表示されます。
ログイン
<!doctype html>
<html>
<body>
<h1>Login</h1>
{% if error %}
<p><strong>Error:</strong> {{ error }}
{% endif %}
<form action = "" method = post>
<dl>
<dt>Username:</dt>
<dd>
<input type = text name = username
value = "{{request.form.username }}">
</dd>
<dt>Password:</dt>
<dd><input type = password name = password></dd>
</dl>
<p><input type = submit value = Login></p>
</form>
</body>
</html>
一方、 login が成功すると、インデックステンプレートで成功メッセージがフラッシュされます。
インデクス
<!doctype html>
<html>
<head>
<title>Flask Message flashing</title>
</head>
<body>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul>
{% for message in messages %}
<li<{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<h1>Flask Message Flashing Example</h1>
<p>Do you want to <a href = "{{ url_for('login') }}">
<b>log in?</b></a></p>
</body>
</html>
Flaskメッセージフラッシュの例の完全なコードを以下に示します-
Flash.py
from flask import Flask, flash, redirect, render_template, request, url_for
app = Flask(__name__)
app.secret_key = 'random string'
@app.route('/')
def index():
return render_template('indexl')
@app.route('/login', methods = ['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != 'admin' or \
request.form['password'] != 'admin':
error = 'Invalid username or password. Please try again!'
else:
flash('You were successfully logged in')
return redirect(url_for('index'))
return render_template('loginl', error = error)
if __name__ == "__main__":
app.run(debug = True)
上記のコードを実行すると、次のような画面が表示されます。
リンクをクリックすると、ログインページが表示されます。
ユーザー名とパスワードを入力します。
[ログイン]をクリックします。 「あなたは正常にログインしました」というメッセージが表示されます。
フラスコ–ファイルのアップロード
Flaskでのファイルアップロードの処理は非常に簡単です。 enctype属性が「multipart/form-data」に設定されたHTMLフォームが必要で、ファイルをURLにポストします。 URLハンドラーは、 request.files [] オブジェクトからファイルを取得し、目的の場所に保存します。
アップロードされた各ファイルは、実際に最終的な場所に保存される前に、まずサーバー上の一時的な場所に保存されます。 宛先ファイルの名前は、ハードコーディングするか、 request.files [file] オブジェクトのfilenameプロパティから取得できます。 ただし、* secure_filename()*関数を使用して安全なバージョンを取得することをお勧めします。
Flaskオブジェクトの構成設定で、デフォルトのアップロードフォルダーのパスとアップロードされるファイルの最大サイズを定義することができます。
app.config[‘UPLOAD_FOLDER’] | Defines path for upload folder |
app.config[‘MAX_CONTENT_PATH’] | Specifies maximum size of file yo be uploaded – in bytes |
次のコードには、テンプレートフォルダーから ‘uploadl’ を表示する ‘/upload’ URLルールと、アップロードプロセスを処理する* uploader()関数を呼び出す *‘/upload-file’ URLルールがあります。
- 「uploadl」*には、ファイル選択ボタンと送信ボタンがあります。
<html>
<body>
<form action = "http://localhost:5000/uploader" method = "POST"
enctype = "multipart/form-data">
<input type = "file" name = "file"/>
<input type = "submit"/>
</form>
</body>
</html>
以下に示す画面が表示されます。
ファイルを選択した後、[送信]をクリックします。 フォームのpostメソッドは ’/upload_file’ URLを呼び出します。 基礎となる関数* uploader()*が保存操作を実行します。
以下は、FlaskアプリケーションのPythonコードです。
from flask import Flask, render_template, request
from werkzeug import secure_filename
app = Flask(__name__)
@app.route('/upload')
def upload_file():
return render_template('uploadl')
@app.route('/uploader', methods = ['GET', 'POST'])
def upload_file():
if request.method == 'POST':
f = request.files['file']
f.save(secure_filename(f.filename))
return 'file uploaded successfully'
if __name__ == '__main__':
app.run(debug = True)
フラスコ–拡張機能
コア機能には Werkzeug に基づくWSGIおよび Jinja2 に基づくテンプレートエンジンが含まれているため、Flaskはマイクロフレームワークと呼ばれることがよくあります。 さらに、Flaskフレームワークは、 JSON 、静的ファイルなどのWebヘルパーだけでなく、Cookieとセッションもサポートしています。 明らかに、これは本格的なWebアプリケーションの開発には十分ではありません。 ここで、Flask拡張機能が登場します。 Flask拡張機能は、Flaskフレームワークの拡張性を提供します。
多数のFlask拡張機能が利用可能です。 Flask拡張機能は、特定のタイプのサポートをFlaskアプリケーションに追加するPythonモジュールです。 Flask Extension Registryは、利用可能な拡張機能のディレクトリです。 必要な拡張機能は、 pip ユーティリティでダウンロードできます。
このチュートリアルでは、次の重要なFlask拡張機能について説明します-
- Flask Mail -FlaskアプリケーションへのSMTPインターフェイスを提供
- Flask WTF -WTFormsのレンダリングと検証を追加
- Flask SQLAlchemy -FlaskアプリケーションにSQLAlchemyサポートを追加
- Flask Sijax -Sijaxのインターフェース-WebアプリケーションでAJAXを使いやすくするPython/jQueryライブラリ
通常、各タイプの拡張機能は、その使用法に関する広範なドキュメントを提供します。 拡張機能はPythonモジュールであるため、使用するには拡張機能をインポートする必要があります。 Flask拡張機能は通常、flask-fooという名前です。 インポートするには、
from flask_foo import [class, function]
0.7以降のFlaskのバージョンでは、構文を使用することもできます-
from flask.ext import foo
この使用法では、互換性モジュールをアクティブにする必要があります。 flaskext_compat.pyを実行することでインストールできます
import flaskext_compat
flaskext_compat.activate()
from flask.ext import foo
フラスコ–メール
多くの場合、Webベースのアプリケーションには、ユーザー/クライアントにメールを送信する機能が必要です。 Flask-Mail 拡張機能を使用すると、任意の電子メールサーバーと簡単なインターフェイスを簡単にセットアップできます。
最初に、Pipユーティリティを使用してFlask-Mail拡張機能をインストールする必要があります。
pip install Flask-Mail
次に、次のアプリケーションパラメータの値を設定して、Flask-Mailを設定する必要があります。
Sr.No | Parameters & Description |
---|---|
1 |
MAIL_SERVER 電子メールサーバーの名前/IPアドレス |
2 |
MAIL_PORT 使用するサーバーのポート番号 |
3 |
MAIL_USE_TLS Transport Security Layer暗号化を有効/無効にします |
4 |
MAIL_USE_SSL Secure Sockets Layer暗号化の有効化/無効化 |
5 |
MAIL_DEBUG デバッグのサポート。 デフォルトはFlaskアプリケーションのデバッグステータスです |
6 |
MAIL_USERNAME 送信者のユーザー名 |
7 |
MAIL_PASSWORD 送信者のパスワード |
8 |
MAIL_DEFAULT_SENDER デフォルトの送信者を設定します |
9 |
MAIL_MAX_EMAILS 送信するメールの最大数を設定します |
10 |
MAIL_SUPPRESS_SEND app.testingがtrueに設定されている場合、送信は抑制されます |
11 |
MAIL_ASCII_ATTACHMENTS trueに設定されている場合、ASCIIに変換された添付ファイル名 |
flask-mailモジュールには、以下の重要なクラスの定義が含まれています。
メールクラス
メールメッセージングの要件を管理します。 クラスのコンストラクタは次の形式を取ります-
flask-mail.Mail(app = None)
コンストラクターは、Flaskアプリケーションオブジェクトをパラメーターとして受け取ります。
Mailクラスのメソッド
Sr.No | Methods & Description |
---|---|
1 |
send() Messageクラスオブジェクトの内容を送信します |
2 |
connect() メールホストとの接続を開きます |
3 |
send_message() メッセージオブジェクトを送信します |
メッセージクラス
電子メールメッセージをカプセル化します。 メッセージクラスのコンストラクタにはいくつかのパラメータがあります-
flask-mail.Message(subject, recipients, body, html, sender, cc, bcc,
reply-to, date, charset, extra_headers, mail_options, rcpt_options)
メッセージクラスメソッド
- attach()*-メッセージに添付ファイルを追加します。 このメソッドは、次のパラメータを取ります-
- filename -添付するファイルの名前
- content_type -MIMEタイプのファイル
- data -生ファイルデータ
- disposition -コンテンツの配置(ある場合)。
- add_recipient()*-メッセージに別の受信者を追加します
次の例では、GoogleのgmailサービスのSMTPサーバーがFlask-Mail構成のMAIL_SERVERとして使用されます。
- ステップ1 *-コード内のflask-mailモジュールからMailおよびMessageクラスをインポートします。
from flask_mail import Mail, Message
- ステップ2 *-Flask-Mailは次の設定に従って構成されます。
app.config['MAIL_SERVER']='smtp.gmail.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USERNAME'] = '[email protected]'
app.config['MAIL_PASSWORD'] = '*****'
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USE_SSL'] = True
- ステップ3 *-Mailクラスのインスタンスを作成します。
mail = Mail(app)
ステップ4 *-URLルール( ‘/’)*によってマップされたPython関数でメッセージオブジェクトを設定します。
@app.route("/")
def index():
msg = Message('Hello', sender = '[email protected]', recipients = ['[email protected]'])
msg.body = "This is the email body"
mail.send(msg)
return "Sent"
ステップ5 *-コード全体を以下に示します。 Pythonシェルで次のスクリプトを実行し、 http://localhost:5000/.*にアクセスします
from flask import Flask
from flask_mail import Mail, Message
app =Flask(__name__)
mail=Mail(app)
app.config['MAIL_SERVER']='smtp.gmail.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USERNAME'] = '[email protected]'
app.config['MAIL_PASSWORD'] = '*****'
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USE_SSL'] = True
mail = Mail(app)
@app.route("/")
def index():
msg = Message('Hello', sender = '[email protected]', recipients = ['[email protected]'])
msg.body = "Hello Flask message sent from Flask-Mail"
mail.send(msg)
return "Sent"
if __name__ == '__main__':
app.run(debug = True)
Gmailサービスの組み込みのセキュリティ機能により、このログイン試行がブロックされる場合があります。 セキュリティレベルを下げる必要がある場合があります。 Gmailアカウントにログインし、https://www.google.com/settings/security/lesssecureapps [this]リンクにアクセスしてセキュリティを低下させてください。
フラスコ– WTF
Webアプリケーションの重要な側面の1つは、ユーザーにユーザーインターフェイスを提供することです。 HTMLは <form> タグを提供します。これは、インターフェースの設計に使用されます。 テキスト入力、ラジオ、選択などの*フォーム*要素 適切に使用できます。
ユーザーが入力したデータは、GETメソッドまたはPOSTメソッドのいずれかによって、Httpリクエストメッセージの形式でサーバー側のスクリプトに送信されます。
- サーバー側のスクリプトは、http要求データからフォーム要素を再作成する必要があります。 したがって、実際には、フォーム要素を2回定義する必要があります(HTMLで1回、サーバー側スクリプトで1回)。
- HTMLフォームを使用する別の欠点は、フォーム要素を動的にレンダリングすることが(不可能ではないにしても)難しいことです。 HTML自体は、ユーザーの入力を検証する方法を提供しません。
ここで、柔軟なフォーム、レンダリング、および検証ライブラリである WTForms が役立ちます。 Flask-WTF拡張機能は、この WTForms ライブラリとのシンプルなインターフェースを提供します。
*Flask-WTF* を使用して、Pythonスクリプトでフォームフィールドを定義し、HTMLテンプレートを使用してそれらをレンダリングできます。 *WTF* フィールドに検証を適用することもできます。
このHTMLの動的生成がどのように機能するかを見てみましょう。
まず、Flask-WTF拡張機能をインストールする必要があります。
pip install flask-WTF
インストール済みパッケージには Form クラスが含まれており、ユーザー定義フォームの親として使用する必要があります。
*WTforms* パッケージには、さまざまなフォームフィールドの定義が含まれています。 一部の*標準フォームフィールド*を以下に示します。
Sr.No | Standard Form Fields & Description |
---|---|
1 |
TextField <input type = 'text'> HTMLフォーム要素を表します |
2 |
BooleanField <input type = 'checkbox'> HTMLフォーム要素を表します |
3 |
DecimalField 数値を小数で表示するためのテキストフィールド |
4 |
IntegerField 整数を表示するためのTextField |
5 |
RadioField <input type = 'radio'> HTMLフォーム要素を表します |
6 |
SelectField 選択フォーム要素を表します |
7 |
TextAreaField <testarea> htmlフォーム要素を表します |
8 |
PasswordField <input type = 'password'> HTMLフォーム要素を表します |
9 |
SubmitField <input type = 'submit'>フォーム要素を表します |
たとえば、テキストフィールドを含むフォームは次のように設計することができます-
from flask_wtf import Form
from wtforms import TextField
class ContactForm(Form):
name = TextField("Name Of Student")
*'name'* フィールドに加えて、CSRFトークンの非表示フィールドが自動的に作成されます。 これは、 *Cross Site Request Forgery* 攻撃を防ぐためです。
レンダリングされると、これは以下に示すように同等のHTMLスクリプトになります。
<input id = "csrf_token" name = "csrf_token" type = "hidden"/>
<label for = "name">Name Of Student</label><br>
<input id = "name" name = "name" type = "text" value = ""/>
ユーザー定義フォームクラスはFlaskアプリケーションで使用され、フォームはテンプレートを使用してレンダリングされます。
from flask import Flask, render_template
from forms import ContactForm
app = Flask(__name__)
app.secret_key = 'development key'
@app.route('/contact')
def contact():
form = ContactForm()
return render_template('contactl', form = form)
if __name__ == '__main__':
app.run(debug = True)
WTFormsパッケージには、バリデータクラスも含まれています。 フォームフィールドに検証を適用するのに役立ちます。 次のリストは、一般的に使用されるバリデーターを示しています。
Sr.No | Validators Class & Description |
---|---|
1 |
DataRequired 入力フィールドが空かどうかを確認します |
2 |
フィールド内のテキストが電子メールIDの規則に従っているかどうかを確認します |
3 |
IPAddress 入力フィールドのIPアドレスを検証します |
4 |
Length 入力フィールドの文字列の長さが指定された範囲内にあるかどうかを検証します |
5 |
NumberRange 指定された範囲内の入力フィールドの数値を検証します |
6 |
URL 入力フィールドに入力されたURLを検証します |
連絡先フォームの name フィールドに 'DataRequired' 検証ルールを適用します。
name = TextField("Name Of Student",[validators.Required("Please enter your name.")])
フォームオブジェクトの* validate()*関数はフォームデータを検証し、検証が失敗した場合に検証エラーをスローします。 *エラー*メッセージがテンプレートに送信されます。 HTMLテンプレートでは、エラーメッセージは動的にレンダリングされます。
{% for message in form.name.errors %}
{{ message }}
{% endfor %}
次の例は、上記の概念を示しています。 Contact form のデザインは、*(forms.py)*の下にあります。
from flask_wtf import Form
from wtforms import TextField, IntegerField, TextAreaField, SubmitField, RadioField,
SelectField
from wtforms import validators, ValidationError
class ContactForm(Form):
name = TextField("Name Of Student",[validators.Required("Please enter
your name.")])
Gender = RadioField('Gender', choices = [('M','Male'),('F','Female')])
Address = TextAreaField("Address")
email = TextField("Email",[validators.Required("Please enter your email address."),
validators.Email("Please enter your email address.")])
Age = IntegerField("age")
language = SelectField('Languages', choices = [('cpp', 'C++'),
('py', 'Python')])
submit = SubmitField("Send")
バリデーターは Name および Email フィールドに適用されます。
以下は、Flaskアプリケーションスクリプト*(formexample.py)*です。
from flask import Flask, render_template, request, flash
from forms import ContactForm
app = Flask(__name__)
app.secret_key = 'development key'
@app.route('/contact', methods = ['GET', 'POST'])
def contact():
form = ContactForm()
if request.method == 'POST':
if form.validate() == False:
flash('All fields are required.')
return render_template('contactl', form = form)
else:
return render_template('successl')
elif request.method == 'GET':
return render_template('contactl', form = form)
if __name__ == '__main__':
app.run(debug = True)
テンプレート*(contactl)*のスクリプトは次のとおりです-
<!doctype html>
<html>
<body>
<h2 style = "text-align: center;">Contact Form</h2>
{% for message in form.name.errors %}
<div>{{ message }}</div>
{% endfor %}
{% for message in form.email.errors %}
<div>{{ message }}</div>
{% endfor %}
<form action = "http://localhost:5000/contact" method = post>
<fieldset>
<legend>Contact Form</legend>
{{ form.hidden_tag() }}
<div style = font-size:20px; font-weight:bold; margin-left:150px;>
{{ form.name.label }}<br>
{{ form.name }}
<br>
{{ form.Gender.label }} {{ form.Gender }}
{{ form.Address.label }}<br>
{{ form.Address }}
<br>
{{ form.email.label }}<br>
{{ form.email }}
<br>
{{ form.Age.label }}<br>
{{ form.Age }}
<br>
{{ form.language.label }}<br>
{{ form.language }}
<br>
{{ form.submit }}
</div>
</fieldset>
</form>
</body>
</html>
Pythonシェルで formexample.py を実行し、URL http://localhost:5000/contact にアクセスします。 以下に示すように、 Contact フォームが表示されます。
エラーがある場合、ページは次のようになります-
エラーがない場合は、「成功」*がレンダリングされます。
フラスコ– SQLite
Pythonには SQlite の組み込みサポートがあります。 SQlite3モジュールはPythonディストリビューションに同梱されています。 PythonでのSQLiteデータベースの使用に関する詳細なチュートリアルについては、リンク:/sqlite/sqlite_python [このリンク]を参照してください。 このセクションでは、FlaskアプリケーションとSQLiteの相互作用を確認します。
SQLiteデータベース*「database.db」*を作成し、その中に学生のテーブルを作成します。
import sqlite3
conn = sqlite3.connect('database.db')
print "Opened database successfully";
conn.execute('CREATE TABLE students (name TEXT, addr TEXT, city TEXT, pin TEXT)')
print "Table created successfully";
conn.close()
Flaskアプリケーションには、3つの*表示*関数があります。
最初の* new_student()関数はURLルール( ‘/addnew’)*にバインドされています。 学生情報フォームを含むHTMLファイルをレンダリングします。
@app.route('/enternew')
def new_student():
return render_template('studentl')
*‘studentl’* のHTMLスクリプトは次のとおりです-
<html>
<body>
<form action = "{{ url_for('addrec') }}" method = "POST">
<h3>Student Information</h3>
Name<br>
<input type = "text" name = "nm"/></br>
Address<br>
<textarea name = "add" ></textarea><br>
City<br>
<input type = "text" name = "city"/><br>
PINCODE<br>
<input type = "text" name = "pin"/><br>
<input type = "submit" value = "submit"/><br>
</form>
</body>
</html>
ご覧のとおり、フォームデータは* addrec()関数をバインドする *’/addrec’ URLに投稿されます。
この* addrec()関数は、 *POST メソッドによってフォームのデータを取得し、studentsテーブルに挿入します。 挿入操作の成功またはエラーに対応するメッセージは ‘resultl’ にレンダリングされます。
@app.route('/addrec',methods = ['POST', 'GET'])
def addrec():
if request.method == 'POST':
try:
nm = request.form['nm']
addr = request.form['add']
city = request.form['city']
pin = request.form['pin']
with sql.connect("database.db") as con:
cur = con.cursor()
cur.execute("INSERT INTO students (name,addr,city,pin)
VALUES (?,?,?,?)",(nm,addr,city,pin) )
con.commit()
msg = "Record successfully added"
except:
con.rollback()
msg = "error in insert operation"
finally:
return render_template("resultl",msg = msg)
con.close()
*resultl* のHTMLスクリプトには、 *Insert* 操作の結果を表示するエスケープステートメント *\ {\ {msg}}* が含まれています。
<!doctype html>
<html>
<body>
result of addition : {{ msg }}
<h2><a href = "\">go back to home page</a></h2>
</body>
</html>
アプリケーションには、 ’/list’ URLで表される別の* list()関数が含まれています。 学生テーブル内のすべてのレコードを含む *MultiDict オブジェクトとして 'rows' を設定します。 このオブジェクトは listl テンプレートに渡されます。
@app.route('/list')
def list():
con = sql.connect("database.db")
con.row_factory = sql.Row
cur = con.cursor()
cur.execute("select * from students")
rows = cur.fetchall();
return render_template("listl",rows = rows)
この listl はテンプレートであり、行セットを反復処理し、データをHTMLテーブルにレンダリングします。
<!doctype html>
<html>
<body>
<table border = 1>
<thead>
<td>Name</td>
<td>Address>/td<
<td>city</td>
<td>Pincode</td>
</thead>
{% for row in rows %}
<tr>
<td>{{row["name"]}}</td>
<td>{{row["addr"]}}</td>
<td> {{ row["city"]}}</td>
<td>{{row['pin']}}</td>
</tr>
{% endfor %}
</table>
<a href = "/">Go back to home page</a>
</body>
</html>
最後に、 ‘/’ URLルールは、アプリケーションのエントリポイントとして機能する ‘homel’ をレンダリングします。
@app.route('/')
def home():
return render_template('homel')
*Flask-SQLite* アプリケーションの完全なコードは次のとおりです。
from flask import Flask, render_template, request
import sqlite3 as sql
app = Flask(__name__)
@app.route('/')
def home():
return render_template('homel')
@app.route('/enternew')
def new_student():
return render_template('studentl')
@app.route('/addrec',methods = ['POST', 'GET'])
def addrec():
if request.method == 'POST':
try:
nm = request.form['nm']
addr = request.form['add']
city = request.form['city']
pin = request.form['pin']
with sql.connect("database.db") as con:
cur = con.cursor()
cur.execute("INSERT INTO students (name,addr,city,pin)
VALUES (?,?,?,?)",(nm,addr,city,pin) )
con.commit()
msg = "Record successfully added"
except:
con.rollback()
msg = "error in insert operation"
finally:
return render_template("resultl",msg = msg)
con.close()
@app.route('/list')
def list():
con = sql.connect("database.db")
con.row_factory = sql.Row
cur = con.cursor()
cur.execute("select * from students")
rows = cur.fetchall();
return render_template("listl",rows = rows)
if __name__ == '__main__':
app.run(debug = True)
このスクリプトをPythonシェルから実行し、開発サーバーの実行を開始します。 ブラウザの http://localhost:5000/ にアクセスすると、次のようなシンプルなメニューが表示されます-
*[新しいレコードを追加]* リンクをクリックして、*学生情報*フォームを開きます。
フォームフィールドに入力して送信します。 基礎となる関数は、学生テーブルにレコードを挿入します。
ホームページに戻り、[リストを表示] *リンクをクリックします。 サンプルデータを示すテーブルが表示されます。
フラスコ– SQLAlchemy
Flask Webアプリケーションで生のSQLを使用してデータベースでCRUD操作を実行するのは退屈です。 代わりに、Pythonツールキットである SQLAlchemy は、アプリケーション開発者にSQLのフルパワーと柔軟性を提供する強力な* ORマッパー*です。 Flask-SQLAlchemyは、FlaskアプリケーションにSQLAlchemyのサポートを追加するFlask拡張機能です。
- ORM(オブジェクト関係マッピング)とは何ですか?*
ほとんどのプログラミング言語プラットフォームはオブジェクト指向です。 一方、RDBMSサーバーのデータはテーブルとして保存されます。 オブジェクト関係マッピングは、オブジェクトパラメータを基になるRDBMSテーブル構造にマッピングする手法です。 ORM APIは、生のSQLステートメントを記述することなくCRUD操作を実行するメソッドを提供します。
このセクションでは、Flask-SQLAlchemyのORMテクニックを研究し、小さなWebアプリケーションを構築します。
- ステップ1 *-Flask-SQLAlchemy拡張機能をインストールします。
pip install flask-sqlalchemy
- ステップ2 *-このモジュールからSQLAlchemyクラスをインポートする必要があります。
from flask_sqlalchemy import SQLAlchemy
- ステップ3 *-Flaskアプリケーションオブジェクトを作成し、使用するデータベースのURIを設定します。
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///students.sqlite3'
ステップ4 *-次に、パラメータとしてアプリケーションオブジェクトを使用して、SQLAlchemyクラスのオブジェクトを作成します。 このオブジェクトには、ORM操作のヘルパー関数が含まれています。 また、ユーザー定義モデルの宣言に使用される親Modelクラスも提供します。 以下のスニペットでは、 *students モデルが作成されます。
db = SQLAlchemy(app)
class students(db.Model):
id = db.Column('student_id', db.Integer, primary_key = True)
name = db.Column(db.String(100))
city = db.Column(db.String(50))
addr = db.Column(db.String(200))
pin = db.Column(db.String(10))
def __init__(self, name, city, addr,pin):
self.name = name
self.city = city
self.addr = addr
self.pin = pin
ステップ5 *-URIに記載されているデータベースを作成/使用するには、 create_all()*メソッドを実行します。
db.create_all()
*SQLAlchemy* の *Session* オブジェクトは、 *ORM* オブジェクトのすべての永続化操作を管理します。
次のセッションメソッドはCRUD操作を実行します-
- db.session.add (model object)-マッピングされたテーブルにレコードを挿入します
- db.session.delete (model object)-テーブルからレコードを削除します
- * model.query.all()*-テーブルからすべてのレコードを取得します(SELECTクエリに対応)。
filter属性を使用して、取得したレコードセットにフィルターを適用できます。 たとえば、学生のテーブルで city = ’Hyderabad’ のレコードを取得するには、次のステートメントを使用します-
Students.query.filter_by(city = ’Hyderabad’).all()
このように多くのバックグラウンドがあるので、今度は、学生データを追加するためのアプリケーションのビュー機能を提供します。
アプリケーションのエントリポイントは、 ’/’ URLにバインドされた* show_all()*関数です。 学生のレコードセットテーブルは、パラメータとしてHTMLテンプレートに送信されます。 テンプレート内のサーバー側コードは、HTMLテーブル形式でレコードをレンダリングします。
@app.route('/')
def show_all():
return render_template('show_alll', students = students.query.all() )
テンプレート*( ‘show_alll’)*のHTMLスクリプトは次のとおりです-
<!DOCTYPE html>
<html lang = "en">
<head></head>
<body>
<h3>
<a href = "{{ url_for('show_all') }}">Comments - Flask
SQLAlchemy example</a>
</h3>
<hr/>
{%- for message in get_flashed_messages() %}
{{ message }}
{%- endfor %}
<h3>Students (<a href = "{{ url_for('new') }}">Add Student
</a>)</h3>
<table>
<thead>
<tr>
<th>Name</th>
<th>City</th>
<th>Address</th>
<th>Pin</th>
</tr>
</thead>
<tbody>
{% for student in students %}
<tr>
<td>{{ student.name }}</td>
<td>{{ student.city }}</td>
<td>{{ student.addr }}</td>
<td>{{ student.pin }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
上記のページには、 ’/new’ URLマッピング* new()関数へのハイパーリンクが含まれています。 クリックすると、学生情報フォームが開きます。 データは *POST メソッドで同じURLに投稿されます。
newl
<!DOCTYPE html>
<html>
<body>
<h3>Students - Flask SQLAlchemy example</h3>
<hr/>
{%- for category, message in get_flashed_messages(with_categories = true) %}
<div class = "alert alert-danger">
{{ message }}
</div>
{%- endfor %}
<form action = "{{ request.path }}" method = "post">
<label for = "name">Name</label><br>
<input type = "text" name = "name" placeholder = "Name"/><br>
<label for = "email">City</label><br>
<input type = "text" name = "city" placeholder = "city"/><br>
<label for = "addr">addr</label><br>
<textarea name = "addr" placeholder = "addr"></textarea><br>
<label for = "PIN">City</label><br>
<input type = "text" name = "pin" placeholder = "pin"/><br>
<input type = "submit" value = "Submit"/>
</form>
</body>
</html>
httpメソッドがPOSTとして検出されると、フォームデータが学生テーブルに追加され、アプリケーションは追加されたデータを表示するホームページに戻ります。
@app.route('/new', methods = ['GET', 'POST'])
def new():
if request.method == 'POST':
if not request.form['name'] or not request.form['city'] or not request.form['addr']:
flash('Please enter all the fields', 'error')
else:
student = students(request.form['name'], request.form['city'],
request.form['addr'], request.form['pin'])
db.session.add(student)
db.session.commit()
flash('Record was successfully added')
return redirect(url_for('show_all'))
return render_template('newl')
以下に示すのは、アプリケーション*(app.py)*の完全なコードです。
from flask import Flask, request, flash, url_for, redirect, render_template
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///students.sqlite3'
app.config['SECRET_KEY'] = "random string"
db = SQLAlchemy(app)
class students(db.Model):
id = db.Column('student_id', db.Integer, primary_key = True)
name = db.Column(db.String(100))
city = db.Column(db.String(50))
addr = db.Column(db.String(200))
pin = db.Column(db.String(10))
def __init__(self, name, city, addr,pin):
self.name = name
self.city = city
self.addr = addr
self.pin = pin
@app.route('/')
def show_all():
return render_template('show_alll', students = students.query.all() )
@app.route('/new', methods = ['GET', 'POST'])
def new():
if request.method == 'POST':
if not request.form['name'] or not request.form['city'] or not request.form['addr']:
flash('Please enter all the fields', 'error')
else:
student = students(request.form['name'], request.form['city'],
request.form['addr'], request.form['pin'])
db.session.add(student)
db.session.commit()
flash('Record was successfully added')
return redirect(url_for('show_all'))
return render_template('newl')
if __name__ == '__main__':
db.create_all()
app.run(debug = True)
Pythonシェルからスクリプトを実行し、ブラウザーに http://localhost:5000/ と入力します。
- 「生徒を追加」*リンクをクリックして、*生徒情報*フォームを開きます。
フォームに記入して送信します。 送信されたデータとともにホームページが再表示されます。
次のように出力を確認できます。
フラスコ– Sijax
*Sijax* は*「Simple Ajax」*の略で、 *Ajax* をアプリケーションに簡単に導入できるように設計された *Python/jQuery* ライブラリです。 *jQuery.ajax* を使用してAJAXリクエストを作成します。
インストール
Flask-Sijaxのインストールは簡単です。
pip install flask-sijax
設定
- SIJAX_STATIC_PATH -Sijax javascriptファイルをミラーリングする静的パス。 デフォルトの場所は static/js/sijax です。 このフォルダーには、 sijax.js および json2.js ファイルが保持されます。
- SIJAX_JSON_URI -json2.js静的ファイルをロードするURI
Sijaxは JSON を使用して、ブラウザーとサーバー間でデータを渡します。 つまり、ブラウザーは JSON をネイティブでサポートするか、 json2.js ファイルから JSON サポートを取得する必要があります。
この方法で登録された関数は、デフォルトで POST メソッドを使用してアクセスできないため(およびSijaxはPOST要求を使用するため)、 Sijax 機能を提供できません。
*Sijax* リクエストを処理できる *View* 関数を作成するには、* @ app.route( '/url'、methods = ['GET'、 'POST'])*を使用してPOSTでアクセスできるようにするか、 *@ flask_sijax.route* このようなヘルパーデコレータ-
@flask_sijax.route(app, '/hello')
(このような)すべてのSijaxハンドラー関数は、Pythonがオブジェクトメソッドに「自己」を渡すように、少なくとも1つのパラメーターを自動的に受け取ります。 'obj_response' パラメータは、関数がブラウザに応答する方法です。
def say_hi(obj_response):
obj_response.alert('Hi there!')
Sijax要求が検出されると、Sijaxは次のように処理します-
g.sijax.register_callback('say_hi', say_hi)
return g.sijax.process_request()
Sijaxアプリケーション
最小限のSijaxアプリケーションコードは次のようになります-
import os
from flask import Flask, g
from flask_sijax import sijax
path = os.path.join('.', os.path.dirname(__file__), 'static/js/sijax/')
app = Flask(__name__)
app.config['SIJAX_STATIC_PATH'] = path
app.config['SIJAX_JSON_URI'] = '/static/js/sijax/json2.js'
flask_sijax.Sijax(app)
@app.route('/')
def index():
return 'Index'
@flask_sijax.route(app, '/hello')
def hello():
def say_hi(obj_response):
obj_response.alert('Hi there!')
if g.sijax.is_sijax_request:
# Sijax request detected - let Sijax handle it
g.sijax.register_callback('say_hi', say_hi)
return g.sijax.process_request()
return _render_template('sijaxexamplel')
if __name__ == '__main__':
app.run(debug = True)
Sijaxがサーバーにリクエスト(特別な* jQuery.ajax()リクエスト)すると、このリクエストは g.sijax.is_sijax_request()によってサーバー上で検出されます。この場合、 *Sijax にリクエストを処理させます。
- g.sijax.register_callback()*を使用して登録されたすべての関数は、ブラウザーからの呼び出し用に公開されます。
- g.sijax.process_request()*を呼び出すと、適切な(以前に登録された)関数を実行し、ブラウザーに応答を返すようSijaxに指示します。
フラスコ–展開
外部から見えるサーバー
開発サーバー上のFlaskアプリケーションは、開発環境がセットアップされているコンピューターでのみアクセスできます。 これはデフォルトの動作です。デバッグモードでは、ユーザーがコンピューター上で任意のコードを実行できるためです。
*debug* が無効になっている場合、ホスト名を *‘0.0.0.0’* に設定することにより、ローカルコンピューター上の開発サーバーをネットワーク上のユーザーが利用できるようにすることができます。
app.run(host = ’0.0.0.0’)
これにより、オペレーティングシステムはすべてのパブリックIPをリッスンします。
展開
開発環境から本格的な本番環境に切り替えるには、アプリケーションを実際のWebサーバーにデプロイする必要があります。 持っているものに応じて、Flask Webアプリケーションをデプロイするためのさまざまなオプションがあります。
小規模アプリケーションの場合、次のホストプラットフォームのいずれかに展開することを検討できます。これらはすべて、小規模アプリケーションの無料プランを提供します。
- ヘロク
- ドットクラウド
- ウェブファクション
Flaskアプリケーションは、これらのクラウドプラットフォームにデプロイできます。 さらに、FlaskアプリをGoogleクラウドプラットフォームに展開することもできます。 Localtunnelサービスを使用すると、DNSおよびファイアウォールの設定を変更することなく、localhostでアプリケーションを共有できます。
上記の共有プラットフォームの代わりに専用のWebサーバーを使用する場合は、次のオプションがあります。
mod_wsgi
*mod_wsgi* は、ApacheサーバーでPythonベースのWebアプリケーションをホストするためのWSGI準拠のインターフェイスを提供するApacheモジュールです。
mod_wsgiのインストール
PyPiから直接公式リリースをインストールするには、次を実行できます-
pip install mod_wsgi
インストールが成功したことを確認するには、start-serverコマンドでmod_wsgi-expressスクリプトを実行します-
mod_wsgi-express start-server
これにより、ポート8000でApache/mod_wsgiが起動します。 次に、ブラウザで次を指定することにより、インストールが機能したことを確認できます-
http://localhost:8000/
.wsgiファイルの作成
*yourapplication.wsgi* ファイルが必要です。 このファイルには、起動時に実行されてアプリケーションオブジェクトを取得するコード *mod_wsgi* が含まれています。 ほとんどのアプリケーションでは、次のファイルで十分です-
from yourapplication import app as application
*yourapplication* および使用中のすべてのライブラリがpythonロードパス上にあることを確認してください。
Apacheの構成
アプリケーションの場所を mod_wsgi に伝える必要があります。
<VirtualHost *>
ServerName example.com
WSGIScriptAlias/C:\yourdir\yourapp.wsgi
<Directory C:\yourdir>
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
スタンドアロンWSGIコンテナー
WSGIアプリケーションを含み、HTTPを提供するPythonで書かれた多くの一般的なサーバーがあります。
- ユニコーン
- 竜巻
- ゲベント
- ツイストWeb
フラスコ– FastCGI
FastCGIは、nginix、lighttpd、CherokeeなどのWebサーバー上のFlaskアプリケーションの別の展開オプションです。
FastCGIの構成
最初に、 FastCGI サーバーファイルを作成する必要があります。 yourapplication.fcgi と呼びましょう。
from flup.server.fcgi import WSGIServer
from yourapplication import app
if __name__ == '__main__':
WSGIServer(app).run()
*nginx* および *lighttpd* の古いバージョンでは、 *FastCGI* サーバーと通信するためにソケットを明示的に渡す必要があります。 それが機能するためには、ソケットへのパスを *WSGIServer* に渡す必要があります。
WSGIServer(application, bindAddress = '/path/to/fcgi.sock').run()
Apacheの構成
基本的なApacheデプロイメントの場合、。fcgi *ファイルはアプリケーションURLに表示されます。 *example.com/yourapplication.fcgi/hello/ 。 yourapplication.fcgi がURLに表示されないようにアプリケーションを構成する方法はいくつかあります。
<VirtualHost *>
ServerName example.com
ScriptAlias//path/to/yourapplication.fcgi/
</VirtualHost>
lighttpdの構成
*lighttpd* の基本設定は次のようになります-
fastcgi.server = ("/yourapplication.fcgi" => ((
"socket" => "/tmp/yourapplication-fcgi.sock",
"bin-path" => "/var/www/yourapplication/yourapplication.fcgi",
"check-local" => "disable",
"max-procs" => 1
)))
alias.url = (
"/static/" => "/path/to/your/static"
)
url.rewrite-once = (
"^(/static($|/.*))$" => "$1",
"^(/.*)$" => "/yourapplication.fcgi$1"
)
*FastCGI* 、エイリアス、および書き換えモジュールを必ず有効にしてください。 この構成は、アプリケーションを */yourapplication* にバインドします。