はじめに
個人的まとめ
変数
変数の展開
{{ var }}
{{ 変数名 }}
テンプレートへの変数の渡し方
def index(request):
context = {'var': 'Hello'}
return render(request, 'myhtml/index.html', context)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>index</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<p>{{ var }}</p>
</body>
</html>
- **
head
**タグはメタデータを書くところなので実際に表示されるわけではない - **
p
**タグは一つの段落を表す
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>index</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<p>Hello</p>
</body>
</html>
テンプレートタグ
- Djangoにはプログラミング言語の予約語に相当する、テンプレートタグと呼ばれるものがある
- テンプレートタグは**
{% タグ名 %}
**と記述する
if文
{% if s == "django" and n != 5 %}
<p>おはよう</p>
{% elif n != 5 or b is True %}
<p>こんにちは</p>
{% elif b is not True %}
<p>こんばんは</p>
{% else %}
<p>ハロー</p>
{% endif %}
-
==
や!=
、**is
**が使用可能 -
and
やor
、**not
**も使用可能 - **
s=="django"
だとエラーが出る。s == "django"
**のようにスペースを空けないとダメ
for文
リスト
**list_ = [ "hello", "world", "!" ]**
のとき、
{% for i in list_ %}
<p>{{ i }}</p>
<hr>
{% endfor %}
<p>hello</p>
<hr>
<p>world</p>
<hr>
<p>!</p>
<hr>
- **
hr
**タグは段落の意味的な区切りを表す。あくまで意味的な区切りであって、表示的な区切りではないので単に水平線を引きたいならばCSSを使う
辞書
**dic = {"A":"APPLE","B":"BANANA","C":"CHERRY"}
**のとき、
{% for k, v in dic.items %}
<p>{{ k }}{{ v }}</p>
{% endfor %}
- 辞書の名前の後ろに**
.items
**をつけるのを忘れないように
リストの中身がないときに別の内容を表示
{% for i in list_ %}
<p>{{ i }}</p>
{% empty %}
<p>the list is empty.</p>
{% endfor %}
- **
{% empty %}
**節を加えることでリストの中身が空だった場合に別の内容を表示できる
{% if i %}
{% for i in list_ %}
<p>{{ i }}</p>
{% endfor %}
{% else %}
<p>the list is empty.</p>
{% endif %}
- 上記のようにもできるが、**
{% empty %}
**節を使った方が見やすい
リストのうちの一部を表示
{% for i in list_|slice:"2:5" %}
<p>{{i}}</p>
{% endfor %}
- **
slice
**フィルタを用いることで、リストの一部を表示することができる - 上の場合はリストの2番目から4番目までが表示される
- **
":5"
とすれば最初から4番目まで、"2:"
**とすれば2番目から最後までが表示 - **
for i in list_|slice:"2:5"
**は3箇所ともくっつけて書かないとだめ。 **for i in list_ | slice: "2:5"
**などとするとエラーになる
ループの最初だけ別の処理を行う
{% for i in list_ %}
{% if forloop.first %}
<p>This is first time. {{ i }}</p>
{% else %}
<p>{{ i }}</p>
{% endif %}
{% endfor %}
- **
forloop.first
は1回目のループの場合はTrue
を、それ以外の場合にはFalse
**を返す - if文と組みあわせるとループの最初だけ別の処理をさせることができる
ループの最後だけ別の処理を行う
{% for i in list_ %}
{% if forloop.last %}
<p>This is last time. {{ i }}</p>
{% else %}
<p>{{ i }}</p>
{% endif %}
{% endfor %}
- **
forloop.last
は最後のループの場合はTrue
を、それ以外の場合にはFalse
**を返す - if文と組みあわせるとループの最初だけ別の処理をさせることができる
- もちろん、**
forloop.first
とforloop.last
**は同時に使うこともできる
ループカウントを取得する
{% for i in list_ %}
<p>index:{{ forloop.counter0 }}/
count:{{ forloop.counter }}/
value:{{ i }}</p>
{% endfor %}
- **
forloop.counter0
**はループの回数を**0**
からカウントアップする- 1回目のループなら**
0
、2回目のループなら1
、N回目ならN-1
**になる - Pythonの**
enumerate
**と同じ働きをする
- 1回目のループなら**
- **
forloop.counter
はループの回数を1
**からカウントアップする- 1回目のループなら**
1
、2回目のループなら2
、N回目ならN
**になる
- 1回目のループなら**
ループカウントを逆順で取得する
{% for i in list_ %}
<p>index:{{ forloop.revcounter0 }}/
count:{{ forloop.revcounter }}/
value:{{ i }}</p>
{% endfor %}
- **
forloop.revcounter0
はループの回数をN
**からカウントダウンする- 1回目のループなら**
N
、2回目のループならN-1
、N回目なら1
**になる - Pythonの**
enumerate
**と同じ働きをする
- 1回目のループなら**
- **
forloop.revcounter
はループの回数をN-1
**からカウントダウンする- 1回目のループなら**
N-1
、2回目のループならN-2
、N回目なら0
**になる
- 1回目のループなら**
ループの特定の回数のところで別の処理をする
{% for i in list_ %}
{% if forloop.counter|divisibleby:'3' %}
<p>this is a multiple of three.{{forloop.counter}}</p>
{% else %}
<p>{{i}}</p>
{% endif %}
{% endfor %}
- **
forloop.counter
**とif文を組み合わせるとループの特定の回数のところで別の処理をする、といったことが実現できる - **
divisibleby
フィルターは値が引数の値で割り切れる場合にTrue
**を返す - 上記の例では3回ごとに違う処理をしている
挿入
{% include "other_template.file" %}
- 別のテンプレートを挿入する
- 各ページに同じもの(アイコン画像、外部のjsファイル、cssファイルなど)を配置するときなどに便利
- 一箇所を書き換えるだけで良くなるのでメンテナンス性が向上する
利用例
一部のページのみjQueryを必要とするとき、
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>template</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
{% include "js_parts.html" %}
</head>
<body>
<p>Hello World!</p>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>template</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
</head>
<body>
<p>Hello World!</p>
</body>
</html>
ブロック化
- ヘッダーやフッター、サイドバーなど複数のページで共通するパーツをブロック化することでメンテナンス性が向上する
- **
{% block ブロック名 %}
と{% endblock %}
**で囲ったところがひとつのブロックになる - ブロック名は他のものと名前が被らなければなんでもいい
- 下記の例では**
index1.html
はbase.html
をextends
タグを使って継承し、my_title
**ブロックに任意の文字列を入れてカスタマイズを加えている - **
index2.html
はindex1.html
をさらに継承し、index2
**ブロックに任意の文字列を入れてカスタマイズを加えている
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{% block my_title %}タイトル{% endblock %}</title>
</head>
<body>
<header>
{% block my_header %}
<p>ヘッダー</p>
{% endblock %}
</header>
{% block my_body %}
<p>ボディ</p>
{% endblock %}
<footer>
{% block my_footer %}
<p>フッター</p>
{% endblock %}
</footer>
</body>
</html>
{% extends 'myhtml/base.html' %}
{% block my_title %}トップページ{% endblock %}
{% block my_body %}
<p>トップページです</p>
{% block index %}
<p>インデックス1</p>
{% endblock %}
{% endblock %}
{% extends 'myhtml/index1.html' %}
{% block index %}
<p>インデックス2</p>
{% endblock %}