VS Codeのエージェントモードを拡張するには、を試してください!

Visual Studio Code での Django チュートリアル

Django は、迅速で安全、かつスケーラブルな Web 開発のために設計された高水準の Python フレームワークです。Django には、URL ルーティング、ページ テンプレート、データ操作のための豊富なサポートが含まれています。

この Django チュートリアルでは、共通の基本テンプレートを使用する 3 つのページを持つ簡単な Django アプリを作成します。VS Code のターミナル、エディター、デバッガーで Django を扱う方法を理解するために、このアプリを Visual Studio Code のコンテキストで作成します。このチュートリアルでは、データモデルの操作や管理インターフェイスの作成など、Django 自体のさまざまな詳細については触れません。これらの側面に関するガイダンスについては、このチュートリアルの最後にある Django ドキュメントのリンクを参照してください。

この Django チュートリアルで完成したコードプロジェクトは GitHub で見つけることができます: python-sample-vscode-django-tutorial

問題が発生した場合は、Python 拡張機能 Discussions Q&A で回答を検索したり、質問したりできます。

前提条件

この Django チュートリアルを正常に完了するには、次のことを行う必要があります (これは一般的な Python チュートリアルの手順と同じです)

  1. Python 拡張機能をインストールします。

  2. Python 3 のバージョンをインストールします (このチュートリアルは Python 3 向けに書かれています)。オプションには以下が含まれます

    • (すべてのオペレーティングシステム) python.org からのダウンロード。通常は、ページに最初に表示される Download Python 3.9.1 ボタン (または最新バージョン) を使用します。
    • (Linux) 内蔵の Python 3 インストールでも問題ありませんが、他の Python パッケージをインストールするには、ターミナルで sudo apt install python3-pip を実行する必要があります。
    • (macOS) macOS 上で Homebrew を使用して brew install python3 でインストールします (macOS のシステムインストール版 Python はサポートされていません)。
    • (すべてのオペレーティングシステム) Anaconda からのダウンロード (データサイエンス目的)。
  3. Windows では、Python インタープリターの場所が PATH 環境変数に含まれていることを確認してください。コマンドプロンプトで path を実行すると場所を確認できます。Python インタープリターのフォルダーが含まれていない場合は、Windows の設定を開き、「環境」を検索して [アカウントの環境変数を編集] を選択し、Path 変数を編集してそのフォルダーを追加します。

Django チュートリアルのプロジェクト環境を作成する

このセクションでは、Django をインストールする仮想環境を作成します。仮想環境を使用することで、Django をグローバルな Python 環境にインストールすることを避け、アプリケーションで使用されるライブラリを正確に制御できます。仮想環境を使用すると、環境用の requirements.txt ファイルを作成するのも簡単になります。

  1. ファイルシステム上で、このチュートリアル用のプロジェクトフォルダーを作成します。例: hello_django

  2. そのフォルダーで、(お使いのコンピューターに合わせて) 次のコマンドを使用して、現在のインタープリターに基づいて .venv という名前の仮想環境を作成します。

    # Linux
    sudo apt-get install python3-venv    # If needed
    python3 -m venv .venv
    source .venv/bin/activate
    
    # macOS
    python3 -m venv .venv
    source .venv/bin/activate
    
    # Windows
    py -3 -m venv .venv
    .venv\scripts\activate
    

    : 上記のコマンドを実行する際には、標準の Python インストールを使用してください。Anaconda インストールの python.exe を使用すると、ensurepip モジュールが利用できないためエラーが発生し、環境は未完了の状態で残されます。

  3. code . を実行するか、VS Code を起動して [ファイル] > [フォルダーを開く] コマンドを使用して、プロジェクトフォルダーを VS Code で開きます。

  4. VS Code で、コマンド パレットを開きます ([表示] > [コマンド パレット] または (⇧⌘P (Windows, Linux Ctrl+Shift+P)))。次に、Python: Select Interpreter コマンドを選択します。

    Django tutorial: opening the Command Palette in VS Code

  5. このコマンドは、VS Code が自動的に見つけることができる利用可能なインタープリターのリストを表示します (あなたのリストは異なります。目的のインタープリターが表示されない場合は、Python 環境の構成を参照してください)。リストから、プロジェクトフォルダー内の ./.venv または .\.venv で始まる仮想環境を選択します。

    Django tutorial: Selecting the virtual environment for Python

  6. コマンド パレットから [ターミナル: 新しいターミナルを作成] (⌃⇧` (Windows, Linux Ctrl+Shift+`)) を実行します。これによりターミナルが作成され、アクティベーション スクリプトが実行されて仮想環境が自動的にアクティブ化されます。

    : Windows で、デフォルトのターミナルタイプが PowerShell の場合、システムでスクリプトの実行が無効になっているため activate.ps1 を実行できないというエラーが表示されることがあります。エラーには、スクリプトを許可する方法に関する情報へのリンクが表示されます。それ以外の場合は、[ターミナル: 既定のプロファイルの選択] を使用して、"コマンド プロンプト" または "Git Bash" をデフォルトに設定してください。

  7. 選択された環境は VS Code のステータスバーの右側に表示され、('.venv': venv) というインジケーターが仮想環境を使用していることを示します。

    Django tutorial: selected environment showing in the VS Code status bar

  8. VS Code ターミナルで次のコマンドを実行して、仮想環境内の pip を更新します。

    python -m pip install --upgrade pip
    
  9. VS Code ターミナルで次のコマンドを実行して、仮想環境に Django をインストールします。

    python -m pip install django
    

これで、Django コードを書くための自己完結型環境ができました。VS Code は [ターミナル: 新しいターミナルを作成] (⌃⇧` (Windows, Linux Ctrl+Shift+`)) を使用すると自動的に環境をアクティブ化します。別のコマンドプロンプトやターミナルを開いた場合は、source .venv/bin/activate (Linux/macOS) または .venv\Scripts\Activate.ps1 (Windows) を実行して環境をアクティブ化します。コマンドプロンプトの先頭に (.venv) が表示されると、環境がアクティブ化されていることがわかります。

最小限の Django アプリを作成して実行する

Django の用語では、「Django プロジェクト」はいくつかのサイトレベルの設定ファイルと、1 つ以上の「アプリ」で構成されます。これらを Web ホストにデプロイして、完全な Web アプリケーションを作成します。1 つの Django プロジェクトには複数のアプリを含めることができ、各アプリは通常、プロジェクト内で独立した機能を持ちます。また、同じアプリを複数の Django プロジェクトで使用することもできます。アプリ自体は、Django が期待する特定の規約に従った Python パッケージにすぎません。

最小限の Django アプリを作成するには、まずアプリのコンテナーとして機能する Django プロジェクトを作成し、次にアプリ自体を作成する必要があります。両方の目的のために、Django パッケージをインストールしたときにインストールされる Django 管理ユーティリティ django-admin を使用します。

