Djangoでの他のテンプレートの継承とフィルタ機能、カスタムテンプレートフィルタの実装

○他のテンプレートの継承
DTLでは、他のテンプレートを継承して。そのテンプレートの機能をそのまま利用することが出来る。ヘッダーの作成や、画面間で共通する機能を実装し、継承先で独自の内容を記述するようになる。


#継承元
```
<html>
{% block content %}
ここの内容は継承先が記載する。
{% endblock %}
</html>
```

#継承先
```
{% extends "base.html" %}

{% block content %}
ここに独自の内容を記述する
{% endblock %}
#継承元の要素を利用する場合は{{block.super}}と記載する。
```
例：

#継承元(base.html)
```
<!DOCTYPE html>
<html>
    <head>
        <meta charset='urf-8'>
        <title>{% block title %}Django大学陸上部{% endblock %}</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
        {% load static%}
        <link rel="stylesheet" href="{% static 'css/style.css' %}">
    </head>
    <body>
        <nav class="navbar navbar-expand-lg navbar-light bg-light">
            <a class="navbar-brand" href="{% url 'app:home' %}"> Home </a>
            <a class="navbar-brand" href="{% url 'app:members' %}"> メンバー一覧 </a>
        </nav>
    {% block content %}{% endblock %}
    </body>
<html>
```

#継承先(home.html)
```
{% extends "base.html" %}
{% block title %}ホーム{{ block.super}}{% endblock %}
{% block content %}
<p>Django大学陸上部ホーム</p>
{% endblock %}
```

こうすることでbaseを軸にしたページを複数作成することが出来る。
extendsで継承元を指定して、継承先ではblockで囲まれた変更部分を入力する。

○フィルター機能
templateで用いられるフィルター機能がある。pythonのメソッドのようなイメージ。
各単語をフィルタする場合、{{単語|filter}}として使用し、文章全体で指定する場合は{% filter upper %} ~ {% endfilter %}とすると囲われた~の部分はそのフィルターが有効になっている。様々な機能があるため使用する際はドキュメントを参考にする。

https://docs.djangoproject.com/ja/3.1/ref/templates/builtins/#built-in-filter-reference

https://qiita.com/nachashin/items/d3f9cd637a9cecbda72c

#sample.html
```
<h1>{{name|upper}}</h1>

<h1>{{page_url|urlize}}</h1>

<p>BMI:{{bmi|floatformat:2}}</p>

<p>給料:{{salary|default:'ヒミツ'}}</p>

<p>フルーツ:{{fruits|random|lower}}</p>

<p>フルーツ:{{fruits|join:','}}</p>

<p>メッセージ:{{msg|linebreaks}}</p>

<p>メッセージ:{{msg}}</p>

<p>メッセージ2:{{msg2|truncatechars:5}}</p>

{% filter upper%}
<p>aaaaaaaaaaaa</p>
<h1>bbbbbbbbbbbbbbb</hi>
{% endfilter%}
```
#app/views.py
```
def sample(request):
    name = 'Yusuke Someya'
    height = 172.0
    weight = 58
    bmi = weight/(height / 100)**2
    page_url ='ホームページ : https://www.google.com'
    favorite_fruits = [
        'Apple', 'Grape', 'Lemon'
    ]
    msg = """
    Hello
    my name is 
    Yusuke
    """

    msg2 = '1234567890'

    return render(request, 'sample.html', context={
        'name': name,
        'bmi': bmi,
        'page_url': page_url,
        'fruits': favorite_fruits,
        'msg': msg,
        'msg2': msg2,
    })
```

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2971002/f6ac3fa6-196a-2654-9fb7-5cf549413909.png)

○Templatesでのカスタムテンプレートの実装
カスタムテンプレートフィルタとは上記に記入したテンプレートフィルタを自分で作成することが出来るというもの。

これを作成する手順は以下の通り。
1.アプリケーションのフォルダ内にtemplatetagsフォルダを作成する。
2.templatetagsの中に__init__.pyを作成する。
3.filterを自作するファイルを作成し、中に関数を定義する。
4.templateの中でloadして利用する。

3について詳しく。
必要な記述がいくつかある。
一番初めに
```
from django import template

register = template.Library()
```
と記述する。そして、フィルタにする関数の上部に
```
@register.filter(name='custom_template_filter_name')
```
を指定する。この引数のnameの部分はフィルタの名前となり、フィルタを呼び出す際に使用する。
実際に使用すると下のような感じになる。

```
from django import template

register = template.Library()


@register.filter(name='status_to_string')
def convert_status_to_string(status,name):
    print(f'name = {name}')
    if status == 10:
        return 'Success'
    elif status == 20:
        return 'Error'
    elif status == 30:
        return 'Pending'
    elif status == 40:
        return 'Failded'
    else:
        return 'Unknown'
```
こちらの場合、引数は2つ持ち、呼び出す際に｜(pipe)を挟んで向こうの変数と呼び出したときにもう一つ別に引数を与える必要がある。実際には下のように使用し、処理が行われると、statusの値によって表記が変わり、Yusukeとログに出力される仕組みになっている。

```
<p>{{status | status_to_string:"Yusuke"}}</p>
```