この記事では、 Visual Studio の Django Web フレームワークを操作するチュートリアル シリーズの手順 2 について説明します。
Visual Studio では、プロジェクトのより広範な開始点を提供するプロジェクト テンプレートから Django アプリケーションを作成できます。 チュートリアル シリーズの手順 1 では、1 つ以上の Django Web アプリをサポートする Django Web プロジェクトのサイト レベルの構成ファイルを作成する方法について説明します。 手順 2 では、Django Web プロジェクトにコンテンツを追加して、複数の表示ビューを含む 1 ページで最初の Django Web アプリを作成します。
チュートリアルの手順 2 では、次の方法を学習します。
- 1 つのページで Django アプリを作成する
- Django プロジェクトからアプリを実行する
- HTML を使用してビューをレンダリングする
- Django ページ テンプレートを使用してビューをレンダリングする
[前提条件]
「手順 1: Visual Studio ソリューションと Django プロジェクトを作成する」で作成した Visual Studio ソリューションと Django プロジェクト。
Django テンプレートのバージョン、Visual Studio プロジェクトと Django プロジェクト、Mac での Python 開発の詳細については、このチュートリアル シリーズの手順 1 の「前提条件の」セクションを参照してください。
既定の構造で Django アプリを作成する
Django アプリは、特定の目的に関連するファイルのセットを含む別の Python パッケージです。 Django プロジェクトには多数のアプリを含めることができます。これは、Web ホストが 1 つのドメイン名から多数の独立したエントリ ポイント (または ルート) を提供するのに役立ちます。 たとえば、 contoso.com
のようなドメインの Django プロジェクトには、 www.contoso.com
ルート用の 1 つのアプリ、 support.contoso.com
ルート用の 2 つ目のアプリ、 docs.contoso.com
ルート用の 3 つ目のアプリが含まれる場合があります。 このシナリオでは、Django プロジェクトは、 urls.py ファイルと settings.py ファイル内のサイト レベルの URL ルーティングと設定を処理します。 各アプリには、内部ルーティング、ビュー、モデル、静的ファイル、管理インターフェイスを通じて、独自のスタイル設定と動作があります。
Django アプリの開発は、通常、標準のファイル セットから始まります。 Visual Studio には、Django プロジェクト内でこれらのファイルを使用して Django アプリを初期化するためのテンプレートが用意されています。 また、同じ目的を果たす統合メニュー コマンドもあります。
テンプレートを使用してアプリを作成する
テンプレートからアプリを作成するには、次の手順に従います。
ソリューション エクスプローラーで、Visual Studio プロジェクト (BasicProject) を右クリックし、[追加>新しい項目] を選択します。
[ 新しい項目の追加 ] ダイアログで、 Django 1.9 アプリ テンプレートを選択します。
アプリ 名HelloDjangoApp を入力します。
[] を選択し、[] を追加します。
統合メニュー コマンドを使用してアプリを作成する
統合された Django メニュー コマンドを使用してアプリを作成するには、次の手順に従います。
ソリューション エクスプローラーで、Visual Studio プロジェクト (BasicProject) を右クリックし、[追加>Django アプリ] を選択します。
[ Django アプリの追加 ] ダイアログで、アプリ名 HelloDjangoApp を入力します。
[OK] を選択.
Django アプリ フォルダーを探索する
HelloDjangoApp アプリを作成すると、Visual Studio プロジェクトに同じ名前のフォルダーが作成されます。
フォルダーには、次の項目が含まれています。
Item | 説明 |
---|---|
移行 | モデルの変更に合わせてデータベースを更新するスクリプトを Django が格納するフォルダー。 その後、Django の移行ツールは、現在のモデルに合わせて、必要な変更を以前のバージョンのデータベースに適用します。 移行を使用する場合は、モデルに重点を置き、基になるデータベース スキーマを Django が処理できるようにします。 このチュートリアル シリーズの演習では、フォルダーに __init__.py ファイルが含まれています。これは、フォルダーが独自の Python パッケージを定義していることを示します。 詳細については、「Django のドキュメント」を参照してください。 |
__init__.py | init ファイルが存在すると、Django アプリがパッケージとして識別されます。 |
テンプレート | 1 つの index.html ファイルを含む Django ページ テンプレートのフォルダー。 index.html ファイルは、アプリ名と同じ名前のフォルダーに配置されます。 テンプレートは HTML ブロックであり、ビューで情報を追加してページを動的にレンダリングできます。 ページ テンプレートの "変数" (index.htmlファイル内の{{ content }} など) は、この記事で後述する動的な値のプレースホルダーです。 通常、Django アプリは、アプリ名に一致するサブフォルダーにテンプレートを配置することで、テンプレートの名前空間を作成します。 |
admin.py | アプリの管理インターフェイスを拡張する Python ファイル。データベース内のデータを表示および編集するために使用されます。 最初に、このファイルにはステートメント ( from django.contrib import admin ) のみが含まれます。 既定では、Django には、Django プロジェクトの settings.py ファイル内のエントリを介した標準の管理インターフェイスが含まれています。 インターフェイスを有効にするには、 urls.py ファイル内の既存のエントリのコメントを解除します。 |
apps.py | アプリの構成クラスを定義する Python ファイル。 (この表の後の例を参照してください)。 |
models.py | モデルは、ビューがアプリの基になるデータベースと対話する関数によって識別されるデータ オブジェクトです。 Django は、アプリがモデルの詳細に関心を持たないように、データベース接続レイヤーを提供します。 models.py ファイルは、モデルを作成する既定の場所です。 最初に、 models.py ファイルにはステートメント ( from django.db import models ) のみが含まれます。 |
tests.py | 単体テストの基本的な構造を含む Python ファイル。 |
views.py | ビューは、HTTP 要求を受け取り、HTTP 応答を返す Web ページに似ています。 通常、ビューは HTML としてレンダリングされ、Web ブラウザーは表示方法を認識しますが、ビューを表示する必要はありません (中間フォームなど)。 Python 関数は、HTML をブラウザーにレンダリングするビューを定義します。 views.py ファイルは、ビューを作成する既定の場所です。 最初に、 views.py ファイルにはステートメント ( from django.shortcuts import render ) のみが含まれます。 |
"HelloDjangoApp" という名前を使用すると、 apps.py ファイルの内容は次のように表示されます。
from django.apps import AppConfig
class HelloDjangoAppConfig(AppConfig):
name = 'HelloDjangoApp'
Visual Studio またはコマンド ラインからアプリを作成する
Add>Django アプリ コマンドと Add>New Item コマンド (Django アプリケーション テンプレートと組み合わせる) は、Django CLI コマンド manage.py startapp <app_name>
と同じファイルを生成します。 Visual Studio で Django アプリを作成する利点は、アプリ フォルダーとそのすべてのファイルがプロジェクトに自動的に統合される点です。 同じ Visual Studio コマンドを使用して、プロジェクトに任意の数のアプリを作成できます。
アプリ固有のページ ビューを追加する
Visual Studio で現在のプロジェクトを実行する場合は、メイン ツール バーの [デバッグの開始>デバッグの開始 (F5) または Web サーバーを選択すると、既定の Django ページが表示されます。 Web アプリには、通常、ビューが異なる複数のページがあります。 アプリの URL アドレスの一意のルートは、アプリ内の各ページを識別します。
アプリ固有のページ ビューを定義し、Django プロジェクトにアプリを追加するには、次の手順に従います。
Visual Studio プロジェクトの HelloDjangoApp サブフォルダーで、 views.py ファイルの内容を次のコードに置き換えます。
from django.shortcuts import render from django.http import HttpResponse def index(request): return HttpResponse("Hello, Django!")
このコードは、必要なレンダリング定義と HTTP 定義をインポートし、
index
という名前のビューを定義します。Visual Studio プロジェクトの BasicProject サブフォルダーで、次のコードに一致するように urls.py ファイルを変更します。 必要に応じて、現在のファイルに指示的なコメントを保持できます。
from django.urls import include, re_path import HelloDjangoApp.views # Django processes URL patterns in the order they appear in the array urlpatterns = [ re_path(r'^$', HelloDjangoApp.views.index, name='index'), re_path(r'^home$', HelloDjangoApp.views.index, name='home') ]
各 URL パターンは、Django が特定のサイト相対 URL をルーティングするビュー (つまり、URL アドレス https://www.domain.com/
に続くルート部分) を記述します。
- 正規表現
^$
で始まるurlPatterns
定義の最初のエントリは、サイト ルート ページのルーティング/
です。 - 2 番目のエントリ (
^home$
) は、アプリケーション/home
ページにルーティングされます。
このコード例の定義では、同じビューに対して複数のルーティングを実行できることを示しています。
(r) プレフィックスを使用して未加工のルート文字列を定義する
Python のルート文字列の r
プレフィックスは "raw" を意味します。このプレフィックスは、ルート文字列内の文字をエスケープしないように Python に指示します。 ルート文字列の正規表現では、多くの特殊文字が使用されます。 ルート文字列の r
プレフィックスは、エスケープ文字 \
よりも読みやすいです。
ルートでキャレット (^) 文字とドル ($) 文字を使用する
URL パターンを定義する正規表現では、キャレット記号 ^
は "行の開始" を意味し、ドル記号 $
は "行末" を意味します。サイト ルートに対する相対 URL (アプリ アドレス https://www.domain.com/
に続く部分) では、これらの文字に対していくつかの用途があります。
- 正規表現
^$
は実質的に "空白" を意味し、アプリのサイト ルート (https://www.domain.com/
) の完全な URL アドレスと一致します。 - パターン
^home$
はhttps://www.domain.com/home/
に正確に一致し、これは/home
が続くサイトルートです。 Djangoはパターンマッチングで末尾の/を使用しません。 ^home
ルート文字列など、正規表現で末尾のドル記号$
を使用しない場合、URL パターン マッチングは、home
、homework
、homestead
、home192837
など、home
で始まるすべての URL に適用されます。
さまざまな正規表現を試すには、pythex.org でregex101.com などのオンライン ツールを試してください。
Django プロジェクトからアプリを実行する
アプリ固有のコンテンツを追加したら、アプリをもう一度実行し、ブラウザーでルート ビューを確認します。
アプリケーションがブラウザーで開いたら、ブラウザーで
/
(サイト ルート) と/home
URL ルートの両方のページ ビューを確認します。 どちらのルートでも、アプリケーションはブラウザーに Hello, Django! というメッセージを表示します。完了したら、コンソール ウィンドウで Ctrl+C を選択し、その後に任意のキーを押してアプリケーションを停止します。 [デバッグ]>[デバッグの停止]を選択することもできます。
アプリケーションの開いているブラウザー ウィンドウを閉じます。
ソース管理に変更をコミットする
Django アプリ コードを更新し、更新プログラムをテストしたら、変更を確認してソース管理にコミットできます。
Ctrl+S キーボード ショートカットを使用して、プロジェクト ファイルへの変更を保存します。
Git コントロール バーで、コミットされていない変更 (鉛筆 11) を選択して、[ Git の変更] ウィンドウを開きます。
[ Git の変更 ] ウィンドウで、コミット メッセージを入力し、[ すべてコミット] を選択します。
コミットが完了すると、ローカルで 作成されたコミット <hash> メッセージが Visual Studio に表示されます。
(省略可能)コミットされた変更をリモート リポジトリにプッシュします。
Git コントロール バーで、送信/受信コミット (矢印 1/0) を選択します。
[ 同期 (プルしてからプッシュ)] または [プッシュ] を選択 します。
リモート リポジトリにプッシュする前に、複数のローカル コミットを蓄積することもできます。
Ctrl+S キーボード ショートカットを使用して、プロジェクト ファイルへの変更を保存します。
Visual Studio の右下にあるコミットされていない変更 (鉛筆 11) を選択すると、 チーム エクスプローラーが開きます。
チーム エクスプローラーで、"Create Django app-specific page" のようなコミット メッセージを入力し、[すべてコミット] を選択します。
コミットが完了すると、ローカルで 作成されたコミット <hash> メッセージが Visual Studio に表示されます。同期して変更をサーバーと共有します。
(省略可能)コミットされた変更をリモート リポジトリにプッシュします。
チーム エクスプローラーで、[同期] を選択します。
[送信コミット] を展開し、[プッシュ]を選択します。
リモート リポジトリにプッシュする前に、複数のローカル コミットを蓄積することもできます。
このチュートリアル シリーズの以降の手順では、ソース管理に変更をコミットする手順については、このセクションを参照してください。
テンプレートを使用してページとビューをレンダリングする
views.py ファイルのindex
関数は、Django アプリ ページのプレーンテキスト HTTP 応答を生成します。 ほとんどの実際の Web ページは、多くの場合、ライブ データを組み込むリッチ HTML ページで応答します。 開発者が関数を使用してビューを定義する主な理由は、コンテンツを動的に生成するためです。
HttpResponse
メソッドの引数は単なる文字列です。 動的コンテンツを使用して、文字列内の任意の HTML を構築できます。 マークアップをデータから分離することをお勧めします。そのため、マークアップをテンプレートに配置し、データをコードに保持することをお勧めします。
インライン HTML を使用するようにビューを調整する
動的コンテンツのあるページにインライン HTML を使用するようにビュー処理を変換します。
Visual Studio プロジェクトの HelloDjangoApp サブフォルダーで、 views.py ファイルを開きます。
index
関数を次のコードに置き換えます (既存のfrom
ステートメントを保持します)。from datetime import datetime def index(request): now = datetime.now() html_content = "<html><head><title>Hello, Django</title></head><body>" html_content += "<strong>Hello Django!</strong> on " + now.strftime("%A, %d %B, %Y at %X") html_content += "</body></html>" return HttpResponse(html_content)
変更後の
index
関数は、ページを更新するたびに更新される動的コンテンツを使用して HTML 応答を生成します。変更を保存し、アプリをもう一度実行します。 このページには、現在の日付と時刻と共に "Hello Django! メッセージ" が表示されます。
ページを数回更新して、日付と時刻が更新されることを確認します。 完了したら、アプリを停止します。
ページ ビュー用の HTML テンプレートを作成する
コードで HTML を生成すると、小さなページで問題なく動作します。 ただし、ページが高度になるにつれて、ページの静的 HTML 部分 (CSS および JavaScript ファイルへの参照と共に) を "ページ テンプレート" として維持する必要があります。その後、動的なコード生成コンテンツをページ テンプレートに挿入できます。 前のセクションでは、 now.strftime
呼び出しの日時のみが動的であるため、他のすべてのコンテンツをページ テンプレートに配置できます。
Django ページ テンプレートは、"変数" と呼ばれる複数の置換トークンを含む HTML のブロックです。中かっこ {{
を開いたり閉じたり }}
、 {{ content }}
などの変数を線で示します。 その後、Django のテンプレート モジュールは、変数をコードで指定した動的コンテンツに置き換えます。
HTML テンプレートを使用するようにページ レンダリング プロセスを変換するには、次の手順に従います。
Visual Studio プロジェクトの HelloDjangoApp サブフォルダーで、 settings.py ファイルを開きます。
INSTALLED_APPS
定義内のアプリケーション参照を更新して、アプリ名のHelloDjangoApp
を含めます。 アプリ名をリストの最初のエントリとして追加します。INSTALLED_APPS = [ 'HelloDjangoApp', # Existing entries in the list ... ]
アプリを一覧に追加すると、アプリを含む HelloDjangoApp という名前のフォルダーがあることを Django プロジェクトに通知します。
TEMPLATES
オブジェクト構成セットAPP_DIRS
True
を確認します。'APP_DIRS': True,
このステートメントは、インストールされているアプリケーションの templates フォルダー内のテンプレートを探すように Django に指示します。 (このステートメントは、既定で定義に含める必要があります)。
HelloDjangoApp サブフォルダーで、templates/HelloDjangoApp/index.html ページ テンプレート ファイルを開きます。
ファイルに変数が 1 つだけ含まれていることを確認
{{ content }}
。<html> <head> <title></title> </head> <body> {{ content }} </body> </html>
{{ content }}
ステートメントは、コードに値を指定するプレースホルダーまたは置換トークン (テンプレート変数とも呼ばれます) です。Visual Studio プロジェクトの HelloDjangoApp サブフォルダーで、 views.py ファイルを開きます。
index
関数を、django.shortcuts.render
ヘルパー関数を使用する次のコードに置き換えます (既存のfrom
ステートメントを保持します)。def index(request): now = datetime.now() return render( request, "HelloDjangoApp/index.html", # Relative path from the 'templates' folder to the template file { 'content': "<strong>Hello Django!</strong> on " + now.strftime("%A, %d %B, %Y at %X") } )
render
ヘルパー関数は、ページ テンプレートを操作するための簡略化されたインターフェイスを提供します。 この関数には、次の 3 つの引数があります。- リクエストオブジェクト。
- アプリの templates フォルダー内のテンプレート ファイルへの相対パス。 必要に応じて、サポートするビューのテンプレート ファイルに名前が付けられます。
- テンプレートが参照する変数のディクショナリ。 テンプレート内の変数が
{{ object.property }}
を参照できるオブジェクトをディクショナリに含めることができます。
プロジェクトの変更を保存し、アプリをもう一度実行します。
テンプレート エンジン (Jinja) は HTML コンテンツを自動的にエスケープするため、
content
値内のインライン HTML 構文 (\<strong>
...) が HTML としてレンダリングされない点に注意してください。 自動エスケープは、インジェクション攻撃に対する偶発的な脆弱性を防ぎます。開発者は多くの場合、あるページから入力を収集し、テンプレート プレースホルダーを使用して別のページの値として使用します。 エスケープは、HTML をコードから離しておくのが望ましいことを思い出させてくれます。
完了したら、アプリを停止します。
個別のプレースホルダーを使用する
HTML マークアップ内のデータごとに個別のプレースホルダーを使用できます。 次に、 index
関数をもう一度調整して、特定のプレースホルダー値を指定します。
templates/HelloDjangoApp/index.html ページ テンプレート ファイルの内容を次のマークアップに置き換えます。
<html> <head> <title>{{ title }}</title> </head> <body> <strong>{{ message }}</strong>{{ content }} </body> </html>
この HTML マークアップは、ページ タイトルを追加し、ページ テンプレート内のすべての書式設定を保持します。
HelloDjangoApp/views.py ファイルで、
index
関数を次のコードに置き換えます。def index(request): now = datetime.now() return render( request, "HelloDjangoApp/index.html", # Relative path from the 'templates' folder to the template file # "index.html", # Use this code for VS 2017 15.7 and earlier { 'title' : "Hello Django", 'message' : "Hello Django!", 'content' : " on " + now.strftime("%A, %d %B, %Y at %X") } )
このコードは、ページ テンプレート内のすべての変数の値を提供します。
変更を保存し、アプリをもう一度実行します。 今回は、正しくレンダリングされた出力が表示されます。
変更をソース管理にコミットし、リモート リポジトリを更新できます。 詳細については、「 ソース管理への変更のコミット」を参照してください。
個別のページ テンプレート
テンプレートは通常、個別の HTML ファイルに保持されますが、インライン テンプレートを使用することもできます。 マークアップとコードを完全に分離するために、個別のファイルを使用することをお勧めします。
テンプレート .html 拡張機能を使用する
ページ テンプレート ファイルの .html 拡張機能は完全に省略可能です。 render_template
関数の最初の引数で、ファイルへの正確な相対パスを常に識別できます。 ただし、Visual Studio (およびその他のエディター) には、通常、ページ テンプレートが HTML ではないという事実を上回る、 .html ファイルでのコード補完や構文の色付けなどの機能が用意されています。
Django プロジェクトを操作すると、編集中の HTML ファイルが実際に Django テンプレートであるかどうかを自動的に検出し、特定のオートコンプリート機能を提供します。 Django ページ テンプレート コメント ({#
) の入力を開始すると、Visual Studio によって終了 #}
文字が自動的に提供されます。 [コメントの選択] コマンドと [コメント解除の選択] コマンド ([編集]>[追加] メニュー) では、HTML コメントの代わりにテンプレート コメントも使用されます。
問題のトラブルシューティング
アプリを実行すると、アプリのテンプレート ファイルに関連する問題が発生する可能性があります。 次の点を確認し、Django プロジェクトの構成が正しいことを確認します。
テンプレートが見つかりません
Django または Visual Studio で テンプレートが見つからない というエラーが表示される場合は、アプリが INSTALLED_APPS
一覧にあることを確認します。 この一覧は、Visual Studio プロジェクトのアプリ サブフォルダー (HelloDjangoApp など) の下にある settings.py ファイルにあります。 一覧にアプリのエントリがない場合、Django はアプリの テンプレート フォルダー内を検索することを認識しません。
重複するテンプレート構造
Django は、 render
関数で参照されるテンプレートを検索するときに、相対パスに一致する最初のファイルを使用します。 テンプレートのフォルダー構造が同じ同じプロジェクトに複数の Django アプリがある場合、あるアプリが別のアプリのテンプレートを誤って使用する可能性があります。 このようなエラーを回避するには、重複を回避するために、アプリの テンプレート フォルダーの下に、アプリの名前と一致するサブフォルダーを常に作成します。