Django プロジェクトを作成する

  1. 仮想環境がアクティブになっている VS Code ターミナルで、次のコマンドを実行します。

    django-admin startproject web_project .
    

    この startproject コマンドは、(末尾の . により) 現在のフォルダーがプロジェクトフォルダーであると仮定し、その中に以下のものを作成します。

    • manage.py: プロジェクト用の Django コマンドライン管理ユーティリティ。プロジェクトの管理コマンドは python manage.py <command> [options] を使用して実行します。

    • web_project という名前のサブフォルダー。以下のファイルが含まれています。

      • __init__.py: このフォルダーが Python パッケージであることを Python に伝える空のファイル。
      • asgi.py: プロジェクトを提供するための ASGI互換の Web サーバーのエントリーポイント。本番の Web サーバー用のフックを提供するため、通常はこのファイルをそのままにしておきます。
      • settings.py: Django プロジェクトの設定が含まれており、Web アプリの開発過程で変更します。
      • urls.py: Django プロジェクトの目次が含まれており、これも開発過程で変更します。
      • wsgi.py: プロジェクトを提供するための WSGI 互換の Web サーバーのエントリーポイント。本番の Web サーバー用のフックを提供するため、通常はこのファイルをそのままにしておきます。
  2. 次のコマンドを実行して、空の開発用データベースを作成します。

    python manage.py migrate
    

    初めてサーバーを実行すると、開発目的のデフォルトの SQLite データベースが db.sqlite3 ファイルに作成されますが、これは小規模な Web アプリの本番環境でも使用できます。データベースに関する追加情報については、データベースの種類セクションを参照してください。

  3. Django プロジェクトを検証するには、仮想環境がアクティブになっていることを確認し、コマンド python manage.py runserver を使用して Django の開発サーバーを起動します。サーバーはデフォルトのポート 8000 で実行され、ターミナルウィンドウに次のような出力が表示されます。

    Watching for file changes with StatReloader
    Performing system checks...
    
    System check identified no issues (0 silenced).
    June 13, 2023 - 18:38:07
    Django version 4.2.2, using settings 'web_project.settings'
    Starting development server at http://127.0.0.1:8000/
    Quit the server with CTRL-BREAK.
    

    Django の組み込み Web サーバーは、ローカルでの開発目的*のみ*を意図しています。しかし、Web ホストにデプロイすると、Django は代わりにホストの Web サーバーを使用します。Django プロジェクトの wsgi.pyasgi.py モジュールが、本番サーバーへの接続を処理します。

    デフォルトの 8000 以外のポートを使用したい場合は、コマンドラインでポート番号を指定します。例: python manage.py runserver 5000

  4. ターミナルの出力ウィンドウで http://127.0.0.1:8000/ URL を Ctrl+クリック すると、デフォルトのブラウザーでそのアドレスが開きます。Django が正しくインストールされ、プロジェクトが有効であれば、以下に示すデフォルトページが表示されます。VS Code のターミナル出力ウィンドウには、サーバーのログも表示されます。

    Django tutorial: default view of empty Django project

  5. 完了したら、ブラウザーウィンドウを閉じ、ターミナル出力ウィンドウに示されているように Ctrl+C を使用して VS Code でサーバーを停止します。

Django アプリを作成する

  1. 仮想環境がアクティブになっている VS Code ターミナルで、プロジェクトフォルダー (manage.py がある場所) 内で管理ユーティリティの startapp コマンドを実行します。

    python manage.py startapp hello
    

    このコマンドは hello というフォルダーを作成し、その中には多数のコードファイルと 1 つのサブフォルダーが含まれています。これらのうち、頻繁に扱うのは views.py (Web アプリのページを定義する関数を含む) と models.py (データオブジェクトを定義するクラスを含む) です。migrations フォルダーは、このチュートリアルの後半で説明するように、Django の管理ユーティリティがデータベースのバージョンを管理するために使用します。他にも apps.py (アプリ設定)、admin.py (管理インターフェースを作成するため)、tests.py (テストを作成するため) といったファイルがありますが、ここでは扱いません。

  2. hello/views.py を次のコードに一致するように変更します。これにより、アプリのホームページ用の単一のビューが作成されます。

    from django.http import HttpResponse
    
    def home(request):
        return HttpResponse("Hello, Django!")
    
  3. 以下の内容で hello/urls.py というファイルを作成します。urls.py ファイルは、さまざまな URL を適切なビューにルーティングするためのパターンを指定する場所です。以下のコードには、アプリのルート URL ("") を、先ほど hello/views.py に追加した views.home 関数にマッピングする 1 つのルートが含まれています。

    from django.urls import path
    from hello import views
    
    urlpatterns = [
        path("", views.home, name="home"),
    ]
    
  4. web_project フォルダーにも urls.py ファイルがあり、ここで実際に URL ルーティングが処理されます。web_project/urls.py を開き、次のコードに一致するように変更します (参考になるコメントは残しておいても構いません)。このコードは、アプリの hello/urls.pydjango.urls.include を使って取り込みます。これにより、アプリのルートがアプリ内に収められます。この分離は、プロジェクトに複数のアプリが含まれている場合に役立ちます。

    from django.contrib import admin
    from django.urls import include, path
    
    urlpatterns = [
        path("", include("hello.urls")),
        path('admin/', admin.site.urls)
    ]
    
  5. 変更したすべてのファイルを保存します。

  6. VS Code ターミナルで、仮想環境を再度アクティブ化し、python manage.py runserver で開発サーバーを実行し、ブラウザーで http://127.0.0.1:8000/ を開くと、「Hello, Django」と表示されるページが表示されます。

    Django tutorial: the basic Django app running in a browser

デバッガーの起動プロファイルを作成する

毎回 python manage.py runserver と入力せずにサーバーを実行してアプリをテストする簡単な方法はないか、すでにお考えかもしれません。幸いにも、あります!VS Code でカスタマイズされた起動プロファイルを作成できます。これは、避けられないデバッグの練習にも使用されます。

  1. VS Code で [実行] ビューに切り替えます (左側のアクティビティバーまたは F5 を使用)。「実行とデバッグをカスタマイズするには、launch.json ファイルを作成してください」というメッセージが表示されることがあります。これは、デバッグ構成を含む launch.json ファイルがまだないことを意味します。[launch.json ファイルを作成] リンクをクリックすると、VS Code がファイルを作成してくれます。

    Django tutorial: initial view of the debug panel

  2. リンクを選択すると、VS Code がデバッグ構成を要求します。ドロップダウンから Django を選択すると、VS Code は新しい launch.json ファイルに Django の実行構成を入力します。launch.json ファイルには多数のデバッグ構成が含まれており、それぞれが configuration 配列内の個別の JSON オブジェクトです。

  3. 下にスクロールして、「Python: Django」という名前の構成を確認します。

    {
      // Use IntelliSense to learn about possible attributes.
      // Hover to view descriptions of existing attributes.
      // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
      "version": "0.2.0",
      "configurations": [
        {
          "name": "Python Debugger: Django",
          "type": "debugpy",
          "request": "launch",
          "program": "${workspaceFolder}\\manage.py",
          "args": ["runserver"],
          "django": true,
          "justMyCode": true
        }
      ]
    }
    

    この構成は、選択された Python インタープリターと args リスト内の引数を使用して "${workspaceFolder}/manage.py" を実行するように VS Code に指示します。したがって、この構成で VS Code デバッガーを起動することは、アクティブ化された仮想環境で VS Code ターミナルで python manage.py runserver を実行するのと同じです。(必要であれば、"5000" のようなポート番号を args に追加できます。) "django": true エントリは、このチュートリアルの後半で見る Django ページテンプレートのデバッグを有効にするよう VS Code に指示します。

  4. [実行] > [デバッグの開始] メニューコマンドを選択するか、リストの横にある緑色の [デバッグの開始] 矢印 (F5) を選択して構成をテストします。

    Django tutorial: start debugging/continue arrow on the debug toolbar

  5. ターミナル出力ウィンドウの http://127.0.0.1:8000/ URL を Ctrl+クリック してブラウザーを開き、アプリが正しく実行されていることを確認します。

  6. 終了したらブラウザーを閉じ、デバッガーを停止します。デバッガーを停止するには、停止ツールバーボタン (赤い四角) または [実行] > [デバッグの停止] コマンド (⇧F5 (Windows, Linux Shift+F5)) を使用します。

  7. これで、いつでも [実行] > [デバッグの開始] を使用してアプリをテストできます。これには、変更されたすべてのファイルが自動的に保存されるという利点もあります。

