プログラミングを頑張る土木系専攻大学院生のブログ

主にプログラミングについて開発備忘録的な形で投稿しています。

Djangoのテンプレート機能を使ってデータを一覧表示してみた。レシピ提案アプリ⑤

 

siip.hateblo.jp

今回の内容

今回は、以前作成した「レシピ追加機能」で登録したレシピを 一覧表示するページ を作成してみました!

DjangoでWebアプリ開発する際のHTMLの書き方、views.pyでのGETメソッドの実装方法について書いていきます。

Djangoのテンプレート機能を活用することで、データベースの中身を とても簡単にループ処理で表示 できるのが魅力です!


完成イメージ 📷

こんな感じに追加したレシピをカードで一覧表示します

スパニッシュオムレツがめちゃくちゃ好きです(レシピ2つ登録してる)

 




views.py の解説

レシピ一覧ページを表示するために、RecipeListView というクラスを用意しました。

from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
import logging
from .models import Recipe

logger = logging.getLogger(__name__)

class RecipeListView(APIView):
    template_name = 'recipes_list.html'

    def get(self, request, *args, **kwargs):
        try:
            recipes = Recipe.objects.all()
            return render(request, self.template_name, {
                "recipes": recipes,
                "name": "Recipe List"
            })
        except Exception as e:
            logger.error(f"Error while fetching recipes: {str(e)}")
            return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

✅ GET処理の流れ

recipes = Recipe.objects.all()

この一行で、データベースに登録された全レシピが取得されます。

  • recipes という変数に全レシピを格納し、

  • テンプレート(HTML)へ渡して、表示させる仕組みです。


例外処理にも対応

except Exception as e:
    logger.error(f"Error while fetching recipes: {str(e)}")
    return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

万が一、データベースに接続できないなどのエラーが起きた場合も、ユーザーにエラーメッセージを返せるようになっています。ログも出力されるため、開発中のデバッグにも役立ちます。


テンプレート(recipes_list.html)

Djangoテンプレートでは、{% for item in items %} という構文を使って、繰り返し表示が可能です。

今回は、各レシピを カード形式で表示 するようにしました。

{% extends "base.html" %}
{% load static %}
{% block content %}
<body>
  <div class="container mt-5 card-list">
    <h1 class="text-center">レシピ一覧</h1>
    <div class="row row-cols-1 row-cols-md-3 g-4 mt-4">
      {% for recipe in recipes %}
      <div class="col">
        <div class="card h-100">
          <img src="{{ recipe.thumbnail }}"
               class="card-img-top recipe-thumbnail"
               alt="{{ recipe.name }}"
               width="100%"
               height="auto">
          <div class="card-body">
            <h5 class="card-title">{{ recipe.name }}</h5>
            <p class="card-text">
              カテゴリ:
              {% for category in recipe.categories.all %}
                {{ category.name }}{% if not forloop.last %}, {% endif %}
              {% endfor %}
            </p>
            <a href="{% url 'recipe_detail' recipe.id %}" class="btn btn-warning">詳細を見る</a>
          </div>
        </div>
      </div>
      {% endfor %}
    </div>
  </div>
</body>
{% endblock content %}

表示される内容

  • 📷 サムネイル画像(recipe.thumbnail

  • 📝 レシピ名(recipe.name

  • 🗂️ 複数カテゴリ(カンマ区切り)

  • 🔗 詳細ページへのリンク(例:/recipe/3/


Djangoテンプレートの基本構文解説 

Djangoのテンプレートでは、PythonのようなコードをHTMLの中に組み込んで使うことができます。主に使うのは以下の3つの構文です。

① 変数の出力:{{ 変数名 }}

テンプレートに渡されたオブジェクトの値を表示します。

<h1>{{ recipe.name }}</h1>

👉 recipe オブジェクトの name フィールドの値を表示します。


② ループ処理:{% for item in list %} ... {% endfor %}

リストなどの繰り返し処理ができます。

{% for recipe in recipes %}
  <p>{{ recipe.name }}</p>
{% endfor %}

👉 recipes に入っているすべてのレシピの名前を順に表示します。


③ 条件分岐:{% if 条件 %} ... {% endif %}

HTMLの中で if 文も使えます。

{% if recipe.thumbnail %}
  <img src="{{ recipe.thumbnail }}">
{% else %}
  <p>画像がありません</p>
{% endif %}

👉 サムネイルがあるかどうかで表示内容を切り替えています。


④ forloopの活用(ループ中の情報)

Djangoではループの中で使える便利な変数 forloop があります。

{% if not forloop.last %}, {% endif %}

👉 最後の要素以外にはカンマをつける、という処理に使われています。


⑤ テンプレートの継承(extends

共通のレイアウト(ヘッダーやフッターなど)を再利用するために、テンプレートの「継承」が使えます。

{% extends "base.html" %}
{% block content %}
  <!-- ここに個別ページの内容を書く -->
{% endblock content %}

👉 base.html を土台にして、このページの中身だけ差し替える仕組みです。

 


補足:なぜテンプレートが便利なのか?

  • HTMLとPythonロジックを分離できるため、保守性が高い

  • 初心者でも forif を使って直感的にデータを扱える

  • BootstrapなどのCSSフレームワークとも簡単に組み合わせ可能


まとめ ✅

  • RecipeListViewで全レシピを取得しテンプレートに渡す

  • recipes_list.htmlでループ表示し、カードで見やすく整える

  • Djangoテンプレートの力で、一覧ページが簡単に実装できた!