8.Djangoでモデルからデータを取り出して表示

登録したサンプルデータをモデルから取り出して表示してみましょう。実際の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変数として取り出し、それに対応するオブジェクトを取得しています。

ここで使用している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/ にアクセスします。

個別投稿ページ1

個別のデータを表示することができています。

http://127.0.0.1:8000/bbs/2/ にもアクセスしてみましょう。

個別投稿ページ2

idが2のデータを表示できています。

このように動的なWebページでは、ページを1つ1つ個別に作らなくても、似たようなページであれば一定の法則性に基づいてプログラムで自動生成し、ブラウザ側からのリクエストに応じたページを表示することができます。

では次は存在しない、idが4のページ(http://127.0.0.1:8000/bbs/4/)にアクセスしてみましょう。

404エラーページ

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/ にアクセスします。

リンク付きの一覧ページ

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

リンク先の個別ページ

クリックしたデータの個別投稿ページへアクセスできました。

「一覧ページへ戻る」をクリックすると一覧ページへ戻ってくることができます。

このエントリーをはてなブックマークに追加

コメントを残す

頂いたコメントは一読した後表示させて頂いております。
反映まで数日かかる場合もございますがご了承下さい。