デバッガーを探索する

デバッグは、実行中のプログラムを特定のコード行で一時停止する機会を与えてくれます。プログラムが一時停止している間、変数を調べたり、デバッグ コンソール パネルでコードを実行したり、その他 デバッグで説明されている機能を利用したりできます。デバッガーを実行すると、デバッグ セッションが始まる前に変更されたファイルも自動的に保存されます。

始める前に: 前のセクションの最後で、ターミナルで Ctrl+C を使用して実行中のアプリを停止したことを確認してください。アプリを 1 つのターミナルで実行したままにすると、そのポートを占有し続けます。その結果、同じポートを使用してデバッガーでアプリを実行すると、元の実行中のアプリがすべてのリクエストを処理し、デバッグ中のアプリでは何もアクティビティが見られず、プログラムはブレークポイントで停止しません。つまり、デバッガーが機能していないように思われる場合は、アプリの他のインスタンスがまだ実行されていないことを確認してください。

  1. hello/urls.py で、urlpatterns リストにルートを追加します。

    path("hello/<name>", views.hello_there, name="hello_there"),
    

    path の最初の引数は、*name* という名前の可変文字列を受け入れる "hello/" というルートを定義します。この文字列は、path の 2 番目の引数で指定された views.hello_there 関数に渡されます。

    URL ルートでは大文字と小文字が区別されます。たとえば、ルート /hello/<name>/Hello/<name> とは異なります。同じビュー関数で両方を処理したい場合は、それぞれのバリアントのパスを定義します。

  2. views.py の内容を次のコードに置き換えて、デバッガーでステップ実行できる hello_there 関数を定義します。

    import re
    from django.utils.timezone import datetime
    from django.http import HttpResponse
    
    def home(request):
        return HttpResponse("Hello, Django!")
    
    def hello_there(request, name):
        now = datetime.now()
        formatted_now = now.strftime("%A, %d %B, %Y at %X")
    
        # Filter the name argument to letters only using regular expressions. URL arguments
        # can contain arbitrary text, so we restrict to safe characters only.
        match_object = re.match("[a-zA-Z]+", name)
    
        if match_object:
            clean_name = match_object.group(0)
        else:
            clean_name = "Friend"
    
        content = "Hello there, " + clean_name + "! It's " + formatted_now
        return HttpResponse(content)
    

    URL ルートで定義された name 変数は、hello_there 関数への引数として与えられます。コードのコメントで説明されているように、アプリへのさまざまな攻撃を避けるため、常にユーザーが提供する任意の情報をフィルタリングしてください。この場合、コードは name 引数を文字のみを含むようにフィルタリングし、制御文字や HTML などの注入を防ぎます。(次のセクションでテンプレートを使用する場合、Django は自動フィルタリングを行うため、このコードは不要です。)

  3. hello_there 関数の最初のコード行 (now = datetime.now()) にブレークポイントを設定するには、次のいずれかの操作を行います。

    • カーソルをその行に置き、F9 を押すか、
    • カーソルをその行に置き、[実行] > [ブレークポイントの切り替え] メニューコマンドを選択するか、
    • 行番号の左側の余白を直接クリックします (そこにカーソルを合わせると薄い赤色の点が表示されます)。

    ブレークポイントは左側の余白に赤い点として表示されます。

    Django tutorial: a breakpoint set on the first line of the hello_there function

  4. [実行] > [デバッグの開始] メニューコマンドを選択するか、リストの横にある緑色の [デバッグの開始] 矢印 (F5) を選択してデバッガーを開始します。

    Django tutorial: start debugging/continue arrow on the debug toolbar

    ステータスバーの色が変わり、デバッグ中であることを示していることを確認してください。

    Django tutorial: appearance of the debugging status bar

    デバッグツールバー (下記参照) も VS Code に表示され、次の順序でコマンドが含まれています: 一時停止 (または続行、F5)、ステップオーバー (F10)、ステップイン (F11)、ステップアウト (⇧F11 (Windows, Linux Shift+F11))、再起動 (⇧⌘F5 (Windows, Linux Ctrl+Shift+F5))、停止 (⇧F5 (Windows, Linux Shift+F5))。各コマンドの説明については、VS Code のデバッグを参照してください。

    Django tutorial: the VS Code debug toolbar

  5. 出力は「Python デバッグ コンソール」ターミナルに表示されます。ブラウザーを開き、http://127.0.0.1:8000/hello/VSCode に移動します。ページがレンダリングされる前に、VS Code は設定したブレークポイントでプログラムを一時停止します。ブレークポイント上の小さな黄色い矢印は、それが次に実行されるコード行であることを示します。

    Django tutorial: VS Code paused at a breakpoint

  6. ステップオーバーを使用して now = datetime.now() ステートメントを実行します。

  7. VS Code ウィンドウの左側には、now などのローカル変数や name などの引数を表示する [変数] ペインが表示されます。その下には、[ウォッチ][コール スタック][ブレークポイント] のペインがあります (詳細は VS Code のデバッグ を参照)。[ローカル] セクションで、さまざまな値を展開してみてください。値をダブルクリック (または Enter (Windows, Linux F2)) して変更することもできます。ただし、now などの変数を変更すると、プログラムが壊れる可能性があります。開発者は通常、コードが最初に正しい値を生成しなかった場合に値を修正するためだけに値を変更します。

    Django tutorial: local variables and arguments in VS Code during debugging

  8. プログラムが一時停止している間、デバッグ コンソール パネル (ターミナル パネルの「Python デバッグ コンソール」とは異なります) を使用して、式を試したり、プログラムの現在の状態を使用してコードの一部を試したりできます。たとえば、now = datetime.now() の行をステップオーバーした後、さまざまな日付/時刻形式を試すことができます。エディターで、now.strftime("%A, %d %B, %Y at %X") というコードを選択し、右クリックして [デバッグ: 評価] を選択してそのコードをデバッグ コンソールに送信し、実行します。

    now.strftime("%A, %d %B, %Y at %X")
    'Friday, 07 September, 2018 at 07:46:32'
    

    ヒント: デバッグ コンソールには、ターミナルには表示されないアプリ内の例外も表示されます。たとえば、[実行とデバッグ] ビューの [コールスタック] 領域に「例外で一時停止」というメッセージが表示された場合は、デバッグ コンソールに切り替えて例外メッセージを確認してください。

  9. その行をデバッグ コンソールの下部にある > プロンプトにコピーし、書式設定を変更してみてください。

    now.strftime("%A, %d %B, %Y at %X")
    'Tuesday, 13 June, 2023 at 18:03:19'
    now.strftime("%a, %d %b, %Y at %X")
    'Tue, 13 Jun, 2023 at 18:03:19'
    now.strftime("%a, %d %b, %y at %X")
    'Tue, 13 Jun, 23 at 18:03:19'
    
  10. 必要であれば、さらに数行のコードをステップスルーし、次に [続行] (F5) を選択してプログラムを実行させます。ブラウザー ウィンドウに結果が表示されます。

    Django tutorial: result of the modified program

  11. コードの行を異なる日時形式、例えば now.strftime("%a, %d %b, %y at %X") を使うように変更し、ファイルを保存します。Django サーバーは自動的にリロードします。これは、デバッガーを再起動しなくても変更が適用されることを意味します。ブラウザーでページを更新して、更新を確認してください。

  12. 終了したらブラウザーを閉じ、デバッガーを停止します。デバッガーを停止するには、停止ツールバーボタン (赤い四角) または [実行] > [デバッグの停止] コマンド (⇧F5 (Windows, Linux Shift+F5)) を使用します。

