手順 2: ビューおよびページ テンプレートを使用して Django アプリを作成する

前の手順:Visual Studio プロジェクトとソリューションを作成する

Visual Studio プロジェクトにあるのは、1 つ以上の Django "アプリ" を実行できる Django "プロジェクト" のサイトレベル要素だけです。 次の手順では、単一のページを持つ最初のアプリを作成します。

この手順では、次の方法を学習します。

  • 単一のページを持つ Django アプリを作成する (手順 2-1)
  • Django プロジェクトからアプリを実行する (手順 2-2)
  • HTML を使用してビューを表示する (手順 2-3)
  • Django ページ テンプレートを使用してビューを表示する (手順 2-4)

手順 2-1: 既定の構造を備えたアプリを作成する

Django アプリは、特定の目的のために関連ファイルのセットを含む別個の Python パッケージです。 Django プロジェクトには多くのアプリを含めることができ、これによって Web ホストは 1 つのドメイン名から多数の個別のエントリ ポイントを提供できます。 たとえば、contoso.com のようなドメインに対する Django プロジェクトでは、www.contoso.com に 1 つ目のアプリ、support.contoso.com に 2 つ目のアプリ、docs.contoso.com に 3 つ目のアプリを含めることが可能です。 この場合、Django プロジェクトは、サイトレベルの URL ルーティングと設定 (urls.pysettings.py のファイル内) を処理します。 各アプリには、内部ルーティング、ビュー、モデル、静的ファイル、および管理インターフェイスを通じた独自のスタイルと動作があります。

通常、Django アプリは、標準的なファイル セットから始まります。 次に示すように、Visual Studio では Django プロジェクト内にある Django アプリを初期化するテンプレートを提供しています。また、同様の目的を果たす統合メニュー コマンドもあります。

  • テンプレート: ソリューション エクスプローラーで、プロジェクトを右クリックして、[追加]>[新しい項目] の順に選択します。 [新しい項目の追加] ダイアログで、Django 1.9 アプリ テンプレートを選択し、[名前] フィールドにアプリ名を指定して、[OK] を選択します。

Screenshot of Solution Explorer.

Screenshot of Add New Item window.

  • 統合コマンド: ソリューション エクスプローラーで、プロジェクトを右クリックして、[追加]>[Django アプリ] の順に選択します。 このコマンドでは、名前の入力を求められます。 [新しいアプリ名] フィールドにアプリ名を指定し、[OK] を選択します。

    Menu command for adding a Django app.

    Menu command to enter a Django app name.

どちらかの方法を使って、"HelloDjangoApp" という名前のアプリを作成します。 これで、"HelloDjangoApp" フォルダーがプロジェクトに作成されます。 このフォルダーには、次の項目が含まれています。

Django app files in Solution Explorer.

項目 説明
migrations Django が、モデルに対する変更に沿ってデータベースを更新するスクリプトを格納するためのフォルダー。 Django の移行ツールは、現在のモデルに適合するように、データベースの任意の以前のバージョンに必要な変更を適用します。 移行を使用して、モデルにフォーカスを保持し、Django が基になるデータベース スキーマを処理できるようにします。 移行については、Django のドキュメントを参照してください。 現状では、フォルダーに __init__.py ファイル (フォルダーが独自の Python パッケージを定義していることを示す) が含まれています。
__init__.py アプリをパッケージとして識別するファイル。
templates 1 つの index.html ファイルを含む Django ページ テンプレート用のフォルダー。 index.html ファイルは、アプリ名と同じ名前のフォルダーに配置されます。 (Visual Studio 2017 15.7 とそれ以前では、ファイルは templates の直下に配置され、手順 2-4 によってサブフォルダーを作成するよう指示されます。) テンプレートは HTML のブロックであり、ビューでページを動的にレンダリングするための情報を追加できます。 index.html 内の {{ content }} のようなページ テンプレート "変数" は、この記事で後述する動的な値のプレースホルダーです (手順 2)。 通常、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 ビューは Web ページと似ていて、HTTP 要求を受け取り、HTTP 応答を返します。 一般的に、ビューは HTML をレンダリングし、Web ブラウザーは表示方法を認識していますが、ビューが必ずしも表示されるとは限りません (中間フォームのように)。 ビューは、HTML をブラウザーにレンダリングする役割を担う Python 関数によって定義されています。 views.py ファイルは、ビューを作成する既定の場所です。 最初、views.py ファイルにはステートメント from django.shortcuts import render のみが含まれています。

