ブログBLOG

\ Web・ゲーム開発に関する情報を発信中 /

【簡単】DjangoのListViewでモデルを複数表示する方法

Django
django , python
20230415_django-listview-display-multiple-model-tmb

ご覧いただきありがとうございます!
領護(りょうご)です。

DjangoのListViewでモデルを複数表示する方法を解説します。
GitHubのソースコードリンクも張っておくので、是非試して見てくださいね。
GitHubリポジトリを見る

目次

実行環境

Docker Desktop・・・4.17.1
Python・・・3.10.9
Django・・・4.1.7

models.pyの作成

product/models.py
from django.db import models
from django.utils.translation import gettext_lazy as _

# 商品情報登録モデル
class Product(models.Model):

    # 商品名
    name = models.CharField(verbose_name=_("商品名"), max_length=64)

    # 商品詳細
    detail = models.TextField(verbose_name=_("商品詳細"), max_length=1000)

    # 商品金額
    price = models.PositiveIntegerField(verbose_name=_("商品金額"))

    # 登録日時
    created_at = models.DateTimeField(verbose_name=_("登録日時"), auto_now_add=True)


# 商品管理者登録モデル
class ProductManager(models.Model):

    # 担当者名
    name = models.CharField(verbose_name=_("担当者名"), max_length=32)

    # メールアドレス
    email = models.EmailField(verbose_name=_("email address"), max_length=256)

    # 電話番号
    phone_number = models.CharField(verbose_name=_("電話番号"), max_length=32)

商品情報登録と商品管理者登録の2つのモデルを使用します。
この2つのモデルを使って、ListViewに表示します。

views.pyの作成

2つのモデルを表示するListViewクラスを作成します。

product/views.py
from django.views.generic import ListView # ListViewをインポート
from .models import Product, ProductManager

# 商品登録一覧ページ
class ProductSuccessPage(ListView):
    template_name = "product/success.html"

    # 1つ目のモデルを指定
    model = Product

    # テンプレートで使用するモデルの参照名(なくてもOK)
    context_object_name = "list_objects"

    # ページの切り替え設定(10個区切りでページを切り替える)
    paginate_by = 10

    # get_context_data関数をオーバーラード
    def get_context_data(self, **kwargs):
        ctx = super().get_context_data(**kwargs)

        # 2つ目のモデルを指定
        ctx["product_managers"] = ProductManager.objects.all()
        return ctx

ListViewクラスを継承して、商品登録一覧ページで使用する「ProductSuccessPage」を作成しました。
詳しく解説しますね。

from django.views.generic import ListView

ListViewをインポートします。

# 1つ目のモデルを指定
model = Product

1つ目のProductモデルは、「model = Product」で指定します。
普通のListViewクラスと同じですね。

def get_context_data(self, **kwargs):
    ctx = super().get_context_data(**kwargs)

    # 2つ目のモデルを指定
    ctx["product_managers"] = ProductManager.objects.all()
    return ctx

2つ目のProductManagerモデルは、get_context_data関数をオーバーライドしてcontextで指定します。
今回は「product_managers」という名前でcontextに保存していますが、ご自身のお好きな名前で大丈夫です。

これで複数のモデルをListViewで表示する準備ができました。
次は、htmlを作成します。

htmlの作成

商品登録一覧ページに使用するhtmlファイルを作成します。

success.html
<h1>商品登録完了</h1>
<p>商品の登録が完了しました!</p>

<!-- 1つ目のモデルを表示 -->
<section>
  <h2>商品情報登録一覧</h2>
  <table class="table">
    <thead>
      <tr>
        <th>商品名</th>
        <th>商品詳細</th>
        <th>商品金額</th>
        <th>登録日時</th>
      </tr>
    </thead>
    <tbody>
      <!-- 1つ目のモデルの表示処理 -->
      {% for lo in list_objects %}
      <tr>
        <td>{{ lo.name }}</td>
        <td>{{ lo.detail }}</td>
        <td>{{ lo.price }}</td>
        <td>{{ lo.created_at }}</td>
      </tr>
      {% endfor %}
    </tbody>
  </table>
  <!-- ページネーションを表示 -->
  {% include "include/list/pagination.html" with page_obj=page_obj search_word=search_word %}
</section>

<!-- 2つ目のモデルを表示 -->
<section>
  <h2>商品管理者登録一覧</h2>
  <table class="table">
    <thead>
      <tr>
        <th>担当者名</th>
        <th>メールアドレス</th>
        <th>電話番号</th>
      </tr>
    </thead>
    <tbody>
      <!-- 2つ目のモデルの表示処理 -->
      {% for product_manager in product_managers %}
      <tr>
        <td>{{ product_manager.name }}</td>
        <td>{{ product_manager.email }}</td>
        <td>{{ product_manager.phone_number }}</td>
      </tr>
      {% endfor %}
    </tbody>
  </table>
</section>

商品登録一覧ページに使用するhtmlファイル「success.html」を作成しました。
詳しく解説しますね。

<!-- 1つ目のモデルの表示処理 -->
{% for lo in list_objects %}
<tr>
  <td>{{ lo.name }}</td>
  <td>{{ lo.detail }}</td>
  <td>{{ lo.price }}</td>
  <td>{{ lo.created_at }}</td>
</tr>
{% endfor %}

1つ目のモデルは、views.pyのProductSuccessPagecontext_object_nameで指定したlist_objectsをループして表示します。

<!-- 2つ目のモデルの表示処理 -->
{% for product_manager in product_managers %}
<tr>
  <td>{{ product_manager.name }}</td>
  <td>{{ product_manager.email }}</td>
  <td>{{ product_manager.phone_number }}</td>
</tr>
{% endfor %}

2つ目のモデルは、get_context_dataで指定したproduct_managersをループして表示します。

urls.pyの作成

商品登録一覧ページのURLを設定します。

product/urls.py
from django.urls import path

from . import views

urlpatterns = [
    # 商品登録一覧ページ
    path("product/success/", views.ProductSuccessPage.as_view(), name="success"),
]

「urls.py」ファイル作成してURLを設定

app_project/urls.py
from django.contrib import admin
from django.urls import include, path
from product import urls as product_urls

urlpatterns = [
    # Django管理画面ログイン
    path("admin/", admin.site.urls),
    # 商品ページ
    path("", include(product_urls)), # 追加
]

Djangoプロジェクトの「urls.py」にもURLを設定

動作確認

それでは動作を確認してみます。

20230415_django-listview-display-multiple-model-01
20230415_django-listview-display-multiple-model-02

http://127.0.0.1:8000/product/sucess/にアクセスすると2つのモデルがListViewで表示できました。

Djangoの1ページ内に複数のモデルフォームを使用して表示・保存

Djangoの1ページ内に複数のモデルフォームを使用して表示・保存する方法も解説しています。
こちらの記事も合わせてご覧ください!

最後に

DjangoのListViewでモデルを複数表示する方法を解説しました。
ListViewでモデルを複数表示する時に是非試してみてくださいね!
ソースコード全体は、下記のGitHubリンクからご覧ください。
GitHubリポジトリを見る

参考にさせて頂いたサイト様

https://qiita.com/yongjugithub/items/edd69e1ac6d4507f9ad1


\ よかったらシェアしてね /

関連記事