Python/Flask

FlaskはPythonで書かれたマイクロウェブフレームワークです。 特定のツールやライブラリを必要としないため、マイクロフレームワークに分類されます。 データベースの抽象化レイヤーやフォームの検証など、既存のサードパーティライブラリが共通機能を提供するコンポーネントは存在しません。 しかし、Flaskは拡張機能をサポートしており、Flask自体に実装されているかのようにアプリケーションの機能を追加することができます。 オブジェクトリレーショナルマッパー、フォームバリデーション、アップロード処理、様々なオープン認証技術、いくつかの一般的なフレームワーク関連ツールのための拡張機能が存在します。
Flaskのインストールにはいくつかの方法があります。
Flaskのパッケージがあるオペレーションシステムでは、pip ではなく、パッケージマネージャーからFlaskと依存パッケージをインストールしましょう。 混在すると、OSのパッケージマネージャーと pip の間で管理情報に矛盾が生じアップデートなどに支障をきたすようになっていまいます。
多くの BSD UNIX は ports/pkgsrc/pkg で Flask をサポートしています。
portsレクションに www/py-flask があります。
ソースコードからインストール
バイナリーパッケージからインストール
Werkzeug や Jinja などの Flask が依存するパッケージも自動的にビルド/インストールされます。
また、静的なサイトを生成する www/py-frozen-flask もパッケージ化されています。
GNU/Linuxでは、ディストリビューションによってパッケージマネージャーや、パッケージアーカイブスが異なるので、お使いのパッケージマネージャーの利用方向に従ってインストールしてください。
を実行し、flask を名前に含むパッケージの一覧を表示し、その中から python3-flask を選びインストールします。
Fedora には、python3-flaskパッケージがあるので、 pip から flask をインストールすると、パッケージマネージャーで管理している依存パッケージ(Werkzeug や Jinja)と、 pip で管理している依存パッケージのバージョンが違ったりパスが違ったりする「キマイラ環境」ができてしまい、アップデートやアップグレードに支障を来たします。
ウェブアプリケーションを起動する前に、インストールが成功したか、またどのバージョンがインストールされたかを確認します。
"Hello World" だけを返すウェブサービスをつくってみます。
起動してみましょう。
http://127.0.0.1:5000 を開いてみます(127.0.0.0/8は、他のホストからはアクセスできないループバックインターフェースに割り当てられたアドレスです)。
Flaskを実行中の端末には
http://127.0.0.1:5000/no-exist を開いてみましょう。
Flaskを実行中の端末には
Flaskを実行中の端末でFlaskを強制終了します。
Flaskは、Jinjaテンプレートエンジンと連携し、テンプレートベースの動的なウェブページの生成が可能です
Flaskの既定のディレクトリーレイアウトでは、スクリプトのあるディレクトリーの下に、templates/ という名前のディレクトリーを掘り、そこにテンプレートを用意します。
2つのテンプレートファイルと1つのスクリプトを用意します。
Jinja は、Python で実装されたテンプレートエンジンで、Flaskウェブアプリケーションフレームワークの一部として提供されていますが、単体で使用することも可能です。
{{ 式 }} でテンプレート中で変数(キーワード引数)や関数を参照できます。
{% set 変数 = 値 %} でテンプレート中で変数に値を代入できます。
{# コメント #}がJinjaテンプレートのコメントの構文で、出力には含まれません。
Jinjaには、条件分岐と反復の制御構造があります。
は
と %} を -%} とすることで
マクロ( macro )機能を使うと、繰返し使うフレーズをテンプレートの中で定義し、呼出しという形で再利用できます。
Jinjaでは、Pythonのすべての組込み型を render_template() の引数として受取ることができ、反復構文を使うことで自由度の高いテンプレートを作ることができます。
Jinjaでは、テンプレートを別のテンプレートから雛形として継承する事ができます。
Example.html.jinja の block content
ブロックは、マクロと異なり継承元では定義を行うだけで、展開は継承先だけで行なえます。また継承元も継承先も同じ開始タグと終了タグを使うので、多段継承(孫テンプレートを作ること)はできません。定義を blockdef、展開を blockref のように別の名前にすれば構文的には多段継承できますが、その場合「super()が何を表すのか」「循環継承が起こったらどうするか?」など意味論・運用論的な問題を多数生んでしまうので、多段継承を妨げたのは設計上のロバストな選択です。
また、継承元で定義したマクロを、継承先で展開することはできます。
block と extends によるテンプレート継承が雛形だとすれば、include による包含は部品化です。
[TODO:コード例]
filter には、式指向のフィルターとブロック指向のフィルターとがあります。
[TODO:コード例]
Flaskに次ぐシェア2位のPythonベースのウェブアプリケーションフレームワークにDjangoがあります。
単独のページとして立項できる内容と信頼性を得るまで、Flaskの下におきました。
Djangoのインストールにはいくつかの方法があります。
Djangoのパッケージがあるオペレーションシステムでは、pip ではなく、パッケージマネージャーからDjangoと依存パッケージをインストールしましょう。 混在すると、OSのパッケージマネージャーと pip の間で管理情報に矛盾が生じアップデートなどに支障をきたすようになっていまいます。
多くの BSD UNIX は ports/pkgsrc/pkg で Django をサポートしています。
portsレクションに www/py-django があります。
ソースコードからインストール
バイナリーパッケージからインストール
GNU/Linuxでは、ディストリビューションによってパッケージマネージャーや、パッケージアーカイブスが異なるので、お使いのパッケージマネージャーの利用方向に従ってインストールしてください。
を実行し、django を名前に含むパッケージの一覧を表示し、その中から python3-django を選びインストールします。
Djangoのバージョン確認の方法
Django を使うには、コマンドラインを使う必要があります。
まず、プロジェクトのディレクトリ群を作らないといけないのですが、さすがにこれは自動生成してくれるコマンドがあります。
コマンド
で、まずプロジェクトを作ります。
上記コマンドを使えば、Django用のプロジェクトのディレクトリを自動生成してくれます。
たとえば、 「projtest」というプロジェクトを作るなら
になるわけです。
そして、このプロジェクト内でこれから作業するので、移動コマンドcdを使い、
で、さきほど作成したプロジェクトのディレクトリ内に移動します。
コマンド
を使うと、Django の ウェブサーバーが立ち上がります。
ウェブブラウザで、
でアクセスできます。
まだ何もユーザー側でHTMLを作っていないので、初期設定のHTMLページが表示されるので、表示ページには英文およびロゴマークでロケットの打ち上げ絵が書かれています。水色っぽいロケットの打ち上がってるイラストが出たら、とりあえず、ここまでの作業は成功です。
サーバ立ち上げのコマンドの冒頭は、 django-admin ではなく Python ですので、間違えないようにしましょう。なんでここだけPythonなのか謎ですが、そういう仕様なので、従うしかありません。
なお、自動作成ずみのプロジェクト用ディレクトリ内にすでに manage.py というスクリプトがあり、それを上記コマンド Python manage.py runserver で実行している仕組みです。

