Help us understand the problem. What is going on with this article?

Django Webアプリ作成(7) テンプレートの拡張

More than 1 year has passed since last update.

環境
OS : macOS Mojave
Anaconda : python3.6.7
Django==2.1.5

ここまで

前回までで一通りの流れをやりました。
今回は、Djangoのテンプレート拡張機能を用いて新たなページを作成していきたいと思います。

テンプレートの拡張

はじめにサイトの大枠であるbase.htmlを作成します。
templatesディレクトリにbase.htmlを作成

Terminal
touch templates/base.html

base.htmlを作成したら、post_list.htmlの中身をコピーして貼る。
その後、

base.html
{% for post in posts %}
.
.
.
{% endfor %}

部分を

base.html
{% block content %}
{% endblock %}

に書き換える。

これで拡張元のhtmlファイルが完成
次に、post_list.htmlを以下のように書き換える。

post_list.html
{% extends 'base.html' %}

{% block content %}
    {% for post in posts %}
        <div class="post">
            <div class="date">
                {{ post.published_date }}
            </div>
            <h1><a href="">{{ post.title }}</a></h1>
            <p>{{ post.text|linebreaks }}</p>
        </div>
    {% endfor %}
{% endblock %}

今回は、post_list.htmlを作ってからbase.htmlを作ったが
実際、作る際は先に大枠となるbase.htmlを作成してからそれぞれのページ(htmlファイル)を作成していくと良い。

新ページ(post_detail.html)の作成

これまでブログの一覧ページ(post_list.html)を作成したので、次にブログの詳細表示ページ(post_detail.html)を作成していく。

Terminal
touch templates/post_detail.html

post_detai.htmlの中身は以下のように

post_detail.html
{% extends 'base.html' %}

{% block content %}
    <div class="post">
        {% if post.published_date %}
            <div class="date">
                {{ post.published_date }}
            </div>
        {% endif %}
        <h1>{{ post.title }}</h1>
        <p>{{ post.text|linebreaksbr }}</p>
    </div>
{% endblock %}

{% if ... %} ... {% endif %}はpythonの基本構文でいうとif...elif...に相当し今回の場合はpublished_dataが存在するかをチェックしている。

ページ(.html)を作成したら次はビューを追加します。

blog/views.py
from django.shortcuts import render, get_object_or_404, redirect
from django.utils import timezone
from .models import Post


def post_list(request):
    posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
    return render(request, 'post_list.html', {'posts': posts})


def post_detail(request, pk):
    post = get_object_or_404(Post, pk=pk)
    return render(request, 'post_detail.html', {'post': post})

上の1行目のfrom文とdef post_detail部分が新たに追加したものです。
ビューが完成したらurls.pyのurlパターンを追加します。

blog/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.post_list, name='post_list'),
    path('post/<int:pk>/', views.post_detail, name='post_detail'),
]

最後にpost_list.html内にpost_detail.htmlに飛ぶようにリンクを追加します。

post_list.html
<h1><a href="">{{ post.title }}</a></h1>

部分を以下のように編集

post_list.html
<h1><a href="{% url 'post_detail' pk=post.pk %}">{{ post.title }}</a></h1>

これは、クリックするとurls.py内のname='post_detail'が呼び出されるという意味です。

復習

ページ作成の手順としては
htmlファイルの作成 → ビュー関数の作成 
→ urls.pyへの追加 → リンクの埋め込み 
といった感じです。

次回はページの表部分からブログ記事を投稿できるようにしたいと思います。

yuta_rug
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away