導入
ブログのトップに、記事の一覧を出しましょう。「モデルからデータを取り、テンプレートに流し込んでレスポンスにする」という、Django の王道の流れを1つにまとめます。
説明
第1章で見た MTV の流れが、そのままコードになります。
flowchart LR
R["GET /"] --> V["ビュー post_list<br/>Post.objects.all()"]
V --> M[("モデル Post")]
V --> T["テンプレート<br/>{% for post in posts %}"]
T --> RES["HTML レスポンス"]
import django
from django.conf import settings
if not settings.configured:
settings.configure(DEBUG=True, SECRET_KEY="dev",
ROOT_URLCONF=__name__, ALLOWED_HOSTS=["testserver"],
INSTALLED_APPS=[],
DATABASES={"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"}},
TEMPLATES=[{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"OPTIONS": {"loaders": [("django.template.loaders.locmem.Loader", {
"list.html": (
"<h1>ブログ記事一覧</h1><ul>"
"{% for post in posts %}<li>{{ post.title }}({{ post.views }}回)</li>{% endfor %}"
"</ul><p>全{{ posts.count }}件</p>"
),
})]},
}])
django.setup()
from django.db import models, connection
from django.shortcuts import render
from django.urls import path
from django.test import Client
class Post(models.Model):
title = models.CharField(max_length=100)
views = models.IntegerField(default=0)
class Meta:
app_label = "blog"
with connection.schema_editor() as schema:
schema.create_model(Post)
Post.objects.create(title="Djangoを始めよう", views=120)
Post.objects.create(title="テンプレート入門", views=80)
Post.objects.create(title="モデルの基礎", views=200)
# ビュー:モデルから取り出し、テンプレートに渡す
def post_list(request):
posts = Post.objects.order_by("-views") # 人気順
return render(request, "list.html", {"posts": posts})
urlpatterns = [path("", post_list)]
client = Client()
print(client.get("/").content.decode())
- ビューは
Post.objects.order_by("-views")で記事を取り、render(request, "list.html", {"posts": posts})でテンプレートに渡します。 - テンプレートは
{% for post in posts %}で1件ずつ回し、{{ post.title }}のようにモデルのフィールドにそのままアクセスできます。 {{ posts.count }}のように、テンプレート内から QuerySet のメソッドも呼べます。
これが Django の一番よく書く形です。あとは URL とテンプレートを増やしていけば、ページが増えていきます。
やってみよう
order_by("-views") を order_by("title") に変えて並び順を変えたり、Post.objects.create(...) で記事を足したりして、一覧の表示が変わることを確かめましょう。
演習
post_list を改造して、views が 100 以上の記事だけを一覧に出してください(人気記事一覧)。filter を使います。出力に テンプレート入門(80回)が含まれないようにできれば成功です。
ヒント1を見る
posts = Post.objects.filter(views__gte=100).order_by("-views")。
ヒント2を見る
テンプレートは変更不要です。ビューの取得条件だけを変えます。