LoginSignup
1
2

More than 1 year has passed since last update.

【Django】 TemplateViewを使ってListページを作る

Posted at

Templateviewを使ってListページを作ろうとしたときに
良い感じの記事と巡り会えず、思ったよりハマったのでTemplateviewを使ってListページを作る方法をまとめました

概要

TemplateViewを使ってListページを作成する方法です

この記事で伝えたいこと

  • Templateviewを使ったListページの作り方

  • context_dataにデータを詰めれば上手くいく

結論

[モデル].objects.all()で取得したデータをcontext_dataに代入する

app1_views.py
from django.views.generic import TemplateView

from .models import TestData


class IndexView(TemplateView):
    template_name: str = "app1/index.html"

    def get_context_data(self, **kwargs):
        ctx = super().get_context_data(**kwargs)
        ctx['object_list'] = TestData.objects.all()
        return ctx

ソースコード

ソースコードをGitHubに公開しています
https://github.com/ANKM0/django_sample_make_list_with_templateview.git

環境

  • django4.1.3

フォルダ構成

フォルダ構成はこんな感じになっています
プロジェクト名はconfig,アプリ名はapp1です


DJANGO_SAMPLE(root)
│  db.sqlite3
│  gen_secrets.py
│  manage.py
│  secrets.json
│
├─app1
│  │  admin.py
│  │  apps.py
│  │  forms.py
│  │  models.py
│  │  tests.py
│  │  urls.py
│  │  views.py
│  │  __init__.py
│  │
│  ├─migrations
│  │  │  0001_initial.py
│  │  │  __init__.py
│  │  │
│  │  └─__pycache__
│  │          0001_initial.cpython-310.pyc
│  │          __init__.cpython-310.pyc
│  │
│  └─__pycache__
│          略
│
├─config
│  │  asgi.py
│  │  settings.py
│  │  urls.py
│  │  wsgi.py
│  │  __init__.py
│  │
│  └─__pycache__
│          略
│
└─templates
    └─app1
            base.html
            index.html

下準備

リストで表示するためのデータを登録

Listページの作り方を説明する前にリストで表示するためのデータを登録します

number, name, priceカラムを持つTestDataモデルを作成します

app1_models.py
from django.db import models


class TestData(models.Model):
    number = models.PositiveIntegerField()
    name = models.CharField(max_length=200, blank=False, null=False)
    price = models.PositiveIntegerField()

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = "テストデータ"

3件のデータを登録しました
Alt text

本題

普段,リストを作成する場合はListViewを使っていると思います

app1_views.py
from django.views.generic import ListView
from .models import TestData


class IndexView(ListView):
    template_name: str = "app1/index.html"
    model = TestData


このとき,ListViewは

  1. モデルからデータを取得
  2. templateにデータをobject_listという名前で渡す
    という処理を行っています

これらの処理をTemplateViewに追加していきます


方法その1 get関数を使う

ListViewと同じ処理をする方法その1はget関数をオーバーライドする方法です


コードで書くとこんな感じになります

app1_views.py
from django.views.generic import TemplateView
from django.shortcuts import redirect, render

from .models import TestData


class IndexView(TemplateView):
    template_name: str = "app1/index.html"
    object_list = TestData.objects.all()

    def get(self, request, *args, **kwargs):
        object_list = self.object_list
        context = {
            "object_list": object_list,
        }
        return render(request, self.template_name, context)


object_list = TestData.objects.all() でモデルからデータを取得しています

contextにデータを渡して
return render(request, self.template_name, context) でデータをテンプレートに渡しています


データを渡すテンプレートはこんな感じです

index.html
{% extends "app1/base.html" %}
{% block title %}index{% endblock %}

{% block content %}
<div class="container">
    <h1>index page</h1>

    {{ object_list }}  <!-- querysetになので取り出す必要があります -->

    {% for item in object_list %}
    <li>{{ item.number }}</li>
    <li>{{ item.name }}</li>
    <li>{{ item.price }}</li>
    <br>
    {% endfor %}

</div>
{% endblock %}

サーバーではこのように表示されます

Alt text


方法その2 get_context_dataを使う

get関数をオーバーライドする場合、処理を都度書く必要があるのでコードが汚く(冗長に)なりがちです

app1_views.py
class IndexView(TemplateView):
    template_name: str = "app1/index.html"
    object_list = TestData.objects.all()

    def get(self, request, *args, **kwargs):
        object_list = self.object_list
        context = {
            "object_list": object_list,
            # たくさんの処理
            # ︙
        }
        return render(request, self.template_name, context)

    def post(self, request, *args, **kwargs):
        object_list = self.object_list
        context = {
            "object_list": object_list,
            # たくさんの処理
            # ︙
        }
        return render(request, self.template_name, context)


そこで簡潔に書くことのできる
get_context_data をオーバーライドする方法を使うことでコードが汚くなるのを防ぐことができます

app1_views.py
from django.views.generic import TemplateView

from .models import TestData


class IndexView(TemplateView):
    template_name: str = "app1/index.html"

    def get_context_data(self, **kwargs):
        ctx = super().get_context_data(**kwargs) # ctxにget_context_dataの中身(**kwargs)を代入
        ctx['object_list'] = TestData.objects.all() # ctxにデータを追加
        return ctx

ctx = super().get_context_data(**kwargs) でget_context_dataを継承してget_context_dataの中身をctxに代入しています

get_context_dataの中身は辞書形式なので ctx['object_list'] = TestData.objects.all() でデータを渡しています



サーバーではこのように表示されます
Alt text

まとめ

TemplateViewでリストを作成するにはcontext_dataにデータを代入する

参考文献

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2