にっきQuickstartは、すでに他のWAF経験がある人向けの文書で、Flask特有のやりかたが書かれているという印象。初心者は読んでいってもピンと来ない部分が多いので、チュートリアルを読み進める。Flaskのチュートリアルは、flaskrというブログアプリを作るものである。(日本語でFlaskのドキュメントを読めると考えたのが甘えだった、という結論に至った。これからは本家のドキュメントを読む)(DB周りがぜんぜん分からなかったので、逐一メモりながら読んでたら後半ほぼ翻訳になった。/templatesなんでflaskrが入れ子になっとるの?と思われるはず。上のflaskrは単なるプロジェクト置き場としてのディレクトリで、下のflaskrディレクトリはパッケージ名としてのそれである。パッケージ化はFlaskアプリを作る際に推奨される方法である。データベーススキーマsqlite3を利用する。DBよく知らないです...。nullもそのままの意味だろ、という理解でなんとかなると思っている。セットアップ特に変わったことはしていないが、app.config.from_object(__name__)で自分のファイルから全ての文字がuppercaseな変数を設定値として読み込むらしい。あと以下のコードについて少しだけ確認。1つのプロセスで複数のアプリケーションを動かすことがありうるから。ここではapp.root_path属性でアプリのパスを取得している。Folderを使えとドキュメントは述べている。templateやstaticディレクトリ、DBスキーマも含めてパッケージングしたい。MANIFEST.inを作成して以下のように記述する。flaskr/schema.sqlgraftとかincludeというのはマニフェストファイルのためにsetuptoolsが用意しているコマンドである。(3系のドキュメントに説明がないので2.7で許していただきたい。このimport文はアプリケーションのインスタンスをパッケージのトップレベルに担ぎ込む。アプリケーションをいざ走らせようとなった段で、Flaskの開発サーバはappインスタンスの場所を知る必要がある。このimport文はロケーションプロセスを単純にする。FLASK_APP=flaskr.flaskrなどと環境変数に書く必要が出てくる。これでアプリをインストールする準備が整った。当然ながら、こうしたアプリのpipでのインストールはvirtualenv内で行うことが推奨される。--editableを使うとインストールしたものがsite-packagesとやらに入らず今のディレクトリのものを使う。変更がそのまま反映されるので楽。2のconnect_db関数を書いたのだが、これはあまり使い勝手がよくない。毎度データベース接続を確立してクローズするというのは非効率的である。接続はちょっぴり長めに手元に留めておきたいわけだ。データベース接続はトランザクションのカプセル化であるために、一度に1つだけのリクエストが接続を使うということを確認する必要がある。このことを実現するための洗練された方法は、アプリケーションコンテクストを利用することである。Flaskは2種類のコンテクストを提供する。アプリケーションコンテクストとリクエストコンテクストである。それらは特殊な変数を使うものだと覚えておけばよい。request変数は現行ののリクエストと関連するリクエストオブジェクトである。それに対してgは現行のアプリケーションコンテクストに関連する汎用の変数である。これらについてはチュートリアルの後半で詳細に触れる。gオブジェクトに情報を安全に保管できるということを覚えておけばよい。ヘルパー関数として以下のコードを書く。g.sqlite_dbこれは初回呼び出し時にデータベース接続を現行のコンテクストに立ち上げ、次回以降の呼び出しでは確立された接続をそのまま返す、という処理である。これで接続の仕方は分かった。Flaskはteardown_appcontextというデコレータを提供している。down)*2するとき毎回呼び出される。g.sqlite_db.close()teardown_appcontextでマークされた関数は、アプリコンテクストを解体するたびに毎回呼び出される。これが何を意味するのか、かいつまんで言うと、アプリコンテクストはリクエストが来る前に作られ、リクエストが終了すると、いつともなく破棄される。(アプリコンテクストの)解体は次の2つの原因により起こりうる:すべてがうまくいった(errorパラメータがNoneであった)場合と、あるいは例外が起こった場合、どちらにしろerrorは解体を行う関数に渡されるのである。Contextを参照。schema.sqlが、sqlite3コマンドが必要、エラーを導入するためのパスが必要、などの不都合がある。dbを初期化する関数を作り、さらにそれをflaskコマンドから扱えるようにすると楽である。database.')app.cli.comannd()デコレータはflaskスクリプトに新しいコマンドを登録する。コマンドが実行されるとFlaskは自動的にアプリケーションコンテクストを作成し、それをアプリケーションに束縛する。関数の内部ではflask.gなど必要そうなものにだいたいアクセスできる。スクリプトが終了するとアプリケーションコンテクストは解体され、データベース接続は解放される。アプリケーションオブジェクトが持っているopen_resource()メソッドはアプリケーションが提供するリソースを開くための便利な関数である。この関数はリソースの場所(flaskr/flaskrフォルダ)からファイルを開き、読み出せるようにしてくれる。SQLiteによって提供される接続オブジェクトは、カーソルオブジェクトを与えることができる。カーソルには完全なスクリプトを実行するメソッドがある。最後は変更をコミットだけである。SQLite3やその他トランザクショナルDBは、こちら側が明示的に伝えるまでコミットを行わない。関数ようやくDB接続終わり。楽しいビュー関数だ!ビュー関数は4つ機能をつける。エントリの表示ルートにアクセスが来たら、DBからタイトルとテキストをid逆順で全部引っ張って来て表示する。何て分かりやすいんだ。show_entries.htmlはhtmlテンプレート(後で)。entries=entries)新しいエントリの追加ここで書くビューは、ログインしているユーザの新しいエントリを追加するものである。これはPOSTメソッドのみに応答する:実際の投稿フォームはshow_entriesページで表示する。すべての処理がうまくいったら、メッセージをflash(チカッ)としてユーザをshow_entiresページにリダイレクトする。redirect(url_for('show_entries'))ところで、上記のようなユーザの入力からそのままSQLを組み立てるようなコードは、セキュリティ的に問題があるので自分だけが使う場合以外はやめた方がいい。ログインとログアウト設定からユーザ名とパスワードをチェックし、セッションのlogged_inキーのフラグをTrueに切り替える。error=error)render_templateにはログイン失敗にしたときのエラーも渡している。logout関数を書く。redirect(url_for('show_entries'))pop()はdictの持つメソッドで、指定したキーの要素が存在する場合削除し、存在しなければ何も悪いことは起こらない。ログアウトしようとしているユーザが、ログインしているかどうか確認する必要がないので楽である。url_for('logout')と変えている。存在する場合はflashされたメッセージを表示している。layout.htmlを拡張し、body部を書いたもの。ログインした状態では投稿フォームを表示したり、エントリの表示をしたりといったことをする。ログイン失敗時には同ページにリダイレクトされるのでその時表示するエラーメッセージ部などを仕込んでいる。スタイルの追加style.cssをstaticフォルダに書いて終わり。アプリケーションのテストやりません感想DB知らないのでそのへんの話を咀嚼するのに骨が折れた。いうかアプリケーションコンテクストについては未だ内実不明である。知らなくてもさしあたりは困らないものだが。DB周りは追い追い覚えるとして、簡単なwebアプリの動きの全体像が把握できたので、やる意義はそれなりあったと感じる。*1:新しいドキュメントにはsetuptoolsでのインストール項目などがあり、かなり異なる。0.11以降でflaskはclickと連携しており、チュートリアルはそれを用いた説明もなされている。古い日本語ドキュメントを読む意義はかなり薄い*2:データベースでよく使う用語っぽいが日本語にしていいのかよくわからない。ここでは「解体」と呼称する。記事をqiitaに転載しました。読みかんたんなスニペットをREPLを利用して書いていく章。002WinAPIもぅマヂ無理。»プロフィールコメントは常に歓迎します。`ssize_t`とは何か2018-04-01【読んだもの】Pythonは逐一解釈されるのか、それともコンパイルされるのか?(答えはどちらも)イエスだ。(6)はてなブログをはじめよう!cofreeさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。