ヒント: http://127.0.0.1:8000/hello/VSCode のような特定の URL に繰り返し移動しやすくするには、views.py のようなファイルのどこかで print ステートメントを使用してその URL を出力します。URL は VS Code ターミナルに表示され、Ctrl+クリック を使用してブラウザーで開くことができます。

[定義へ移動] と [定義をここに表示] コマンド

Django やその他のライブラリでの作業中、それらのライブラリ自体のコードを調べたいことがあるかもしれません。VS Code は、任意のコード内のクラスやその他のオブジェクトの定義に直接移動するための 2 つの便利なコマンドを提供しています。

  • [定義へ移動] は、コードからオブジェクトを定義しているコードへジャンプします。例えば、views.py で、home 関数の HttpResponse を右クリックし、[定義へ移動] を選択 (または F12 を使用) すると、Django ライブラリ内のクラス定義に移動します。

  • [定義をここに表示] (⌥F12 (Windows Alt+F12, Linux Ctrl+Shift+F10)、右クリックのコンテキストメニューにもあります) は似ていますが、クラス定義をエディター内に直接表示します (エディターウィンドウにスペースを作り、コードを隠さないようにします)。Escape を押してピークウィンドウを閉じるか、右上隅の x を使用します。

    Django tutorial: Peek Definition showing the Flask class inline

テンプレートを使用してページをレンダリングする

このチュートリアルでこれまでに作成したアプリは、Python コードからプレーンテキストの Web ページのみを生成します。コード内で直接 HTML を生成することも可能ですが、開発者はそのような方法を避けます。なぜなら、それはアプリをクロスサイト スクリプティング (XSS) 攻撃に対して脆弱にするからです。たとえば、このチュートリアルの hello_there 関数では、content = "<h1>Hello there, " + clean_name + "!</h1>" のようにコードで出力をフォーマットすることを考えるかもしれませんが、content の結果は直接ブラウザーに渡されます。このやり方は、攻撃者が JavaScript コードを含む悪意のある HTML を URL に含めることを可能にし、それが clean_name に入り込み、結果としてブラウザーで実行されてしまいます。

はるかに良い方法は、コードから HTML を完全に分離するためにテンプレートを使用することです。そうすれば、コードはレンダリングではなくデータ値にのみ関心を持つようになります。

Django では、テンプレートは実行時にコードが提供する値のプレースホルダーを含む HTML ファイルです。Django テンプレート エンジンは、ページをレンダリングする際に置換を行い、XSS 攻撃を防ぐための自動エスケープを提供します (つまり、データ値に HTML を使用しようとすると、HTML はプレーンテキストとしてのみレンダリングされます)。したがって、コードはデータ値のみに関心を持ち、テンプレートはマークアップのみに関心を持つことになります。Django テンプレートは、テンプレート継承などの柔軟なオプションを提供しており、これにより共通のマークアップを持つベースページを定義し、そのベースの上にページ固有の追加を行うことができます。

このセクションでは、まずテンプレートを使用して単一のページを作成します。続くセクションでは、静的ファイルを提供し、次に基本テンプレートからナビゲーションバーを含む複数のページをアプリに作成するようにアプリを構成します。Django テンプレートは、このチュートリアルの後半でテンプレートデバッグの文脈で見るように、制御フローや反復もサポートしています。

  1. web_project/settings.py ファイルで、INSTALLED_APPS リストを探し、次のエントリを追加します。これにより、プロジェクトがアプリを認識し、テンプレートを処理できるようになります。

    'hello',
    
  2. hello フォルダ内に templates という名前のフォルダを作成し、次にアプリ名に合わせて hello という名前のサブフォルダをもう 1 つ作成します (この 2 層のフォルダ構造は典型的な Django の慣習です)。

  3. templates/hello フォルダーに、以下の内容で hello_there.html という名前のファイルを作成します。このテンプレートには、"name" と "date" という名前のデータ値用の 2 つのプレースホルダーが含まれており、これらは二重の中括弧 {{}} で区切られています。その他の不変のテキストは、書式設定マークアップ (<strong> など) とともにテンプレートの一部です。ご覧のとおり、テンプレートのプレースホルダーには書式設定も含めることができます。パイプ | 記号の後の式がそれで、この場合は Django の組み込みの date フィルターtime フィルターを使用しています。したがって、コードは事前にフォーマットされた文字列ではなく、datetime の*値*を渡すだけで済みます。

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <title>Hello, Django</title>
        </head>
        <body>
            <strong>Hello there, {{ name }}!</strong> It's {{ date | date:"l, d F, Y" }} at {{ date | time:"H:i:s" }}
        </body>
    </html>
    
  4. views.py の先頭に、次の import 文を追加します。

    from django.shortcuts import render
    
  5. また、views.py で、hello_there 関数を django.shortcuts.render メソッドを使用してテンプレートをロードし、*テンプレートコンテキスト*を提供するように変更します。コンテキストは、テンプレート内で使用するための変数のセットです。render 関数は、リクエストオブジェクト、次に templates フォルダーからのテンプレートへの相対パス、そしてコンテキストオブジェクトを受け取ります。(開発者は通常、テンプレートにそれらを使用する関数と同じ名前を付けますが、コード内で常に正確なファイル名を参照するため、名前の一致は必須ではありません。)

    def hello_there(request, name):
        print(request.build_absolute_uri()) #optional
        return render(
            request,
            'hello/hello_there.html',
            {
                'name': name,
                'date': datetime.now()
            }
        )
    

    マークアップと書式設定はすべてテンプレートに含まれているため、コードはずっとシンプルになり、データ値のみに関心を持つようになったことがわかります。

  6. プログラムを起動し (デバッガーの内外で、⌃F5 (Windows, Linux Ctrl+F5) を使用)、/hello/name URL に移動して結果を確認します。

  7. また、<a%20value%20that%20could%20be%20HTML> のような名前を使用して /hello/name URL に移動し、Django の自動エスケープが機能していることを確認してみてください。「name」の値は、実際の要素をレンダリングするのではなく、ブラウザーにプレーンテキストとして表示されます。

静的ファイルを提供する

静的ファイルとは、CSS ファイルなど、特定のリクエストに対して Web アプリがそのまま返すコンテンツのことです。静的ファイルを提供するには、settings.pyINSTALLED_APPS リストに django.contrib.staticfiles が含まれている必要がありますが、これはデフォルトで含まれています。

Django での静的ファイルの提供は、特に本番環境へのデプロイ時には一種の芸術です。ここで示すのは、Django 開発サーバーと Gunicorn のような本番サーバーの両方で機能する簡単なアプローチです。しかし、静的ファイルの完全な扱いはこのチュートリアルの範囲を超えるため、詳細については Django ドキュメントの 静的ファイルの管理 を参照してください。

