本稿ではViewの役割とその記述の仕方について解説します。
Viewの役割
Viewとは、一般的には「コントローラー」にあたります。
つまり、モデルやテンプレートを繋ぐハブのようなものです。
一般に、Djangoの動作は以下のようになります。
- Djangoサイトへアクセスがある(リクエストといいます)とURLが解析され、それからViewが呼び出されます。
- 呼び出されたViewは必要があればモデルと連携し、データベースからデータを取得します。
- テンプレートを呼び出します。取得したデータはテンプレートに渡され、テンプレートからウェブページを作成します。
- 完成したウェブページをアクセスしてきたユーザーに送付します(レスポンスといいます)。
この手順に沿ってDjangoは動作していますが、Viewが中心となってデータのやりとりが行われていることが分かります。
ですので「ハブ」というわけです。
Viewの作成の仕方
Viewの作成の仕方は2つあります。
- 関数を定義して作成
- クラスを継承して作成
どちらで作成してもいいのですが、Viewの作成には約束というか必須条件があります。
それは、レスポンスを返すことです。
意外に思うかもしれませんが、これだけです。
クラスを継承して作成する場合は、継承するクラスがすべてやってくれます。
関数を定義して作成する場合は自分でレスポンスを返さなくてはなりません。
私はクラスを継承してViewを作成していますが、関数で作成する場合も知っておいた方が良いですのでどちらも解説したいと思います。
説明に使用するモデル
Viewの説明をするために、以下のようなモデルクラスを定義している事とします。
モデルはこんな感じだと思ってください。
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
Viewの目的
この記事でのViewの目的を明確にしておきます。
- Articleモデルのデータをテンプレートに渡す
- テンプレートを指定してレスポンスを返す
関数のView
関数でViewを作成する方法について解説します。
ここでは、実際にコードを書きながら、そこに追加しながら説明をしていきます。
では、その名の通り関数を定義するところから始めましょう。
ここでのViewの名前は仮にarticle_list_view
としましょう。
もちろん、関数の名前は自由につけてOKです。
# 動作しません
def article_list_view():
return None
関数を定義します。もちろんまだ動作しません。
まずは引数を受け取るようにしましょう。
def article_list_view(request): # request を受け取る
return None
Viewの第一引数にはリクエストオブジェクトが渡されます。
これを必ず使う必要はありませんが、渡されてくることは覚えておいてください。
また、仮引数の名称はrequest
にすることが多いようです。
次に、レスポンスを返すようにしましょう。
from django.http import HttpResponse
def article_list_view(request):
return HttpResponse('<h1>article list view</h1>')
これで動作するViewとなります。
HttpResponse
は文字通りレスポンスを返します。
また、引数に文字列を渡すことにより表示されるページに文字列を表示することができます。
ちなみにこの段階でurls.py
を設定してページを確認すると引数に渡した文字列がそのまま表示されます。
ここはあとでテンプレートを使用することにしますので、今は仮にこのようにしておきます。
次に、関数の内部を記述していきます。
from .models import Article
def article_list_view(request):
return HttpResponse('<h1>article list view</h1>')
まず、モデルをインポートします。
モデルはView内でモデルのデータを取得するために使用されます。
from .models import Article
def article_list_view(request):
articles = Article.objects.all()
return HttpResponse('<h1>article list view</h1>')
最後に、テンプレートを使用します。
テンプレートを指定して変数articles
を渡し、レスポンスを返します。
このような複雑なタスクをこなすために便利な関数がDjangoによって用意されています。
それが、render
関数です。
通常views.py
に最初からインポートされているはずです。
テンプレート名は仮にarticle_list.html
としたいと思います。
from django.shortcuts import render
from .models import Articles
def article_list_view(request):
articles = Article.objects.all()
context = {
'articles': articles,
}
return render(request, 'article_list.html', context)
render
関数は必須の引数が2つあります。
- View関数に渡された
requets
- テンプレート名
それぞれ第一引数と第二引数、もしくは名前付き引数で設定します。
3つ目はオプションですが、今回使用しています。
3つ目はコンテキストです。誤解を恐れずにいえばテンプレートに渡す変数のことです。
今は、Article
モデルからデータを取得していますので、それをテンプレートに渡すために使用しています。
コンテキストは辞書で渡せばOKです。
また、render
関数は内部でレスポンスを返すので、関数の処理としてHttpResponse
を返す必要はありません。
以上、ざっくりとしていますが、関数でのViewの作成方法です。
まとめ
ご覧のように関数のViewは関数の内部でモデルからデータを取得し、テンプレートに渡します。
その中でハブとして動作しています。
クラスベースビュー
クラスを継承して作成する場合の説明をします。
Djangoが提供しているクラス(Mixin)を継承して、自分のViewクラスを作成するやり方です。
Djangoにはクラスベースビューというあらかじめ動作を定義しているViewがあります。
このViewはクラスで提供されていますので、これを継承して自身のアプリケーションに合うように必要な部分を設定します。
あとは、クラスベースビューがよしなに処理してくれますので、何もする必要はありません。
よく使われるクラスベースビューで例を示してみます。
from django.views.generic improt ListView
from .models import Article
class ArticleListView(ListView):
model = Article
ここでは、ListView
がクラスベースビューです。
ListView
はモデルからデータをすべて取得して、テンプレートにリストとして提供します。
また、レスポンスも自動で返します。
繰り返しになりますが、レスポンスを自動で返すのはクラスベースビューの基本的な機能です。
テンプレートはクラスベースビューが標準で読み込みますので、設定の必要はありません。
上記関数のViewと同様の動作をしますがコード量がとても少ないことにお気づきと思います。
クラスベースビューは記述する量がとても少なくて済むことがメリットの一つです。
まとめ
クラスベースビューはモデルを指定することで自動的にデータを取得します。
また、テンプレートも所定の場所に作成すれば自動的に使用します。
このような動作でモデルとテンプレートのハブになっています。
urls.pyへの登録
本稿の最後に、urls.py
に登録しましょう。
urls.py
に登録することでブラウザにアクセスして内容を確認できるようになります。
本稿はViewの解説ですので、urls.py
は設定するところだけ記載します。
まずは関数のViewです。
from .views import article_list_view
path('', article_list_view)
関数のViewの場合、関数名のみ設定します。
次に、クラスベースビューでの設定です。
from .views import ArticleListView
path('', ArticleListView.as_view())
クラスベースビューの場合、Viewがクラスですので、スタティックメソッドであるas_view
を呼びます。
そうすればあとはよしなに処理してくれます。
テンプレートについて
本稿はViewの記事ですのでテンプレートについては割愛します。
別途記事にする予定です。