1-4. ビューとテンプレートの基礎

今回のテーマは「ビューとテンプレートの基礎」です。今までは細々と設定作業ばかりでDjangoの面白さを実感出来なかったかも知れません。いよいよ特定のURLに対してHTMLを出力していきますよ。

※本ページはアプリケーションの作成まで読まれた方を対象としています。そのためサンプルソースコードが省略されている場合があります。


Djangoにおけるビューとテンプレート

DjangoはMVT(Model, View, Template)モデルのフレームワークを自称しています。よく知られているMVCモデルとよく似ていますが、MVCモデルにおけるViewが「情報をどのように見せるのか?」という観点で作られるのに対して、DjangoにおけるViewは「表示すべき情報は何か?」を用意しテンプレートに渡す役割を果たしています。「どのように見せるか?」という出力についてはテンプレートが担います。即ちViewはユーザーのアクションに応じてビジネスロジックを担うモデルに通知し、ユーザーに見せる情報を受け取りテンプレートに渡す仕事をします。詳細は公式ドキュメントを参照下さい。

Hello World

とにかく文字を画面に出しましょう。

base/views.py


from django.http import HttpResponse
from django.template import loader

def top(request):
    return HttpResponse('Hello World')
    

このviews.pyに追加したtop関数をURLと結びつけるためbase/urls.pyを修正します。

base/urls.py


from django.urls import path
from . import views
name = 'base'

urlpatterns = [
    path('', views.top, name='top'),
]

ではブラウザで見てみましょう。


(venv)$ ./manage runserver 0.0.0.0:8080

ブラウザでlocalhost:8080にアクセスします。Hello Worldが出ましたね。

templatesディレクトリを設定する

テンプレートを使いたいのですが、まずはテンプレートをどこに配置するか決定しましょう。Djangoのデフォルト設定では各アプリケーション内のtemplatesディレクトリから探す設定となっています。
図にすると


mysite
│└app1
│  └templates
│    └app1
│      └template.html
│
└app2
  └templates
    └app2
      └template.html

というイメージです。一方、テンプレートファイルを1つのtemplatesディレクトリで管理する方法もあります。その場合は


mysites
 └templates
   │└app1
   │ └template.html
   └─app2
      └template.html
  ...

となります。ディレクトリ構成は好みもありますし、プロジェクトの方針にもよりますが、筆者は後者が好みです。前者の構成はアプリケーションがテンプレートを含んだモジュールとして独立することが念頭にあります。今回は後者の設定で進めます。もし前者のスタイルとする場合は以下の設定は不要です。

mysites/settings.pyのTEMPLATES部分の設定を書き換えます。


-        'DIRS': [],
+        'DIRS': [os.path.join(BASE_DIR, 'templates')],

templatesディレクトリをプロジェクト直下に作成し、その中にbaseディレクトリを生成しましょう。


(venv)$ cd mysite #プロジェクト直下にいない場合は移動する
(venv)$ mkdir -p mysite/templates/base

テンプレートを使ってみる

baseアプリケーション用のテンプレートファイルを生成します。
mysite/templates/base/top.html



<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="content-language" content="ja">
    <title>{{title}}</title>
</head>
<body>
<h1>{{title}}</h1>
<p>テンプレートテスト表示</p>
</body>

base/views.py


from django.shortcuts import render
from django.http import HttpResponse
from django.template import loader

def top(request):
    template = loader.get_template('base/top.html')
    ctx = {'title': 'Django学習ちゃんねる(仮)'}
    return HttpResponse(template.render(ctx, request))

base/urls.py


from django.contrib import admin
from django.urls import path, include

app_name = 'base'

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('base.urls')),
]

ではブラウザで確認してみましょう。


(venv)$ ./manage runserver 0.0.0.0:8080

ちなみに毎回runserverを実行することはなく、実行したままソースを書き換えて保存すると自動的に反映されます。(一部settingsに関わるものなどは反映されませんので再起動が必要)

なんとも恥ずかしいタイトルですがスルーしてください。views.pyで渡したtitleパラメータがテンプレートに渡されていることが確認されました。Djangoテンプレートはdict型の変数でパラメータを渡し、テンプレート側では「{{}}」でパラメータ名を囲うことで表示されます。

さて、表示されましたが、テンプレートに表示する度に先程のようにテンプレートを読み込んで表示するのは面倒なのでショートカットが用意されています。先程のviews.pyは以下のように書き換え出来ます。

base/views.py


from django.shortcuts import render
# from django.http import HttpResponse
# from django.template import loader

def top(request):
    # template = loader.get_template('base/top.html')
    ctx = {'title': 'Django学習ちゃんねる(仮)'}
    # return HttpResponse(template.render(ctx, request))
    return render(request, 'base/top.html', ctx)    

loaderもHttpResponseも不要になりスッキリ書けますね。renderを使用すると任意のテンプレートにコンテキスト(テンプレートに変数を渡す入れ物と考えて下さい)を渡して表示することが出来ます。

最後に

現段階ではHTMLを出力するだけでCSSやjavascript等のファイルは読み込んでいません。モダンなWEBアプリにCSS,JSは必須(もはや主役)ですので配置方法を見ていくことにします。

Sponsored Link


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です