本番環境に切り替える際は、settings.py に移動し、DEBUG=False を設定し、ALLOWED_HOSTS = ['*'] を特定のホストを許可するように変更します。これにより、コンテナーを使用する際に追加の作業が発生する場合があります。詳細は、Issue 13 を参照してください。

静的ファイルのためにアプリを準備する

  1. プロジェクトの web_project/urls.py に、次の import 文を追加します。

    from django.contrib.staticfiles.urls import staticfiles_urlpatterns
    
  2. 同じファイルで、末尾に次の行を追加します。これにより、プロジェクトが認識するリストに標準の静的ファイル URL が含まれます。

    urlpatterns += staticfiles_urlpatterns()
    

テンプレートで静的ファイルを参照する

  1. hello フォルダーに、static という名前のフォルダーを作成します。

  2. static フォルダー内に、アプリ名と一致する hello という名前のサブフォルダーを作成します。

    この追加のサブフォルダーを作成する理由は、Django プロジェクトを本番サーバーにデプロイする際に、すべての静的ファイルを 1 つのフォルダーに集め、それを専用の静的ファイルサーバーで提供するためです。static/hello サブフォルダーにより、アプリの静的ファイルが収集されたときに、それらがアプリ固有のサブフォルダーに配置され、同じプロジェクト内の他のアプリのファイルと衝突することがなくなります。

  3. static/hello フォルダーに、以下の内容で site.css という名前のファイルを作成します。このコードを入力した後、VS Code が提供する CSS ファイルの構文ハイライト (カラープレビューを含む) も確認してください。

    .message {
        font-weight: 600;
        color: blue;
    }
    
  4. templates/hello/hello_there.html<title> 要素の後に、次の行を追加します。{% load static %} タグはカスタムの Django テンプレートタグセットで、これにより {% static %} を使用してスタイルシートのようなファイルを参照できます。

    {% load static %}
    <link rel="stylesheet" type="text/css" href="{% static 'hello/site.css' %}" />
    
  5. また、templates/hello/hello_there.html で、<body> 要素の内容を次のマークアップに置き換えます。これは <strong> タグの代わりに message スタイルを使用します。

    <span class="message">Hello, there {{ name }}!</span> It's {{ date | date:'l, d F, Y' }} at {{ date | time:'H:i:s' }}.
    
  6. アプリを実行し、/hello/name URL に移動して、メッセージが青色で表示されることを確認します。完了したらアプリを停止してください。

collectstatic コマンドを使用する

本番環境へのデプロイでは、通常、python manage.py collectstatic コマンドを使用して、アプリのすべての静的ファイルを単一のフォルダーに収集します。その後、専用の静的ファイルサーバーを使用してこれらのファイルを提供でき、これにより通常、全体的なパフォーマンスが向上します。以下の手順は、この収集がどのように行われるかを示していますが、Django 開発サーバーで実行する際にはこの収集を使用しません。

  1. web_project/settings.py に、collectstatic コマンドを使用したときに静的ファイルが収集される場所を定義する次の行を追加します。

    STATIC_ROOT = BASE_DIR / 'static_collected'
    
  2. ターミナルで、python manage.py collectstatic コマンドを実行し、hello/site.cssmanage.py と並んでトップレベルの static_collected フォルダーにコピーされることを確認します。

  3. 実際には、静的ファイルを変更するたびに、また本番環境にデプロイする前に collectstatic を実行します。

基本テンプレートを拡張する複数のテンプレートを作成する

ほとんどのウェブアプリには複数のページがあり、それらのページは通常多くの共通要素を共有しているため、開発者はそれらの共通要素をベースページテンプレートに分離し、他のページテンプレートがそれを拡張します。(これはテンプレート継承とも呼ばれ、拡張されたページはベースページから要素を継承することを意味します。)

また、同じテンプレートを拡張する多くのページを作成することになるため、新しいページテンプレートをすばやく初期化できるコードスニペットを VS Code で作成すると便利です。スニペットは、単一のソースから一貫したコードを提供し、既存のコードからのコピー&ペーストで発生しがちなエラーを回避するのに役立ちます。

以下のセクションでは、このプロセスのさまざまな部分を順を追って説明します。

ベースページテンプレートとスタイルを作成する

Django のベースページテンプレートには、CSS ファイルやスクリプトファイルなどへの参照を含む、一連のページのすべての共有部分が含まれています。ベーステンプレートはまた、拡張テンプレートが上書きすることが期待されるコンテンツを持つ 1 つ以上の block タグも定義します。ブロックタグは、ベーステンプレートと拡張テンプレートの両方で {% block <name> %}{% endblock %} で区切られます。

