フラスコメガチュートリアル、パート2:テンプレート

これは、Flaskマイクロフレームワークを使用してPython Webアプリケーションを作成した経験を説明するシリーズの2番目の記事です。

このガイドの目的は、かなり機能的なマイクロブログアプリケーションを開発することです。オリジナリティが完全に欠如していることからmicroblogと呼ぶことにしました。



短い繰り返し


最初の部分の指示に従った場合、完全に機能するはずですが、このファイル構造を持つ非常にシンプルなアプリケーションが必要です。

 microblog\ flask\ <  > app\ static\ templates\ __init__.py views.py tmp\ run.py 


アプリケーションを実行するには、run.pyスクリプトを実行してから、ブラウザーでURL http:// localhost:5000を開きます。

中断したところから続行するため、上記のアプリケーションがインストールされ、正しく動作していることを確認する必要があります。

テンプレートが必要な理由


小さなアプリケーションをどのように拡張できるかを検討してください。
マイクロブログアプリケーションのメインページには、ログインしているユーザーを歓迎するヘッダーが必要です。これは、この種のアプリケーションの標準です。 現時点では、アプリケーションにユーザーがいないという事実を無視し、適切なタイミングでこの問題の解決策を提供します。

大きくて美しいヘッダーを出力する簡単な方法は、プレゼンテーション関数を次のようなhtmlに変更することです。
 from app import app @app.route('/') @app.route('/index') def index(): user = { 'nickname': 'Miguel' } #   return ''' <html> <head> <title>Home Page</title> </head> <body> <h1>Hello, ''' + user['nickname'] + '''</h1> </body> </html> ''' 

ブラウザでアプリケーションがどのように見えるかを確認してください。

ただし、ユーザーサポートはありませんが、ユーザーモデルのプロトタイプを使用することにしました。これは、偽または架空のプロトタイプと呼ばれることもあります。 これにより、まだ記述されていないシステムの部分に応じて、アプリケーションのいくつかの側面に集中することができます。

上記の解決策は非常にいものであることに同意していただければ幸いです。 大量の動的コンテンツを含むかさばるHTMLページを返す必要がある場合、コードがどれほど複雑になるか想像してみてください。 また、HTMLを直接返す多くのビューを持つ大規模なアプリケーションでWebサイトのレイアウトを変更する必要がある場合はどうでしょうか。 これは明らかにスケーラブルなソリューションではありません。

救助のためのテンプレート


アプリケーションとレイアウトのロジックを別々に保つことができれば、またはページのプレゼンテーションをより良く整理できると考えたことはありますか? Pythonを使用して[サイト]の動作をプログラムしている間に、Webデザイナーを雇って素晴らしいWebサイトを作成することもできます。 テンプレートはこの分離に役立ちます。

最初のテンプレート( app/templates/index.htmlファイル)を書きます:
 <html> <head> <title>{{title}} - microblog</title> </head> <body> <h1>Hello, {{user.nickname}}!</h1> </body> </html> 


上記でわかるように、標準のHTMLページを作成しましたが、1つの違いがあります。動的コンテンツのプレースホルダーは{{...}}セクションで囲まれています

次に、ビュー関数(ファイルapp/views.py )でのテンプレートの使用を検討します。
 from flask import render_template from app import app @app.route('/') @app.route('/index') def index(): user = { 'nickname': 'Miguel' } #   return render_template("index.html", title = 'Home', user = user) 


この段階でアプリケーションを起動して、テンプレートの動作を確認します。 ブラウザでページが表示される場合、そのソースコードを元のテンプレートと比較できます。

ページをレンダリングするには、Flaskからrender_templateと呼ばれる新しい関数をインポートする必要があります。 この関数は、テンプレート名とテンプレートへの可変引数のリストを受け取り、引数を置き換えた既製のテンプレートを返します。

内部:render_template関数は、Flaskフレームワークの一部であるJinja2テンプレートエンジンを呼び出します。 Jinja2は、{{...}}ブロックを、テンプレート引数として渡された対応する値に置き換えます。

テンプレートの制御演算子


Jinja2テンプレートは、とりわけ、{%...%}ブロック内で渡される制御ステートメントをサポートします。 テンプレートにifステートメントを追加しましょう( app/templates/index.htmlファイル):
 <html> <head> {% if title %} <title>{{title}} - microblog</title> {% else %} <title>Welcome to microblog</title> {% endif %} </head> <body> <h1>Hello, {{user.nickname}}!</h1> </body> </html> 


これで、テンプレートが少しスマートになりました。 プレゼンテーション関数でページの名前を定義するのを忘れた場合、例外と引き換えに、テンプレートは独自の名前を提供します。 ビュー関数のrender_template呼び出しからヘッダー引数を安全に削除して、ifステートメントの動作を確認できます。

