登録したサンプルデータをモデルから取り出して表示してみましょう。実際の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/ にアクセスします。

リンクをクリックして個別投稿ページにアクセスできるか確認しましょう。

クリックしたデータの個別投稿ページへアクセスできました。
「一覧ページへ戻る」をクリックすると一覧ページへ戻ってくることができます。