以下の手順は、基本テンプレートの作成を示しています。

  1. templates/hello フォルダに、layout.html という名前のファイルを以下の内容で作成します。これには "title" と "content" という名前のブロックが含まれています。ご覧のとおり、マークアップは、ホーム、アバウト、コンタクトページへのリンクを持つシンプルなナビゲーションバー構造を定義しており、これらは後のセクションで作成します。Django の {% url %} タグを使用して、相対パスではなく対応する URL パターンの名前で他のページを参照している点に注意してください。

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8"/>
        <title>{% block title %}{% endblock %}</title>
        {% load static %}
        <link rel="stylesheet" type="text/css" href="{% static 'hello/site.css' %}"/>
    </head>
    
    <body>
    <div class="navbar">
        <a href="{% url 'home' %}" class="navbar-brand">Home</a>
        <a href="{% url 'about' %}" class="navbar-item">About</a>
        <a href="{% url 'contact' %}" class="navbar-item">Contact</a>
    </div>
    
    <div class="body-content">
        {% block content %}
        {% endblock %}
        <hr/>
        <footer>
            <p>&copy; 2018</p>
        </footer>
    </div>
    </body>
    </html>
    
  2. 既存の "message" スタイルの下に、static/hello/site.css に次のスタイルを追加し、ファイルを保存します。(このウォークスルーではレスポンシブデザインの実証は試みません。これらのスタイルは単に、そこそこ興味深い結果を生成します。)

    .navbar {
        background-color: lightslategray;
        font-size: 1em;
        font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
        color: white;
        padding: 8px 5px 8px 5px;
    }
    
    .navbar a {
        text-decoration: none;
        color: inherit;
    }
    
    .navbar-brand {
        font-size: 1.2em;
        font-weight: 600;
    }
    
    .navbar-item {
        font-variant: small-caps;
        margin-left: 30px;
    }
    
    .body-content {
        padding: 5px;
        font-family:'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    }
    

この時点でアプリを実行できますが、ベーステンプレートをどこにも使用しておらず、コードファイルも変更していないため、結果は前の手順と同じです。残りのセクションを完了して、最終的な効果を確認してください。

コードスニペットを作成する

次のセクションで作成する 3 つのページは layout.html を拡張するため、新しいテンプレートファイルを基本テンプレートへの適切な参照で初期化するための コードスニペット を作成すると時間を節約できます。コードスニペットは、単一のソースから一貫したコードを提供し、既存のコードからのコピー&ペーストで発生しがちなエラーを回避します。

  1. VS Code で、[ファイル] (Windows/Linux) または [Code] (macOS) メニューを選択し、[基本設定] > [ユーザースニペット] を選択します。

  2. 表示されるリストで html を選択します。(以前にスニペットを作成したことがある場合は、このオプションはリストの [既存のスニペット] セクションに「html.json」として表示されることがあります。)

  3. VS Code が html.json を開いた後、既存の中括弧内に以下のコードを追加します。(ここには示されていませんが、説明的なコメントには、$0 の行がスニペットを挿入した後に VS Code がカーソルを置く場所を示す方法などの詳細が記述されています。)

    "Django Tutorial: template extending layout.html": {
        "prefix": "djextlayout",
        "body": [
            "{% extends \"hello/layout.html\" %}",
            "{% block title %}",
            "$0",
            "{% endblock %}",
            "{% block content %}",
            "{% endblock %}"
        ],
    
        "description": "Boilerplate template that extends layout.html"
    },
    
  4. html.json ファイルを保存します (⌘S (Windows, Linux Ctrl+S))。

  5. これで、スニペットのプレフィックス、例えば djext を入力し始めると、VS Code は次のセクションで示すように、スニペットをオートコンプリートのオプションとして提供します。[スニペットの挿入] コマンドを使用してメニューからスニペットを選択することもできます。

コードスニペット全般に関する詳細については、スニペットの作成を参照してください。

コードスニペットを使ってページを追加する

コード スニペットがあれば、ホーム、アバウト、コンタクトページのテンプレートをすばやく作成できます。

  1. templates/hello フォルダーに、home.html という名前の新しいファイルを作成し、次に djext と入力し始めると、スニペットが補完候補として表示されます。

    Django tutorial: autocompletion for the djextlayout code snippet

    補完を選択すると、スニペットのコードが表示され、カーソルがスニペットの挿入点に置かれます。

    Django tutorial: insertion of the djextlayout code snippet

  2. "title" ブロックの挿入ポイントに Home と書き、"content" ブロックに <p>Home page for the Visual Studio Code Django tutorial.</p> と書き、ファイルを保存します。これらの行は、拡張されたページテンプレートのユニークな部分です。

  3. templates/hello フォルダーに about.html を作成し、スニペットを使用して定型マークアップを挿入し、「title」と「content」ブロックにそれぞれ About us<p>About page for the Visual Studio Code Django tutorial.</p> を挿入して、ファイルを保存します。

  4. 前の手順を繰り返して templates/hello/contact.html を作成し、Contact us<p>Contact page for the Visual Studio Code Django tutorial.</p> を使用します。

  5. アプリの urls.py に、/about と /contact ページのルートを追加します。path 関数の name 引数が、テンプレートの {% url %} タグでページを参照する際に使用する名前を定義することに注意してください。

    path("about/", views.about, name="about"),
    path("contact/", views.contact, name="contact"),
    
  6. views.py で、/about と /contact ルート用の関数を追加し、それぞれのページテンプレートを参照するようにします。また、home 関数を home.html テンプレートを使用するように変更します。

    # Replace the existing home function with the one below
    def home(request):
        return render(request, "hello/home.html")
    
    def about(request):
        return render(request, "hello/about.html")
    
    def contact(request):
        return render(request, "hello/contact.html")
    

アプリを実行する

すべてのページテンプレートが配置されたら、views.py を保存し、アプリを実行してブラウザでホームページを開き、結果を確認します。ページ間を移動して、ページテンプレートが基本テンプレートを正しく拡張していることを確認します。

Django tutorial: app rendering a common nav bar from the base template

データ、データモデル、マイグレーションの操作

多くの Web アプリはデータベースに保存された情報を扱いますが、Django はそのデータベース内のオブジェクトを*モデル*を使って簡単に表現できるようにします。Django では、モデルは django.db.models.Model から派生した Python クラスで、特定のデータベースオブジェクト (通常はテーブル) を表します。これらのクラスはアプリの models.py ファイルに配置します。

Django では、データベースの操作はほぼすべて、コードで定義したモデルを通じて行います。モデルを時間とともに進化させると、Django の「マイグレーション」が基盤となるデータベースの詳細をすべて自動的に処理します。一般的なワークフローは次のとおりです。

  1. models.py ファイルでモデルに変更を加えます。
  2. python manage.py makemigrations を実行して、データベースを現在の状態から新しい状態に移行するためのスクリプトを migrations フォルダーに生成します。
  3. python manage.py migrate を実行して、スクリプトを実際のデータベースに適用します。

マイグレーション スクリプトは、データモデルに加えたすべての増分変更を時間を追って効果的に記録します。マイグレーションを適用することで、Django はデータベースをモデルに合わせて更新します。各増分変更には独自のスクリプトがあるため、Django は*どの*以前のバージョンのデータベース (新しいデータベースを含む) も現在のバージョンに自動的に移行できます。その結果、models.py のモデルだけに集中すればよく、基盤となるデータベーススキーマやマイグレーション スクリプトについて心配する必要はありません。その部分は Django に任せましょう!

コードでも、データの保存と取得にはモデルクラスのみを使用します。Django が基盤となる詳細を処理します。唯一の例外は、Django 管理ユーティリティの loaddata コマンドを使用してデータベースにデータを書き込むことができる点です。このユーティリティは、migrate コマンドがスキーマを初期化した後にデータセットを初期化するためによく使用されます。

db.sqlite3 ファイルを使用する場合、SQLite browser のようなツールを使ってデータベースを直接操作することもできます。このようなツールを使ってテーブルにレコードを追加したり削除したりするのは問題ありませんが、データベースのスキーマに変更を加えるのは避けてください。なぜなら、データベースがアプリのモデルと同期しなくなるからです。代わりに、モデルを変更し、makemigrations を実行し、その後 migrate を実行してください。

データベースの種類

デフォルトでは、Django には開発作業に適したアプリのデータベース用の db.sqlite3 ファイルが含まれています。SQLite をいつ使用するか (sqlite.org) で説明されているように、SQLite は 1 日あたり 10 万ヒット未満の中低トラフィックサイトには問題なく機能しますが、それ以上のボリュームには推奨されません。また、単一のコンピューターに限定されているため、負荷分散や地理的複製などのマルチサーバーシナリオでは使用できません。

これらの理由から、PostgreSQLMySQLSQL Server などの本番レベルのデータストアの使用を検討してください。Django の他のデータベースのサポートに関する情報については、データベース設定を参照してください。Azure SDK for Python を使用して、テーブルや BLOB などの Azure ストレージサービスを操作することもできます。

モデルを定義する

Django モデルは、django.db.model.Models から派生した Python クラスであり、アプリの models.py ファイルに配置します。データベースでは、各モデルに id という名前の一意の ID フィールドが自動的に与えられます。他のすべてのフィールドは、CharField (限定されたテキスト)、TextField (無制限のテキスト)、EmailFieldURLFieldIntegerFieldDecimalFieldBooleanFieldDateTimeFieldForeignKeyManyToMany など、django.db.models の型を使用してクラスのプロパティとして定義されます。(詳細は Django ドキュメントのモデルフィールドリファレンスを参照してください。)

各フィールドは、max_length などの属性を取ります。blank=True 属性はフィールドがオプションであることを意味し、null=true は値がオプションであることを意味します。また、値をデータ値/表示値のタプルの配列の値に制限する choices 属性もあります。

例えば、単純なメッセージログの日付付きエントリを表すデータモデルを定義するために、models.py に次のクラスを追加します。

from django.db import models
from django.utils import timezone

class LogMessage(models.Model):
    message = models.CharField(max_length=300)
    log_date = models.DateTimeField("date logged")

    def __str__(self):
        """Returns a string representation of a message."""
        date = timezone.localtime(self.log_date)
        return f"'{self.message}' logged on {date.strftime('%A, %d %B, %Y at %X')}"

モデルクラスには、他のクラスプロパティから計算された値を返すメソッドを含めることができます。モデルには通常、インスタンスの文字列表現を返す __str__ メソッドが含まれています。

データベースを移行する

models.py を編集してデータモデルを変更したので、データベース自体を更新する必要があります。VS Code で、仮想環境がアクティブになっているターミナルを開き ([ターミナル: 新しいターミナルを作成] コマンド、⌃⇧` (Windows, Linux Ctrl+Shift+`)) を使用)、プロジェクトフォルダーに移動して次のコマンドを実行します。

