Django предоставляет возможность использовать в шаблонах ряд специальных тегов, которые упрощают вывод некоторых данных. Рассмотрим некоторые наиболее используемые теги.
Тег autoescape позволяет автоматически экранировать ряд символов HTML и тем самым сделать вывод на страницу более безопасным. В частности, производятся следующие замены:
< заменяется на <
> заменяется на >
' (одинарная кавычка) заменяется на '
" (двойная кавычка) заменяется на "
& заменяется на &
Например, пусть у нас будет определен следующий шаблон index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Django на METANIT.COM</title>
</head>
<body>
{{ body }}
{% autoescape off %}
{{ body }}
{% endautoescape %}
</body>
</html>
Здесь в шаблоне два раза выводится содержимое переменной body. Однако сначала она выводится сама по себе, в во втором случае ее вывод помещается в
между тегами {% autoescape %} и {% endautoescape %}. Тег в качестве параметра принимает одно из значений: on
(экранирование включено) и off (экранирование отключено). В данном случае тегу передается значение off, а это
значит, что внутри блока тега autoescape экранирование отключено.
Определим следующую функцию-представление, которая использует данный шаблон и передает в него некоторые данные:
from django.shortcuts import render
def index(request):
return render(request, "index.html", context = {"body": "<h1>Hello World!</h1>"})
Здесь в шаблон передается некоторая строка с кодом HTML. По умолчанию шаблоны применяют экранирование. Поэтому на веб-странице мы увидим код html в текстовом виде, а во втором случае переданные данные будут интпретированы непосредственно как код html:
Для определения комментариев в шаблоне применяется тег comment: все, что помещается между тегами {% comment %} и {% endcomment %}, игнорируется при генерации html-страницы.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Django на METANIT.COM</title>
</head>
<body>
{% comment %}
<p>Вывод содержимого в шаблон Django</p>
{% endcomment %}
{{ body }}
</body>
</html>
Тег if оформляется в виде блока:
{% if условие %}
содержимое блока
{% endif %}
Этот тег оценивает некоторое условие, которое должно возращать True или False: если
возвращается True, то выводится содержимое блока {% if %}.
Например, пусть в представлении передаются в шаблон некоторые значения:
from django.shortcuts import render
def index(request):
data = {"n" : 5}
return render(request, "index.html", context=data)
В шаблоне в зависимости от значения переменной n мы можем выводить определенный контент:
{% if n > 0 %}
<p>Число положительное</p>
{% endif %}
То есть если n больше 0, то будет выводиться, что число положительное. Если n меньше или равно 0, ничего не будет выводиться.
С помощью дополнительного тега {% else %} можно вывести контент в случае, если условие после if равно False:
{% if n > 0 %}
<p>Число положительное</p>
{% else %}
<p>Число отрицательное или равно нулю</p>
{% endif %}
С помощью тега {% elif %} можно проверить дополнительные условия, если условие в if равно False:
{% if n > 0 %}
<p>Число положительное</p>
{% elif n < 0 %}
<p>Число отрицательное</p>
{% else %}
<p>Число равно нулю</p>
{% endif %}
Стоит отметить, что в условии, которое передается тегу if, можно применять ряд операторов, которые возвращают True или False:
==, !=, <, >, <=,
>=, in, not in, is, is not,
and, or, not.
{% if a > 0 and b > 0 %}
<p>{{ a }}</p>
{% else %}
<p>{{ b }}</p>
{% endif %}
Тег for позволяет создавать циклы. Этот тег принимает в качестве параметра некоторую коллекцию и пробегается по этой коллекции, обрабатывая каждый ее элемент.
{% for element in collection %}
действия с element
{% endfor %}
Например, пусть из представления в шаблон передается некоторый список:
from django.shortcuts import render
def index(request):
langs = ["Python", "JavaScript", "Java", "C#", "C++"]
return render(request, "index.html", context={"langs": langs})
Выведем элементы списка langs в шаблоне с помощью тега for:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Django on METANIT.COM</title>
</head>
<body>
<ul>
{% for lan in langs %}
<li>{{ lan }}</li>
{% endfor %}
</ul>
</body>
</html>
Вполне возможно, что переданная из представления в шаблон коллекция окажется пустой. На этот случай мы можем использовать тег {% empty %}:
<ul>
{% for lan in langs %}
<li>{{ lan }}</li>
{% empty %}
<li>Langs array is empty</li>
{% endfor %}
</ul>
Подобным образом можно перебирать в шаблоне другие коллекции, например, словари:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Django on METANIT.COM</title>
</head>
<body>
{% for key, value in data.items %}
<p>{{ key }}: {{ value }}</p>
{% endfor %}
</body>
</html>
В данном случае перебирается словарь data, который передается из представления:
from django.shortcuts import render
def index(request):
data = {"red": "красный", "green": "зеленый", "blue":"синий"}
return render(request, "index.html", context={"data": data})
Тег {% with %} позволяет определить переменную и использовать ее внутри блока тега. Например:
{% with name="Tom" age=29 %}
<div>
<p>Name: {{ name }}</p>
<p>Age: {{ age }}</p>
</div>
{% endwith %}
В данном случае определены две переменных: name и age, которые мы можем использовать внутри блока {% with%} ... {% endwith %}. Однако вне
этого блока эти переменные использоваться не могут.
Тег {% now "формат_данных" %} позволяет вывести системное время. В качестве параметра тегу now передается формат данный, который указывает, как форматировать время и дату.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Django on METANIT.COM</title>
</head>
<body>
<p>{% now "Y" %}</p>
<p>{% now "F j Y" %}</p>
<p>{% now "N, j, Y" %}</p>
<p>{% now "N j, Y, P" %}</p>
</body>
</html>
Символ "Y" передает год в виде четырех цифр, "y" - берет из года последние две цифры. "F" - полное название месяца, "N" -сокращенное название месяца. "j" - день месяца. "P" - время. Все возможные форматы для вывода даты и времени можно посмотреть в документации
Стоит отметить, что в качестве времени Django берет значение переменной из файла settinds.py, которая по умолчанию имеет следующее определение:
TIME_ZONE = 'UTC'
То есть отсчитывается относительно UTC. Это может быть не всегда удобно. И соответственно мы можем изменить ее значение на нужное. Например, настройка для московского часового пояса:
TIME_ZONE = 'Europe/Moscow'