なお、サーバを終了するには、CTRLキー を押しながら C を押します。(Flaskと同じ終了コマンド)
次回以降のサーバの立ち上げは
になります。
では、これからホームページを作りましょう。Djangoではホームページは「アプリ」に分類されるので、コマンド
で、まずDjangoアプリを作ります。
このコマンドを実行する場所は、どこでもいいのですが、プロジェクト内でしたほうがラクなので、中で作成した場合、コマンドライン画面は
のようになります。
今回、最終的に作りたいのはホームページなので、たとえば「hptest」というアプリ名を作ったとしましょう。
Django用ディレクトリ内に自動作成されたアプリ名ディレクトリの中に
というファイル名と上記のコード内容のファイルがありますので、それをマウスで右クリックして、普通に開き、これから編集することで、ホームページ作成する仕組みです。
これを編集し、下記のような関数を付け足します。関数名(func)とその引数(arg)は自由に設定できますが、「render」はそのままにしてください。
書式はもちろん
です。
次に、プロジェクト名と同名のディレクトリが、プロジェクトに入った階層にあるので、その同名ディレクトリに、マウスで移動します。 そして、その同名ディレクトリ内に、urls.py というファイルが存在し、↓のほうに、下記のようなコードが書かれています。
このファイルのこのコード部分を下記のように書き換えます。
次に、アプリ側に、urls.py という同名のファイルを作りますが(初期設定では用意されてないので、ファイルを新規作成してください)、中身は別です。下記のようなコードをアプリ側に書きます。
そして、さらに、「templates」ディレクトリを作り、そこに最終的に表示したいHTMLを入れます。このディレクトリ名は、必ず「templates」でないといけません。(アプリ側 urls.py のコード中のpath('templates/', といっしょに別ディレクトリ名に書き換えて違うディレクトリ名にしても、エラーになります。なので、必ず「templates」というファイル名にしてください。)

の第一引数の部分は、ウェブブラウザなどで「templates」のメッセージが送られた場合に、テンプレートディレクトリにあるファイルで対応する事を言っています。
なので、たとえば、第一引数を別名にして
のようにしても、ウェブブラウザでのアクセス時にURL欄に
と入力すると、ブラウザからtemplatesディレクトリ内のHTMLなどにアクセスできてしまいます。ですが、まぎらわしいので、第一引数は「templates」のままに、しておいてください。
このtemplatesディレクトリに入れるHTMLには、とりあえず、
と書いてあるとしましょう。
さらに、プロジェクト側にある setting.py に、INSTALLED_APPS という項目があり、最初は
と書かれていますが、これに私達の作成するアプリ名をつけたすことで、そのアプリが追加されたことを知らせます。
あとは、サーバを立ち上げて、ウェブブラウザで
にアクセスすれば、HTMLファイルの内容が表示されます。(上述のコード例の場合なら、 http://localhost:8000/hptest/templates/ にアクセスする事になります。 )

大きな文字で
と表示されれば成功です。
Django では、ログインページそのものを自動作成する機能もあり Auth といいますが、設定が必要です。
これとは別に、ログインページでよく使いそうな、Eメールアドレス入力フォームや、会員サイトでの入会時の生年月日の登録などで使いそうな年月日入力フォームなど、各種の入力フォームを、テンプレートで自動作成する機能があり、Formクラスと言います。
Eメール入力フォームなら、メールアドレス形式以外の文字列が入力されても、送信を禁止します。このように、入力内容を自動的に検査することを「バリデーション」といいます。Formクラスを使うと、バリデーションの機能を使えます。
また、その他の一般のDjangoの入力フォームでも、入力時の必須項目などを設定できます。たとえば、登録ページでユーザー名が未入力なのに「送信」ボタンの押された場合には、「この項目を入力してください」のような警告メッセージを、ウェブページ上で出させて、送信させないでユーザーに再入力させる事ができます。
Djangoなどのフルスタックウェブアプリケーションフレームワークを使う利点として、サーバー製作者は上述のように、入力欄のチェック機能を自作する手間が省けます。
いきなりログインページを作っても、複雑で理解が浅くなってしまうので、まずは、リンクで結ばれている複数のHTMLページをアップロードする方法を学びましょう。
templates にHTMLファイルが2つあるとして、
というファイルがあるとしましょう。
まず、これをアップロードするために、コードを下記のように書き換えます。
なお、(アプリ側でなく)プロジェクト側 urls.py の抜粋はそのままにしておきます。
さて、views.pyに、2ページ目のHTMLのための関数を追加する必要があります。

そして、それぞれのHTMLファイルには
と書いてあるとしましょう。
説明の簡単化のため、まです、各種の Django テンプレートは使わないでおきましょう。
これだけすれば、とりあえず、ウェブブラウザで、
にアクセスすれば、1ページ目を表示できます。
そして、ブラウザに表示されたリンク文をクリックすれば、2ページ目に移動できます。
2ページ目に移動したとき、アドレス欄の末尾が、きちんと2ページ目のファイルである testpage2 に変わっている事を確認しましょう。つまり、
というふうに、なっているハズです。
とりあえず、これで読者のアナタは、Djangoに複数のHTMLページをアップロードする事ができました。
では、今度はHTMLファイルのリンクを、Djangoテンプレートタグの一種である URLテンプレートタグ を使って書き換える方法を学びましょう。
単に、1ページ目のhrefタグの引数を、下記のようにurlテンプレートタグを使って書き換えるだけです。なお、前回との表示の区別のため、下記コードでは表示される文章を少々、追加してあります。
参考のため、2ページ目のHTMLも再掲しておきます。
あとはもう、
にアクセスすれば、前回と同様のアクセス結果になります。