python manage.py makemigrations
python manage.py migrate

migrations フォルダを見て、makemigrations が生成するスクリプトを確認してください。また、データベース自体を見て、スキーマが更新されていることを確認することもできます。

コマンドの実行中にエラーが表示された場合は、前の手順から残っているデバッグターミナルを使用していないことを確認してください。それらは仮想環境が有効になっていない可能性があります。

モデルを介してデータベースを使用する

モデルを配置し、データベースを移行したので、モデルのみを使用してデータを保存および取得できます。このセクションでは、メッセージをログに記録できるフォームページをアプリに追加します。その後、ホームページを変更してそれらのメッセージを表示します。ここでは多くのコードファイルを変更するため、詳細に注意してください。

  1. hello フォルダ (views.py がある場所) に、forms.py という名前の新しいファイルを次のコードで作成します。これは、データモデル LogMessage から取得したフィールドを含む Django フォームを定義します。

    from django import forms
    from hello.models import LogMessage
    
    class LogMessageForm(forms.ModelForm):
        class Meta:
            model = LogMessage
            fields = ("message",)   # NOTE: the trailing comma is required
    
  2. templates/hello フォルダーに、log_message.html という名前の新しいテンプレートを次の内容で作成します。このテンプレートは、フォームの本体を定義するために form という名前の変数が与えられることを想定しています。その後、「Log」というラベルの付いた送信ボタンを追加します。

    {% extends "hello/layout.html" %}
    {% block title %}
        Log a message
    {% endblock %}
    {% block content %}
        <form method="POST" class="log-form">
            {% csrf_token %}
            {{ form.as_p }}
            <button type="submit" class="save btn btn-default">Log</button>
        </form>
    {% endblock %}
    

    : Django の {% csrf_token %} タグは、クロスサイトリクエストフォージェリからの保護を提供します。詳細は Django ドキュメントのクロスサイトリクエストフォージェリ保護を参照してください。

  3. アプリの static/hello/site.css ファイルに、入力フォームを広くするためのルールを追加します。

    input[name=message] {
        width: 80%;
    }
    
  4. アプリの urls.py ファイルに、新しいページのルートを追加します。

    path("log/", views.log_message, name="log"),
    
  5. views.py で、log_message という名前のビュー (URL ルートで参照される) を定義します。このビューは HTTP GET と POST の両方のケースを処理します。GET の場合 (else: セクション)、前の手順で定義したフォームを表示するだけです。POST の場合、フォームからデータをデータオブジェクト (message) に取得し、タイムスタンプを設定し、そのオブジェクトを保存します。その時点でデータベースに書き込まれます。

    # Add these to existing imports at the top of the file:
    from django.shortcuts import redirect
    from hello.forms import LogMessageForm
    from hello.models import LogMessage
    
    # Add this code elsewhere in the file:
    def log_message(request):
        form = LogMessageForm(request.POST or None)
    
        if request.method == "POST":
            if form.is_valid():
                message = form.save(commit=False)
                message.log_date = datetime.now()
                message.save()
                return redirect("home")
        else:
            return render(request, "hello/log_message.html", {"form": form})
    
  6. すべてを試す準備ができるまであと一歩です!templates/hello/layout.html の "navbar" div に、メッセージログページへのリンクを追加します。

    <!-- Insert below the link to Home -->
    <a href="{% url 'log' %}" class="navbar-item">Log Message</a>
    
  7. アプリを実行し、ブラウザでホームページを開きます。ナビゲーションバーの Log Message リンクを選択すると、メッセージログページが表示されるはずです。

    Django tutorial: the message logging page added to the app

  8. メッセージを入力し、[Log] を選択すると、ホームページに戻るはずです。ホームページにはまだログに記録されたメッセージは表示されません (これはすぐに修正します)。気軽にメッセージをいくつか追加してください。必要であれば、SQLite Browser のようなツールを使ってデータベースを覗き、レコードが作成されたことを確認してください。データベースを読み取り専用で開くか、アプリを使用する前にデータベースを閉じることを忘れないでください。そうしないと、データベースがロックされているためアプリが失敗します。

  9. 完了したらアプリを停止してください。

  10. 次に、ホームページを変更してログに記録されたメッセージを表示します。まず、アプリの templates/hello/home.html ファイルの内容を以下のマークアップに置き換えます。このテンプレートは message_list という名前のコンテキスト変数を期待しています。もしそれを受け取った場合 ({% if message_list %} タグで確認)、そのリストを反復処理し ({% for message in message_list %} タグ)、各メッセージのテーブル行を生成します。それ以外の場合、ページはまだメッセージが記録されていないことを示します。

    {% extends "hello/layout.html" %}
    {% block title %}
        Home
    {% endblock %}
    {% block content %}
        <h2>Logged messages</h2>
    
        {% if message_list %}
            <table class="message_list">
                <thead>
                <tr>
                    <th>Date</th>
                    <th>Time</th>
                    <th>Message</th>
                </tr>
                </thead>
                <tbody>
                {% for message in message_list %}
                    <tr>
                        <td>{{ message.log_date | date:'d M Y' }}</td>
                        <td>{{ message.log_date | time:'H:i:s' }}</td>
                        <td>
                            {{ message.message }}
                        </td>
                    </tr>
                {% endfor %}
                </tbody>
            </table>
        {% else %}
            <p>No messages have been logged. Use the <a href="{% url 'log' %}">Log Message form</a>.</p>
        {% endif %}
    {% endblock %}
    
  11. static/hello/site.css に、テーブルを少しフォーマットするためのルールを追加します。

    .message_list th,td {
        text-align: left;
        padding-right: 15px;
    }
    
  12. views.py で、Django の汎用 ListView クラスをインポートします。これはホームページの実装に使用します。

    from django.views.generic import ListView
    
  13. また、views.py で、home 関数を HomeListView という名前の*クラス*に置き換えます。これは ListView から派生し、LogMessage モデルに自身を関連付け、テンプレートのコンテキストを生成する get_context_data 関数を実装します。

    # Remove the old home function if you want; it's no longer used
    
    class HomeListView(ListView):
        """Renders the home page, with a list of all messages."""
        model = LogMessage
    
        def get_context_data(self, **kwargs):
            context = super(HomeListView, self).get_context_data(**kwargs)
            return context
    
  14. アプリの urls.py で、データモデルをインポートします。

    from hello.models import LogMessage
    
  15. また、urls.py で、新しいビュー用の変数を作成します。これは、最新の 5 つの LogMessage オブジェクトを降順で取得し (つまり、データベースにクエリを発行します)、次にテンプレートコンテキスト内のデータの名前 (message_list) を提供し、使用するテンプレートを特定します。

    home_list_view = views.HomeListView.as_view(
        queryset=LogMessage.objects.order_by("-log_date")[:5],  # :5 limits the results to the five most recent
        context_object_name="message_list",
        template_name="hello/home.html",
    )
    
  16. urls.py で、ホームページへのパスを home_list_view 変数を使用するように変更します。

        # Replace the existing path for ""
        path("", home_list_view, name="home"),
    
  17. アプリを起動し、ブラウザでホームページを開くと、メッセージが表示されるはずです。

    Django tutorial: app home page displaying message from the database

  18. 完了したらアプリを停止してください。

