ご覧いただきありがとうございます!
領護(りょうご)です。
DjangoのListViewでモデルを複数表示する方法を解説します。
GitHubのソースコードリンクも張っておくので、是非試して見てくださいね。
GitHubリポジトリを見る
実行環境
Docker Desktop・・・4.17.1
Python・・・3.10.9
Django・・・4.1.7
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クラスを作成します。
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ファイルを作成します。
<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のProductSuccessPageのcontext_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を設定します。
from django.urls import path
from . import views
urlpatterns = [
# 商品登録一覧ページ
path("product/success/", views.ProductSuccessPage.as_view(), name="success"),
]
「urls.py」ファイル作成してURLを設定
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を設定
動作確認
それでは動作を確認してみます。
http://127.0.0.1:8000/product/sucess/にアクセスすると2つのモデルがListViewで表示できました。
Djangoの1ページ内に複数のモデルフォームを使用して表示・保存
Djangoの1ページ内に複数のモデルフォームを使用して表示・保存する方法も解説しています。
こちらの記事も合わせてご覧ください!
最後に
DjangoのListViewでモデルを複数表示する方法を解説しました。
ListViewでモデルを複数表示する時に是非試してみてくださいね!
ソースコード全体は、下記のGitHubリンクからご覧ください。
GitHubリポジトリを見る