Передача данных (переменных) в шаблоны

Курс по Django: https://stepik.org/a/183363

Архив проекта: 10_sitewomen.zip

Я много раз произносил слово «шаблон», но что оно означает? Если посмотреть на файлы index.html или about.html, то это просто текст, который загружается и отдается браузеру по соответствующему запросу. Все так, но в этих же файлах можно прописывать конструкции для отображения информации, например, из переменных или БД. Давайте для начала сделаем так, чтобы на каждой странице был свой заголовок, переданный ей через параметр title. Это можно сделать следующим образом. В файлах index.html и about.html укажем переменную title:

<!DOCTYPE html>
<html>
<head>
         <title>{{title}}</title>
</head>
<body>
<h1>{{title}}</h1>
</body>
</html>

А в функциях представлений передать параметр title соответствующему шаблону. Делается это с помощью словарей. В нашем случае необходимо определить словарь с ключом title и значением, которое будет подставляться вместо этого ключа. Например, так:

def index(request):
    data = {'title': 'Главная страница'}
    return render(request, 'women/index.html', data)

При обновлении страницы увидим, что вместо {{title}} в шаблоне было подставлено значение ключа title словаря data. То есть, внутри шаблонов Django можно прописывать двойные фигурные скобки и указывать параметр (ключ), значение которого здесь будет подставлено.

Или, можно использовать более короткую форму:

def about(request):
    return render(request, 'women/about.html', {'title': 'О сайте'})

Тогда при переходе к странице:

http://127.0.0.1:8000/about/

увидим вместо {{title}} строку «О сайте». Удобно, правда? Вот в этом и есть роль шаблонов: они описывают структуру страницы, а ее наполнение происходит динамически в самой программе.

Конечно, можно выполнять передачу самых разных типов данных: чисел, строк, списков, кортежей, словарей, объектов классов и так далее. Давайте опишем главное меню сайта с помощью списка:

menu = ["О сайте", "Добавить статью", "Обратная связь", "Войти"]

А, затем, в функциях представления, мы можем передать его как параметр:

def index(request):
    data = {
        'title': 'Главная страница',
        'menu': menu,
    }
    return render(request, 'women/index.html', context=data)

Обратите внимание, я здесь передаю словарь data через именованный аргумент context. Это то же самое, что и просто третьим аргументом прописать data. Иногда в программах можно встретить и такую запись.

В самом простом варианте в шаблоне index.html отобразить такой список можно следующим образом:

<!DOCTYPE html>
<html>
<head>
         <title>{{title}}</title>
</head>
<body>
<p >{{menu}}</p>
<h1>{{title}}</h1>
</body>
</html>

Обновляем главную страницу и видим список из строк. Однако если мы попытаемся в шаблоне обратиться к элементу по индексу:

<p >{{menu[0]}}</p>

то получим ошибку:

TemplateSyntaxError at /

так как шаблонизатор Django не поддерживает такую операцию. О том, как перебирать различные коллекции и обращаться к отдельным элементам в шаблонах мы с вами еще будем говорить.

Давайте в шаблоне about.html также пропишем вывод параметра menu:

<p >{{menu}}</p>

Если теперь перейти по адресу:

http://127.0.0.1:8000/about/

то этого списка мы не увидим. Дело в том, что в функции представления about() передается только словарь с ключом title. Ключ menu отсутствует. Поэтому шаблонизатор не находит параметр menu и просто его игнорирует. Обратите внимание, именно игнорирует. Никаких ошибок при этом не возникает.

Давайте для примера передадим в шаблон index.html другие распространенные типы данных:

class MyClass:
    def __init__(self, a, b):
        self.a = a
        self.b = b
 
 
def index(request):
    data = {
        'title': 'Главная страница',
        'menu': menu,
        'float': 28.56,
        'lst': [1, 2, 'abc', True],
        'set': {1, 1, 2, 3, 2, 5},
        'dict': {'key_1': 'value_1', 'key_2': 'value_2'},
        'obj': MyClass(10, 20),
    }
   
 
    return render(request, 'women/index.html', context=data)

И выведем их в шаблоне index.html следующим образом:

<!DOCTYPE html>
<html>
<head>
         <title>{{title}}</title>
</head>
<body>
<p >{{menu}}</p>
<p >{{float}}</p>
<p >{{lst}}</p>
<p >{{set}}</p>
<p >{{dict}}</p>
<p >{{obj}}</p>
 
<h1>{{title}}</h1>
</body>
</html>

При обновлении главной страницы увидим все переданные данные. Причем, к ключам словаря и к атрибутам класса можно обращаться через точку следующим образом:

<p >{{dict.key_1}}</p>
<p >{{obj.a}}</p>

Обратите внимание, что здесь используется оператор «точка» в том числе и у словарей. Прописывать квадратные скобки с указанием ключа недопустимо:

<p >{{dict['key_1']}}</p>

получим ошибку.

Также следует иметь в виду, что каждый отображаемый параметр должен быть записан в отдельных двойных фигурных скобках. Прописывать несколько параметров нельзя. Например, следующая строчка приведет к ошибке:

<p >{{obj.a obj.b}}</p>

Правильно записывать так:

<p >{{obj.a}} {{obj.b}}</p>

Думаю, теперь вы хорошо себе представляете, как передаются и отображаются параметры (переменные) шаблонах.

Курс по Django: https://stepik.org/a/183363

Видео по теме