"HelloDjangoApp" という名前を使用すると、 apps.py ファイルの内容は次のように表示されます。

from django.apps import AppConfig

class HelloDjangoAppConfig(AppConfig):
    name = 'HelloDjango'

質問: Visual Studio で Django アプリを作成することは、コマンド ラインでアプリを作成することと、どう違うのですか。

回答: Django アプリ テンプレートを使って、[追加]>[Django アプリ] コマンドを実行するか、または [追加]>[新しい項目] を使用すると、Django コマンド manage.py startapp <app_name> の場合と同じファイルが作成されます。 Visual Studio でアプリを作成することのベネフィットは、アプリ フォルダーとその中のすべてのファイルが自動的にプロジェクトに統合されることです。 同じ Visual Studio コマンドを使用して、プロジェクト内に任意の数のアプリを作成できます。

手順 2-2: Django プロジェクトからアプリを実行する

この時点で、Visual Studio のプロジェクトをもう一度実行すると (ツール バー ボタンまたは [デバッグ]>[デバッグの開始] を使用)、まだ既定のページが表示されます。 アプリ固有のページを定義し、アプリを Django プロジェクトに追加する必要があるため、アプリのコンテンツは表示されません。

  1. HelloDjangoApp フォルダーで、views.py ファイルを変更して、"index" という名前のビューを定義します。

    from django.shortcuts import render
    from django.http import HttpResponse
    
    def index(request):
        return HttpResponse("Hello, Django!")
    
  2. BasicProject フォルダー (手順 1 で作成済み) で、以下のコードに合わせて 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 (つまり、https://www.domain.com/ に続く部分) のルーティング先にするビューを示します。 正規表現 ^$ から始まる urlPatterns の最初のエントリは、サイト ルート "/" に対するルーティングです。 2 つ目のエントリである ^home$ は、明示的に "/home" をルーティングします。 同じビューに対して複数のルーティングを使用できます。

  3. もう一度プロジェクトを実行すると、ビューに定義されたとおり、"Hello, Django!" というメッセージが表示されます。 完了したら、サーバーを停止します。

ソース管理へのコミット

コードに変更を加え、テストが正常に行われたら、確認してソース管理にコミットできます。 このチュートリアルの後半の手順で、再びソース管理について触れた場合は、このセクションを参照してください。

  1. Visual Studio の下部にある変更ボタン (下の丸印) を選択すると、チーム エクスプローラーに移動します。

    Source control changes button on the Visual Studio status bar.

  2. チーム エクスプローラーで "最初の Django アプリの作成" などのコミット メッセージを入力して、[Commit All]\(すべてコミットする\) を選択します。 コミットが完了すると、"<hash> のコミットがローカルで作成されました。変更をサーバーと共有するには、同期を使用してください。" というメッセージが表示されます。リモート リポジトリに変更をプッシュする場合は、[同期] を選択して、[出力方向のコミット] にある [プッシュ] を選択します。 リモートにプッシュする前に、複数のローカル コミットを蓄積しておくことも可能です。

    Push commits to remote repository in Team Explorer.

質問: ルーティング文字列の前にある 'r' というプレフィックスは何のためにあるのですか。

回答: Python の文字列にある 'r' プレフィックスは "raw" (生) という意味で、文字列内のどの文字もエスケープしないよう Python に指示しています。 正規表現では、多くの特殊文字が使用されます。 'r' プレフィックスを使用すると、エスケープ文字 '\' よりもはるかに文字列を読み取りやすくなります。

質問: URL ルーティング エントリでは、^ および $ 文字にどのような意味がありますか。

回答: URL パターンを定義する正規表現では、^ は "行の開始" を意味し、$ は "行の終了" を意味します。ここで、URL はサイト ルートへの相対 (https://www.domain.com/ の後に続く部分) です。 正規表現 ^$ は実質的に "空白" を意味するため、完全な URL https://www.domain.com/ (サイト ルートに何も追加されない) と一致します。 パターン ^home$https://www.domain.com/home/ と完全に一致します (Django では、パターン マッチングに末尾の / を使用しません)。

^home のように、正規表現で末尾の $ を使用しない場合、URL パターンは "home"、"homework"、"homestead"、および "home192837" など、"home" で始まる任意の URL と一致します。

別の正規表現を使って実験するには、pythex.orgregex101.com のようなオンライン ツールを試行してください。

手順 2-3: HTML を使用してビューを表示する

views.py ファイルの index 関数によって、ページにプレーンテキストの HTTP 応答が生成されます。 現実のほとんどの Web ページは、ライブ データを頻繁に取り込むリッチな HTML ページを使って応答します。 実際、関数を使用してビューを定義する主な理由はコンテンツを動的に生成することにあります。

HttpResponse の引数は単に文字列なので、文字列内に自由に HTML を構築できます。 簡単な例として、index 関数を次のコードに置き換えます (既存の from ステートメントは保持します)。 その後、index 関数では、ページを更新するごとに新しくなる動的コンテンツを使用して、HTML 応答が生成されます。

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)

ここで、もう一度プロジェクトを実行すると、"Hello Django! on Monday, 16 April, 2018 at 16:28:10" のようなメッセージが表示されます。 ページを更新すると時間が更新され、各要求によってコンテンツが生成されていることを確認できます。 完了したら、サーバーを停止します。

ヒント

プロジェクトの停止および再起動を行う簡単な方法として、[デバッグ]>[再起動] メニュー コマンド (Ctrl+Shift+F5 キー) を使用するか、または以下のデバッグ ツールバーの [再起動] ボタンを使用します。

Restart button on the debugging toolbar in Visual Studio.

手順 2-4: ページ テンプレートを使用してビューを表示する

コードで生成された HTML は、小さなページでも動作します。 ただし、ページが高度になると、ページの静的な HTML 部分 (そして CSS および JavaScript ファイルへの参照) を "ページ テンプレート" として維持する必要があります。これで、動的なコード生成コンテンツをページ テンプレートに挿入できます。 前のセクションでは、now.strftime 呼び出しの日時のみが動的であり、それ以外のすべての内容はページ テンプレートに配置できることを意味します。

Django ページ テンプレートは、"変数" と呼ばれる複数の置換トークンを含む HTML のブロックです。変数は、{{}} (例: {{ content }}) で示されます。 Django のテンプレート モジュールは、コードで提供した動的コンテンツで変数を置き換えます。

ページ テンプレートを使用する手順を次に示します。

  1. Django プロジェクトを含む BasicProject フォルダーの下で、settings.py ファイルを開きます。 アプリ名 "HelloDjangoApp" を INSTALLED_APPS 一覧に追加します。 アプリを一覧に追加すると、アプリを格納している "HelloDjangoApp" という名前のフォルダーがあることが、Django プロジェクトに通知されます。

    INSTALLED_APPS = [
        'HelloDjangoApp',
        # Other entries...
    ]
    
  2. settings.py ファイルで、TEMPLATES オブジェクトに次の行が含まれている (既定で含まれている) ことを確認します。 次のコードは、インストールされているアプリの templates フォルダー内のテンプレートを探すよう Django に指示します。

    'APP_DIRS': True,
    
  3. HelloDjangoApp フォルダーの templates/HelloDjangoApp/index.html ページ テンプレート ファイル (VS 2017 15.7 以前の場合、templates/index.html) を開き、{{ content }} という 1 つの変数が含まれていることを確認します。

    <html>
      <head>
        <title></title>
      </head>
    
      <body>
        {{ content }}
      </body>
    </html>
    
  4. HelloDjangoApp フォルダーの views.py を開き、index 関数を django.shortcuts.render ヘルパー関数を使用する次のコードに置き換えます。 render ヘルパーは、ページ テンプレートを操作するために簡素化されたインターフェイスを提供しています。 すべての既存の from ステートメントを保持してください。

    from django.shortcuts import render   # Added for this step
    
    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
            {
                'content': "<strong>Hello Django!</strong> on " + now.strftime("%A, %d %B, %Y at %X")
            }
        )
    

    render の最初の引数は要求オブジェクトであり、その後ろにはアプリの templates フォルダー内の一時ファイルへの相対パスが続きます。 必要に応じて、ビューに対応する名前を付けたテンプレートがサポートされます。 render の 3 つ目の引数は、テンプレートが参照する変数のディクショナリです。 ディクショナリにオブジェクトを含めることができ、その場合はテンプレートの変数が {{ object.property }} を参照できます。

  5. プロジェクトを実行して、出力を確認します。 手順 2-2 で確認したものとほぼ同じメッセージが表示され、テンプレートが機能していることが示されます。

    content プロパティで使用した HTML がプレーン テキストとしてのみレンダリングされることを確認してください。render 関数は自動的にこの HTML をエスケープするためです。 自動エスケープにより、インジェクション攻撃に対する偶発的な脆弱性が防止されます。 開発者は多くの場合、あるページから入力を収集し、テンプレート プレースホルダーを使用してそれを別のページの値として使用します。 エスケープは、HTML をコードとは別にページ テンプレートに保存する方法が最善であることを思い出すためにも役立ちます。 また、必要に応じてより多くの変数を作成するのも簡単です。 たとえば、次のマークアップに合うように index.html ファイルを template で変更します。 次のマークアップでは、ページ タイトルが追加され、ページ テンプレート内のすべての書式設定が保持されます。

    <html>
      <head>
        <title>{{ title }}</title>
      </head>
      <body>
        <strong>{{ message }}</strong>{{ content }}
      </body>
    </html>
    

    次に、ページ テンプレートのすべての変数の値を指定するために、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")
            }
        )
    
  6. サーバーを停止し、プロジェクトを再起動します。 ページが正しくレンダリングされていることを確認します。

    Running app using the template.

  7. Visual Studio 2017 バージョン 15.7 以前: 最後の手順として、アプリと同じ名前のサブフォルダーにテンプレートを移動します。 サブフォルダーによって名前空間が作成され、プロジェクトに追加される可能性のある他のアプリとの潜在的な競合が回避されます。 (VS 2017 15.8 以降のテンプレートでは、これが自動的に行われます。) つまり、HelloDjangoApp という名前の templates にサブフォルダーを作成し、そのサブフォルダーに index.html ファイルを移動して、index ビュー関数を変更します。 index ビュー関数は、テンプレートの新しいパス HelloDjangoApp/index.html を参照します。 次に、プロジェクトを実行してページが正しく表示されることを確認し、サーバーを停止します。

  8. ソース管理への変更をコミットし、必要に応じて手順 2-2 の説明に従って、リモート リポジトリを更新します。

