ビュー関数 を作ろう¶
ビュー関数 で必要な機能を整理しよう¶
今回作る ビュー関数 で必要な機能を整理します。
- 過去に投稿されたメッセージを表示する
- 一度に表示する件数を5件にする
- ページ送りボタンが押下された時は、指定されたページが開かれるようにする。
- 投稿ボタンが押下された時に適切に振る舞う
- 投稿内容に誤りがあれば、投稿内容にエラーがあったことをユーザーに通知し、入力フォーム毎にエラーメッセージを表示する
- 投稿内容に誤りがなければ、投稿を受け付けた事をユーザーに通知し、画面を再表示する
これらの機能を実現するために、2つのモジュールを紹介します。
ページネーターとは¶
長い文章や大量のデータを表示するときに複数のページに分割して表示する機能をページネーターと言います。ショッピングサイトなどで馴染みがある機能だと思います。
Django には、これを実現する為の ページネータークラス( django.core.paginator )が予め組み込まれています。
メッセージフレームワークとは¶
投稿ボタンが押下されたとき、正常に登録されたか、投稿内容にエラーがあったかを一度だけメッセージ表示(フラッシュメッセージ)を行いたいことがあります。
Django には、これを実現する為の メッセージフレームワーク( django.contrib.messages ) が予め組み込まれています。
ビュー関数 を作ろう¶
実際に ビュー関数 を作りましょう。 第一章 - Django基礎編 で登場しなかった3つの機能
- ModelForm
- ページネーター
- メッセージフレームワーク
を使いますので、それぞれの機能がどのように使われるか、注意してみてください。
guestboard/views.py
# ページネーター
from django.core.paginator import (
Paginator, # ページネーター本体のクラス
EmptyPage, # ページ番号が範囲外だった場合に発生する例外クラス
PageNotAnInteger # ページ番号が数字でなかった場合に発生する例外クラス
)
from django.shortcuts import (
render,
redirect,
)
from .models import Posting
from .forms import PostingForm
def _get_page(list_, page_no, count=5):
"""ページネーターを使い、表示するページ情報を取得する"""
paginator = Paginator(list_, count)
try:
page = paginator.page(page_no)
except (EmptyPage, PageNotAnInteger):
# page_noが指定されていない場合、数値で無い場合、範囲外の場合は
# 先頭のページを表示する
page = paginator.page(1)
return page
def index(request):
"""表示・投稿を処理する"""
# ModelFormもFormもインスタンスを作るタイミングでの使い方は同じ
form = PostingForm(request.POST or None)
if request.method == 'POST':
if form.is_valid():
# save()メソッドを呼ぶだけでModelを使ってDBに登録される。
form.save()
# メッセージフレームワークを使い、処理が成功したことをユーザーに通知する
messages.success(request, '投稿を受付ました。')
return redirect('guestboard:index')
else:
# メッセージフレームワークを使い、処理が失敗したことをユーザーに通知する
messages.error(request, '入力内容に誤りがあります。')
page = _get_page(
Posting.objects.order_by('-id'), # 投稿を新しい順に並び替えて取得する
request.GET.get('page') # GETクエリからページ番号を取得する
)
contexts = {
'form': form,
'page': page,
}
return render(request, 'guestboard/index.html', contexts)
URLディスパッチャ を書こう¶
ビュー関数とURLConfを書こう を参考に URLディスパッチャ を書きましょう。
guestboard/urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
]
mysite/urls.py
from django.conf.urls import include, url
urlpatterns = [
url(r'^hello/', include('hello.urls', namespace='hello')),
url(r'^crud/', include('crud.urls', namespace='crud')),
url(r'^guestboard/', include('guestboard.urls', namespace='guestboard')), # 追加する
]