登録したサンプルデータをモデルから取り出して表示してみましょう。実際のWebアプリケーションではデータはビューやテンプレートに直接記述するのではなく、このようにモデルやデータベースから取得して表示します。
目次
すべてのデータ(オブジェクト)を取得
まずはArticleクラスの全てのオブジェクトを取得して表示する投稿一覧ページを作ってみましょう。
モデルからデータを取得してビューに渡し、さらにテンプレートに渡して画面に表示します。
bbsアプリケーションの views.py に次のように記述します。
from django.shortcuts import render from django.http import HttpResponse from .models import Article # Articleモデルクラスをインポート def index(request): articles = Article.objects.all() # Articleテーブルのすべてのレコードに対応するオブジェクトを取得 context = { 'articles': articles, # contextに渡す } return render(request, 'bbs/index.html', context) # テンプレートに渡す
モデルからデータを取得するにはモデルクラス(ここではArticle)をインポートし、all()メソッドを使います。
さらにこのデータをテンプレートファイルに渡すために contextに辞書登録し、render関数の引数として渡します。
では、このデータをテンプレート側で取り出して表示しましょう。
index.html に次のように記述します。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>Djangoを使ってみよう!</title> </head> <body> <h1>Djangoで作る1行掲示板</h1> {% for article in articles %} <p>{{ article.content }}</p> {% endfor %} </body> </html>
データは articles という名前で渡してあるので、これをfor文によるループで1つずつ取り出し、contentを表示するよう記述しています。
Djangoコマンドを使ってサーバーを起動し、ブラウザで確認してみましょう。
http://127.0.0.1:8000/bbs/ にアクセスします。
このようにDjangoではモデルとビュー、テンプレートを組み合わせてデータを表示することができます。
個別のデータ(オブジェクト)を取得
サンプルデータを個別に取り出して表示してみましょう。
せっかくなので個別投稿ページとして、別のルート(URL)に作ります。
まずはルートを決めましょう。一覧ページは /bbs/ でした。個別投稿ページは /bbs/各投稿のid/ としてみます。
まずはルーティングを設定します。
/bbs/ 以下のルーティングは /bbs/urls.py ファイルに任せてあるので、/bbs/urls.py に次のように記述します。
from django.urls import path from . import views app_name = 'bbs' # 各ルートがどのアプリケーションのビューなのかを指定 urlpatterns = [ path('', views.index, name='index'), # bbsに続いて整数型のidがあったらviews.pyのdetail関数を呼び出す path('<int:id>', views.detail, name='detail') ]
URLが/bbs/に続いて整数型のidだった場合、views.pyのdetail関数を呼び出すように記述しています。
また、app_nameをbbsとしておくと
bbs:name属性
で各ルートを呼び出すことができるようになります。
次にviews.py で detail関数を定義しましょう。
from django.shortcuts import render,get_object_or_404 from django.http import HttpResponse from .models import Article def index(request): articles = Article.objects.all() context = { 'articles': articles, } return render(request, 'bbs/index.html', context) def detail(request, id): # ルートで指定した値をid変数として取り出す article = get_object_or_404(Article, pk=id) # 指定したidのレコードに対応するオブジェクトを取得 context = { 'article': article, # contextに渡す } return render(request, 'bbs/detail.html', context) # テンプレートに渡す
detail関数ではルートで指定した値をid変数として取り出し、それに対応するオブジェクトを取得しています。(pkはプライマリキーの略です。)
ここで使用しているget_object_or_404関数はその名の通り、指定したidのオブジェクトを取り出すショートカット関数で、指定したidのデータがない場合は404エラー(そのページが存在しない時に出力するエラーメッセージ)を出力してくれます。
続いてテンプレートファイル detail.html を作ります。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>Djangoを使ってみよう!</title> </head> <body> <h1>{{ article.id }}の個別投稿ページ</h1> <p>{{ article.content }}</p> <p><a href='{% url "bbs:index" %}'>一覧ページへ戻る</a></p> </body> </html>
urls.pyで app_name = ‘bbs’ としてあるので 10行目で 一覧ページのURLを呼び出すことができます。
では、Djangoコマンドを使ってサーバーを起動し、ブラウザで確認してみましょう。
http://127.0.0.1:8000/bbs/1/ にアクセスします。
個別のデータを表示することができています。
http://127.0.0.1:8000/bbs/2/ にもアクセスしてみましょう。
idが2のデータを表示できています。
このように動的なWebページでは、ページを1つ1つ個別に作らなくても、似たようなページであれば一定の法則性に基づいてプログラムで自動生成し、ブラウザ側からのリクエストに応じたページを表示することができます。
では次は存在しない、idが4のページ(http://127.0.0.1:8000/bbs/4/)にアクセスしてみましょう。
get_object_or_404関数ではこのように、存在しないページにアクセスがあった場合は404エラーを出力してくれます。
どのページも正常に動作していることが確認できました。
最後に、一覧ページから個別投稿ページにもリンクを貼っておきましょう。
index.html に次のように記述します。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>Djangoを使ってみよう!</title> </head> <body> <h1>Djangoで作る1行掲示板</h1> {% for article in articles %} <p> <a href='{% url "bbs:detail" article.id %}'>{{ article.content }}</a> </p> {% endfor %} </body> </html>
urls.py でapp_nameを指定してあるので、このように個別ページにidを指定してリンクを貼ることができます。
これならidの数だけリンクを直書きする必要がありませんし、新しくidが増えた時も自動的にそのページへのリンクが生成されます。
Djangoコマンドを使ってサーバーを起動し、ブラウザで確認してみましょう。
http://127.0.0.1:8000/bbs/ にアクセスします。
リンクをクリックして個別投稿ページにアクセスできるか確認しましょう。
クリックしたデータの個別投稿ページへアクセスできました。
「一覧ページへ戻る」をクリックすると一覧ページへ戻ってくることができます。