質問:ページ テンプレートを別のファイルにする必要はありますか。

回答: 通常、テンプレートは別々の HTML ファイルで維持されます。 インライン テンプレートを使用することもできます。 マークアップとコード間の明確な分離を維持するために、別個のファイルを使用することが推奨されています。

質問: テンプレートには、.html のファイル名拡張子を使用する必要がありますか。

回答: render 関数の 2 つ目の引数でファイルへの正確な相対パスが識別されるため、ページ テンプレート ファイルの .html 拡張子は完全にオプションです。 ただし、Visual Studio (および、その他のエディター) では、.html ファイルでのコード補完や構文の色付けなどの機能を提供しており、このことは、ページ テンプレートが厳密に HTML ではないという事実よりも重要です。

実際に、Django プロジェクトを操作していると、Visual Studio では、HTML ファイルに Django テンプレートが含まれることを自動検出して、特定のオートコンプリート機能を提供します。 たとえば、Django ページ テンプレートのコメント {# の入力を開始すると、Visual Studio では終了の #} 文字を自動的に提示します。 また、[選択範囲のコメント] および [選択範囲のコメントを解除] コマンド ([編集]>[詳細] メニューおよびツールバー上にある) では、HTML コメントではなく、テンプレート コメントを使用します。

質問: プロジェクトを実行すると、テンプレートが見つからないというエラーが表示されます。 理由

回答: テンプレートが見つからないというエラーが表示される場合は、アプリを INSTALLED_APPS 一覧にある Django プロジェクトの settings.py に追加済みであることを確認してください。 そのエントリがない場合、Django ではアプリの templates フォルダー内の検索が認識されません。

質問: どうして、テンプレートの名前空間の設定が重要なのですか。

回答: Django が render 関数で参照されるテンプレートを検索すると、相対パスに一致する最初に検出したファイルが使用されます。 テンプレートに同じフォルダー構造を使用している複数の Django アプリが、同じプロジェクト内にある場合、1 つのアプリが意図せずに、もう 1 つのアプリのテンプレートを使用します。 このようなエラーを回避するために、アプリの templates フォルダー内にアプリ名と一致するサブフォルダーを必ず作成して、あらゆる重複を防止してください。

次のステップ

詳しい説明