パターンサイクル


アプリケーションにログインするユーザーは、メインページの連絡先リストにあるユーザーからの最近のエントリを見たいと思うでしょう。その方法を見てみましょう。

最初に、いくつかの偽のユーザーと表示するエントリ( app/views.py )を作成するトリックをapp/views.py
 def index(): user = { 'nickname': 'Miguel' } #   posts = [ #    { 'author': { 'nickname': 'John' }, 'body': 'Beautiful day in Portland!' }, { 'author': { 'nickname': 'Susan' }, 'body': 'The Avengers movie was so cool!' } ] return render_template("index.html", title = 'Home', user = user, posts = posts) 


カスタムエントリを表示するには、各要素に作成者フィールドとメインフィールドがあるリストを使用します。 実際のデータベースの実装に到達したら、これらのフィールド名を保存します。これにより、データベースにアクセスするときに更新を心配することなく、偽のオブジェクトを使用してテンプレートを設計およびテストできます。

テンプレート側から、新しい問題を解決する必要があります。 既存のリストには任意の数の要素を含めることができ、送信するメッセージの数を決定する必要があります。 テンプレートはメッセージの数について何も仮定できないため、ビューが送信する数のメッセージを表示する準備ができている必要があります。

制御構造(ファイルapp/templates/index.html )を使用してこれを行う方法を見てみましょう:
 <html> <head> {% if title %} <title>{{title}} - microblog</title> {% else %} <title>microblog</title> {% endif %} </head> <body> <h1>Hi, {{user.nickname}}!</h1> {% for post in posts %} <p>{{post.author.nickname}} says: <b>{{post.body}}</b></p> {% endfor %} </body> </html> 


そんなに難しくないですか? アプリケーションを確認し、エントリのリストへの新しいコンテンツの追加を必ず確認します。

テンプレートの継承


本日終了する前に、別のトピックを取り上げます。

マイクロブログアプリには、ページ上部にいくつかのリンクがあるナビゲーションバーが必要です。 プロフィールの編集、終了などのリンクがあります。

index.htmlテンプレートにナビゲーションバーを追加できますが、アプリケーションが成長するとすぐに、さらにテンプレートが必要になり、ナビゲーションバーをそれぞれのテンプレートにコピーする必要があります。 次に、これらすべてのコピーを同じ状態に保つ必要があります。 多くのテンプレートがある場合、これは時間のかかるタスクになります。

代わりに、Jinja2テンプレートで継承を使用できます。これにより、ページレイアウトの一部を、他のすべてのテンプレートが継承される共通の基本テンプレートに移動できます。

次に、ナビゲーションバーを含む基本テンプレートと、以前に実装したヘッダーロジック(ファイルapp/templates/base.html )をapp/templates/base.htmlます。
 <html> <head> {% if title %} <title>{{title}} - microblog</title> {% else %} <title>microblog</title> {% endif %} </head> <body> <div>Microblog: <a href="/index">Home</a></div> <hr> {% block content %}{% endblock %} </body> </html> 


このテンプレートでは、 blockコントロール演算子を使用して、子テンプレートを挿入できる場所を決定しました。 ブロックには一意の名前が付けられます。

base.html (ファイルapp/templates/index.html )からbase.htmlようにindex.htmlを変更する必要があります:
 {% extends "base.html" %} {% block content %} <h1>Hi, {{user.nickname}}!</h1> {% for post in posts %} <div><p>{{post.author.nickname}} says: <b>{{post.body}}</b></p></div> {% endfor %} {% endblock %} 


これで、 base.htmlテンプレートのみがページの全体的な構造を担当します。 ここからこれらの要素を削除し、内容のある部分のみを残しました。 extendsブロックは、2つのテンプレート間の遺伝的関係を確立しbase.htmlbase.htmlbase.htmlbase.htmlますbase.htmlを指定する必要がある場合、 base.htmlに含める必要があります。 2つのテンプレートにはcontentという一致するblockステートメントがありcontent 。これが、Jinja2が2つのテンプレートを1つに結合する方法を知っている理由です。 新しいテンプレートを作成するとき、 base.html拡張として作成することも開始します

最後の言葉


時間を節約したい場合は、現在の段階のマイクロブログアプリケーションをここから入手できます。
ダウンロードmicroblog-0.2.zip

zipファイルには、フラスコ仮想環境が含まれていないことに注意してください。 最初のパートの指示に従って自分で作成し、その後アプリケーションを起動できます。

シリーズの次のパートでは、フォームを見ていきます。 またお会いしましょう。

ミゲル

Source: https://habr.com/ru/post/J193260/


All Articles