ページテンプレートでデバッガーを使用する

前のセクションで示したように、ページテンプレートには {% for message in message_list %}{% if message_list %} のような手続き的なディレクティブを含めることができます。これらは {% url %}{% block %} のような受動的で宣言的な要素だけではありません。その結果、他の手続き的なコードと同様に、テンプレート内でもプログラミングエラーが発生する可能性があります。

幸いにも、VS Code の Python 拡張機能は、デバッグ構成に "django": true (すでに設定済み) がある場合にテンプレートデバッグを提供します。以下の手順でこの機能を示します。

  1. templates/hello/home.html で、以下の画像の黄色い矢印で示されているように、{% if message_list %}{% for message in message_list %} の両方の行にブレークポイントを設定します。

    Django tutorial: breakpoints set in a Django page template

  2. デバッガーでアプリを実行し、ブラウザでホームページを開きます。(すでにデバッガーを実行している場合は、ブレークポイントを設定した後にアプリを再起動する必要はありません。ページを更新するだけです。) VS Code がテンプレート内の {% if %} ステートメントでデバッガーにブレークし、[変数] ペインにすべてのコンテキスト変数を表示することを確認します。

    Django tutorial: debugger stopped at breakpoints in the page template

  3. ステップオーバー (F10) コマンドを使用して、テンプレートコードをステップスルーします。デバッガーがすべての宣言型ステートメントをステップオーバーし、手続き型コードで一時停止することを確認します。たとえば、{% for message in message_list %} ループをステップスルーすると、message の各値を調べたり、<td>{{ message.log_date | date:'d M Y' }}</td> のような行にステップしたりできます。

  4. デバッグ コンソール パネルで変数を操作することもできます。(ただし、date のような Django フィルターは現在コンソールでは利用できません。)

  5. 準備ができたら、[続行] (F5) を選択してアプリの実行を完了し、レンダリングされたページをブラウザで表示します。終了したらデバッガーを停止します。

オプションのアクティビティ

以下のセクションでは、Python と Visual Studio Code での作業に役立つ可能性のある追加の手順について説明します。

環境用の requirements.txt ファイルを作成する

ソース管理やその他の手段でアプリのコードを共有する場合、仮想環境内のすべてのファイルをコピーするのは意味がありません。なぜなら、受け取った側はいつでもその環境を自分で再作成できるからです。

したがって、開発者は通常、仮想環境フォルダーをソース管理から除外し、代わりに requirements.txt ファイルを使用してアプリの依存関係を記述します。

ファイルは手動で作成することもできますが、pip freeze コマンドを使用して、アクティブ化された環境にインストールされている正確なライブラリに基づいてファイルを生成することもできます。

  1. Python: Select Interpreter コマンドを使用して選択した環境で、[ターミナル: 新しいターミナルを作成] コマンド (⌃⇧` (Windows, Linux Ctrl+Shift+`)) を実行して、その環境がアクティブになったターミナルを開きます。

  2. ターミナルで pip freeze > requirements.txt を実行して、プロジェクトフォルダーに requirements.txt ファイルを作成します。

プロジェクトのコピーを受け取った人 (またはビルドサーバー) は、pip install -r requirements.txt コマンドを実行するだけで、アプリが依存するパッケージをアクティブな環境内に再インストールできます。

: pip freeze は、現在使用していないパッケージを含め、現在の環境にインストールされているすべての Python パッケージをリストします。このコマンドは、正確なバージョン番号を持つパッケージもリストしますが、将来の柔軟性のためにこれを範囲に変換したい場合があるかもしれません。詳細については、pip コマンドのドキュメントの Requirements Files を参照してください。

スーパーユーザーを作成し、管理インターフェースを有効にする

デフォルトでは、Django は認証によって保護された Web アプリ用の管理インターフェイスを提供します。このインターフェイスは、組み込みの django.contrib.admin アプリを通じて実装されており、これはプロジェクトの INSTALLED_APPS リスト (settings.py) にデフォルトで含まれています。認証は、同じく INSTALLED_APPS にデフォルトで含まれている組み込みの django.contrib.auth アプリで処理されます。

管理インターフェースを有効にするには、以下の手順を実行します。

  1. VS Code で仮想環境用のターミナルを開き、python manage.py createsuperuser --username=<username> --email=<email> コマンドを実行して、アプリにスーパーユーザーアカウントを作成します。もちろん、<username><email> はご自身の個人情報に置き換えてください。コマンドを実行すると、Django はパスワードの入力と確認を求めます。

    ユーザー名とパスワードの組み合わせを必ず覚えておいてください。これらはアプリで認証するために使用する資格情報です。

  2. プロジェクトレベルの urls.py (このチュートリアルでは web_project/urls.py) に、組み込みの管理インターフェイスを指す次の URL ルートを追加します。

    # This path is included by default when creating the app
     path("admin/", admin.site.urls),
    
  3. サーバーを実行し、ブラウザでアプリの /admin ページ (開発サーバーを使用している場合は http://127.0.0.1:8000/admin など) を開きます。

  4. django.contrib.auth のおかげで、ログインページが表示されます。スーパーユーザーの資格情報を入力してください。

    Django tutorial: default Django login prompt

  5. 認証が完了すると、デフォルトの管理ページが表示され、ユーザーとグループを管理できます。

    Django tutorial: the default Django administrative interface

管理インターフェイスは好きなだけカスタマイズできます。例えば、データベースのエントリを編集したり削除したりする機能を提供できます。カスタマイズの詳細については、Django admin サイトのドキュメントを参照してください。

Container Tools 拡張機能を使用して Django アプリ用のコンテナーを作成する

Container Tools 拡張機能を使用すると、Visual Studio Code からコンテナー化されたアプリケーションを簡単にビルド、管理、デプロイできます。このチュートリアルで開発した Django アプリ用の Python コンテナーの作成方法に興味がある場合は、コンテナー内の Python チュートリアルをご覧ください。このチュートリアルでは、以下の方法を順を追って説明します。

  • シンプルな Python コンテナーを記述する Dockerfile ファイルを作成する。
  • Django アプリの機能をビルド、実行、検証します。
  • コンテナーで実行されているアプリをデバッグする。

次のステップ

Visual Studio Code で Django を使用するこのウォークスルーを完了したことをお祝いします!

このチュートリアルの完成したコードプロジェクトは GitHub で見つけることができます: python-sample-vscode-django-tutorial

このチュートリアルでは、Django ができることのほんの表面をなぞったにすぎません。ビュー、テンプレート、データモデル、URL ルーティング、管理インターフェイス、他の種類のデータベースの使用、本番環境へのデプロイなど、さらに多くの詳細については、Django ドキュメント公式 Django チュートリアルを必ずご覧ください。

本番のウェブサイトでアプリを試すには、チュートリアル Docker コンテナーを使用して Python アプリを Azure App Service にデプロイするをご覧ください。Azure は、VS Code 内からウェブアプリをデプロイできる標準コンテナーである App Service on Linux も提供しています。

また、Python に関連する VS Code ドキュメントの以下の記事も確認するとよいでしょう。