Django
テンプレート
サーチ…
変数
ビューコンテキストで提供された変数には、二重カッコ表記を使用してアクセスできます。
あなたのviews.py
:
class UserView(TemplateView):
""" Supply the request user object to the template """
template_name = "user.html"
def get_context_data(self, **kwargs):
context = super(UserView, self).get_context_data(**kwargs)
context.update(user=self.request.user)
return context
user.html
:
<h1>{{ user.username }}</h1>
<div class="email">{{ user.email }}</div>
ドット表記は次のものにアクセスします:
- オブジェクトのプロパティ。たとえば、
user.username
は{{ user.username }}
- 辞書検索、例えば
request.GET["search"]
は{{ request.GET.search }}
- 引数のないメソッド(例:
users.count()
は{{ user.count }}
テンプレート変数は引数を取るメソッドにアクセスできません。
また、変数をテストしてループバックすることもできます。
{% if user.is_authenticated %}
{% for item in menu %}
<li><a href="{{ item.url }}">{{ item.name }}</a></li>
{% endfor %}
{% else %}
<li><a href="{% url 'login' %}">Login</a>
{% endif %}
URLは、 {% url 'name' %}
形式を使用してアクセスします。ここで、名前はurls.py
名前に対応します。
{% url 'login' %}
- /accounts/login/
{% url 'user_profile' user.id %}
- URLの引数は順番に指定されます
{% url next %}
- URLは変数にすることができます
クラスベースのビューでのテンプレート
カスタム変数でテンプレートにデータを渡すことができます。
あなたのviews.py
:
from django.views.generic import TemplateView
from MyProject.myapp.models import Item
class ItemView(TemplateView):
template_name = "item.html"
def items(self):
""" Get all Items """
return Item.objects.all()
def certain_items(self):
""" Get certain Items """
return Item.objects.filter(model_field="certain")
def categories(self):
""" Get categories related to this Item """
return Item.objects.get(slug=self.kwargs['slug']).categories.all()
あなたのitem.html
簡単なリスト:
{% for item in view.items %}
<ul>
<li>{{ item }}</li>
</ul>
{% endfor %}
また、データの追加のプロパティを取得することもできます。
モデルItem
にname
フィールドがあると仮定します:
{% for item in view.certain_items %}
<ul>
<li>{{ item.name }}</li>
</ul>
{% endfor %}
関数ベースのビューでのテンプレート
次のように、関数ベースのビューでテンプレートを使用できます。
from django.shortcuts import render
def view(request):
return render(request, "template.html")
テンプレート変数を使用する場合は、次のようにします。
from django.shortcuts import render
def view(request):
context = {"var1": True, "var2": "foo"}
return render(request, "template.html", context=context)
次に、 template.html
では、変数を次のように参照できます。
<html>
{% if var1 %}
<h1>{{ var2 }}</h1>
{% endif %}
</html>
テンプレートフィルタ
Djangoのテンプレートシステムには、 タグとフィルタが組み込まれています 。これはテンプレート内の関数であり、コンテンツを特定の方法でレンダリングします。パイプで複数のフィルタを指定でき、変数構文と同様にフィルタに引数を付けることができます。
{{ "MAINROAD 3222"|lower }} # mainroad 3222
{{ 10|add:15}} # 25
{{ "super"|add:"glue" }} # superglue
{{ "A7"|add:"00" }} # A700
{{ myDate | date:"D d M Y"}} # Wed 20 Jul 2016
利用可能な組み込みフィルターのリストは、 https://docs.djangoproject.com/en/dev/ref/templates/builtins/#ref-templates-builtins-filtersにあります 。
カスタムフィルタの作成
独自のテンプレートフィルタを追加するには、appフォルダ内にtemplatetags
という名前のフォルダを作成します。次に、 __init__.py
追加し、フィルタを含むファイルをファイルに追加します。
#/myapp/templatetags/filters.py
from django import template
register = template.Library()
@register.filter(name='tostring')
def to_string(value):
return str(value)
実際にフィルタを使用するには、テンプレートにロードする必要があります。
#templates/mytemplate.html
{% load filters %}
{% if customer_id|tostring = customer %} Welcome back {% endif%}
トリック
フィルタは最初はシンプルに見えますが、それはいくつかのすてきなことをすることを可能にします:
{% for x in ""|ljust:"20" %}Hello World!{% endfor %} # Hello World!Hello World!Hel...
{{ user.name.split|join:"_" }} ## replaces whitespace with '_'
詳細については、 テンプレートタグを参照してください。
機密方法がテンプレートで呼び出されないようにする
オブジェクトがテンプレートコンテキストにさらされると、その引数のないメソッドが利用できます。これは、これらの関数が「ゲッタ」である場合に便利です。しかし、これらの方法によってデータが変更されたり、副作用があったりすると危険なことがあります。テンプレートライターを信頼している可能性はありますが、彼は関数の副作用を認識していないか、間違って誤った属性を誤って呼び出すと思っているかもしれません。
次のモデルを考えます。
class Foobar(models.Model):
points_credit = models.IntegerField()
def credit_points(self, nb_points=1):
"""Credit points and return the new points credit value."""
self.points_credit = F('points_credit') + nb_points
self.save(update_fields=['points_credit'])
return self.points_credit
これを間違いなくテンプレートに書いた場合:
You have {{ foobar.credit_points }} points!
これにより、テンプレートが呼び出されるたびにポイントの数が増えます。あなたはそれに気付かないかもしれません。
これを防ぐには、副作用のあるメソッドに対してalters_data
属性をTrue
に設定する必要があります。これは、テンプレートからそれらを呼び出すことが不可能になります。
def credit_points(self, nb_points=1):
"""Credit points and return the new points credit value."""
self.points_credit = F('points_credit') + nb_points
self.save(update_fields=['points_credit'])
return self.points_credit
credit_points.alters_data = True
{%extend%}、{%include%}、{%blocks%}の使用
概要
{%extends%} :引数として与えられたテンプレートを現在のテンプレートの親として宣言します。使用法:
{% extends 'parent_template.html' %}
。{%block%} {%endblock%} :これはテンプレート内のセクションを定義するために使用されるので、別のテンプレートがこのテンプレートを拡張すると、内部に書かれたHTMLコードを置き換えることができます。ブロックはその名前で識別されます。使用法:
{% block content %} <html_code> {% endblock %}
。{%include%} :これは現在のテンプレートにテンプレートを挿入します。インクルードされたテンプレートは要求のコンテキストを受け取るので、カスタム変数も指定できます。基本的な使用法:
{% include 'template_name.html' %}
、変数の使用法{% include 'template_name.html' with variable='value' variable2=8 %}
ガイド
すべてのコードに対して共通のレイアウトを持つフロントエンドサイドコードを構築していて、すべてのテンプレートに対してコードを繰り返したくないとします。 Djangoはそうするためのビルド済みのタグを提供します。
同じレイアウトを共有する3つのテンプレートを持つ1つのブログWebサイトがあるとします。
project_directory
..
templates
front-page.html
blogs.html
blog-detail.html
1) base.html
ファイルを定義し、
<html>
<head>
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
2) blog.html
ように、
{% extends 'base.html' %}
{% block content %}
# write your blog related code here
{% endblock %}
# None of the code written here will be added to the template
ここでは基本レイアウトを拡張して、HTMLレイアウトがblog.html
ファイルで利用できるようにしました。 { % block %}
コンセプトはテンプレートの継承です。これにより、あなたの共通要素をすべて含む基本的な "スケルトン"子テンプレートが上書きできるブロックを定義します。
3)あなたの3つのテンプレートのすべてが同じHTML divを持っていると仮定します。これは人気のある投稿を定義します.3回書かれる代わりに、新しいテンプレートposts.html
作成します。
blog.html
{% extends 'base.html' %}
{% block content %}
# write your blog related code here
{% include 'posts.html' %} # includes posts.html in blog.html file without passing any data
<!-- or -->
{% include 'posts.html' with posts=postdata %} # includes posts.html in blog.html file with passing posts data which is context of view function returns.
{% endblock %}