Progateで作ったWebアプリをDjangoで作ってみる2！ Part6 -base.html編-

# 目標物の確認

ProgateのNode.jsコースで作ったブログアプリと同じものをDjangoで作ってみます。

Djangoでのアプリ開発の一連の流れを整理するために記していきます。

**完成イメージ**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471633/147877a6-1b3a-25e2-7956-720596125802.png)

# レイアウトの使いまわし

どのHTMLファイルにも同じレイアウト部分がある場合、その部分だけ使い回すことができます。

そうすることで、共通部分のレイアウトに変更が生じた場合、大元のHTMLファイルだけ変更することで、個々のページを変更する必要がなくなります。そっちのほうが効率的です。

今回は下の赤枠部分がいくつかのページで使い回されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471633/1fb14fc8-5990-98d9-d2b2-6f9eb281efec.png)

Djangoでは**テンプレートの継承（Template inheritance）**と呼ばれています。

[Template inheritance](https://docs.djangoproject.com/es/3.2/ref/templates/language/#template-inheritance)

定形のhtmlファイルを作成して、それを個々のHTMLファイルで読み込みます。

ベースとなるHTMLファイル、今回は<font color="Red">**赤枠**</font>の部分を**base.html**として作ります。

**base.html**ファイルが全体のフレームワークとなり、個々のページの中（このあと作っていく**list.html**、**article.html**）で``{% block content %}``の情報を入れていきます（☆1）。

**base.html**の中を見てみます。ログインしているときは、「ようこそ、ユーザー名さん」が表示されるようになり、ログインしていないときは「ようこそ、ゲストさん」と表示されるようにしました（☆2）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471633/be66b628-66b4-dfa9-a526-2a1df237f069.png)


さらに、ログインしているときは、「ログアウト」が、ログインしていないときは「新規登録」と「ログイン」が表示されるようにしました（☆3）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471633/21f3ebb7-f047-1b6b-235c-c0c3ee781c6a.png)


```HTML:base.html
{% load static %}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>BLOG</title>
    <link rel="stylesheet" href="{% static 'blog/style.css' %}">
  </head>
  <body>
    <header>
        <div class="header-nav">
          <a href="/">BLOG</a>
          {% if user.is_authenticated %} # ☆2
          <p>ようこそ、{{ user.username }}さん</p> # ☆2
          {% else %} # ☆2
          <p>ようこそ、ゲストさん</p>
          {% endif %} # ☆2
          <ul>
            <li><a href="{% url 'blog:list' %}">記事一覧</a></li>
            {% if user.is_authenticated %} # ☆3
              <li><a href="{% url 'blog:logout' %}">ログアウト</a></li>
            {% else %} # ☆3
              <li><a href="{% url 'blog:signup' %}">新規登録</a></li>
              <li><a href="{% url 'blog:login' %}">ログイン</a></li>
            {% endif %} # ☆3
          </ul>
        </div>
        <p>わんこの学びブログ</p>
      </header>
    
  </body>
{% block content %} <!--☆1-->
{% endblock content %} <!--☆1-->
```

個別の**list.html**ファイルを見てみます。

``{% extends 'blog/base.html' %}``の部分がポイントです。このコードは**base.html**に記載されている内容をベースとして広げて使っていくイメージです（☆4）。**base.html**の中で定義した``{% block content %}`` ``{% endblock content %}``の中に個々のページのコードを書いていく感じです（☆5）。

ブログ記事のカテゴリーが全員か会員限定かで表示が変わるようにします（☆6）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471633/37cc94c0-76a4-d07f-5532-45427034f409.png)



```HTML:list.html
{% extends 'blog/base.html' %} <!--☆4-->

{% block content %} <!--☆5-->
  <main>
    <ul class="list">
      {% for object in object_list %}
      <li>
        {% if object.category == 'limited' %} <!--☆6-->
          <i>会員限定</i>
        {% endif %} <!--☆6-->
        <h2>{{ object.title }}</h2>
        <p>{{ object.summary }}</p>
        <a href="{% url 'blog:article' object.pk %}">続きを読む</a>
      </li>
      {% endfor %} <!--☆6-->
    </ul>
  </main>
{% endblock content %} <!--☆5-->
```

ブログ記事一覧を表示するため、ListViewを使います（☆7）。

```python:blogapp/blog/views.py
from blog.models import BlogModel
from django.shortcuts import render, redirect
from django.views.generic import TemplateView, ListView # ☆7
from django.contrib.auth.models import User
from django.db import IntegrityError
from django.contrib.auth import authenticate, login, logout
from .models import BlogModel

class BlogTop(TemplateView):...

def signupview(request):...

def logoutview(request):...

class BlogList(ListView): # ☆7
    template_name = 'blog/list.html'
    model = BlogModel
```

**urls.py**を編集します（☆8）。

```python:blogapp/blog/urls.py
from django.urls import path
from .views import BlogTop, signupview, loginview, logoutview, BlogList # ☆8

app_name = 'blog'

urlpatterns = [
    path('', BlogTop.as_view(), name='top'),
    path('signup/', signupview, name='signup'),
    path('login/', loginview, name='login'),
    path('logout/', logoutview, name='logout'),
    path('list/', BlogList.as_view(), name='list'), # ☆8

]
```

完成。