Django Inclusion tag
Намагаюся створити тег, що включає, якому передається об'єкт моделі Player і він відображає інформацію про переданого гравця (поля моделі) У директорії templatetags (там є інші включають теги, створені не мною і працюють) у файлі player.py створюю власне функцію для тега і реєструю:
від django import template register = template.Library() @register.inclusion_tag('gamecore/main_menu/PlayerInfo.html', name='player_info') def player_info(player): return
І намагаюся використовувати в іншому шаблоні з передачею аргументу player, який передається в цей шаблон:
Але на сторінці нічого не відображається? Можливо, я забув щось важливе? Робив усе за документацією. Використовую Django 1.11.12
Який тег Django використовується для включення шаблону до іншого шаблону?
Django надає можливість використовувати у шаблонах ряд спеціальних тегів, які спрощують виведення деяких даних. Розглянемо деякі теги, що найбільш використовуються.
autoescape
Тег autoescape дозволяє автоматично екранувати ряд символів HTML і тим самим зробити висновок на сторінку безпечнішим. Зокрема, здійснюються такі заміни:
- < замінюється на <
- > замінюється на >
- '(одинарна лапка) замінюється на '
- (подвійна лапка) замінюється на
- & замінюється на &
Наприклад, нехай у нас буде визначено наступний шаблон index.html:
Django на METANIT.COM
> >
Тут у шаблоні двічі виводиться вміст змінної body. Однак спочатку вона виводиться сама по собі, у другому випадку її висновок міститься між тегами і . Тег як параметр приймає одне із значень: on (екранування включено) та off (екранування вимкнено). У даному випадку тегу передається значення off , а це означає, що всередині блоку тега autoescape екранування відключено.
Визначимо наступну функцію-подання, яка використовує даний шаблон і передає в нього деякі дані:
з django.shortcuts import render def index(request): return render(request, "index.html", context = Hello World!">)
Тут шаблон передається деякий рядок з кодом HTML. За промовчанням шаблони використовують екранування. Тому на веб-сторінці ми побачимо код html у текстовому вигляді, а у другому випадку передані дані будуть інтерпретовані безпосередньо як код html:
Коментарі
Для визначення коментарів у шаблоні застосовується тег comment : все, що міститься між тегами та , ігнорується при генерації html-сторінки.
Django на METANIT.COM
Виведення вмісту у шаблон Django
>
if..else
Тег if оформляється у вигляді блоку:
Цей тег оцінює певну умову, яка повинна повертати True або False: якщо повертається True, то виводиться вміст блоку.
Наприклад, нехай у поданні передаються шаблону деякі значення:
з django.shortcuts import render def index(request): data = return render(request, "index.html", context=data)
У шаблоні в залежності від значення змінної n ми можемо виводити певний контент:
0 %>
Число позитивне
Тобто якщо n більше 0, то виводитиметься, що число позитивне. Якщо n менше або 0, нічого не буде виводитися.
За допомогою додаткового тега можна вивести контент у випадку, якщо умова після if дорівнює False:
0 %>
Число позитивне
Число негативне або дорівнює нулю
За допомогою тега можна перевірити додаткові умови, якщо умова в if дорівнює False:
0 %>
Число позитивне
Число негативне
Число дорівнює нулю
Варто зазначити, що в умові, що передається тегу if можна застосовувати ряд операторів, які повертають True або False: == , != , < , >, = , in , not in , is , not , and , or , not .
Цикли
Тег for дозволяє створювати цикли.Цей тег приймає як параметр деяку колекцію і пробігається цією колекцією, обробляючи кожен її елемент.
дії з element
Наприклад, нехай із подання до шаблону передається певний список:
з django.shortcuts import render def index(request): langs = ["Python", "JavaScript", "Java", "C#", "C++"] return render(request, "index.html", context=)
Виведемо елементи списку langs у шаблоні за допомогою тега for :
Цілком можливо, що передана з подання до шаблону колекція виявиться порожньою. На цей випадок ми можемо використовувати тег:
Подібним чином можна перебирати в шаблоні інші колекції, наприклад, словники:
Django on METANIT.COM
>: >
У разі перебирається словник data, який передається з представлення:
від django.shortcuts import render def index(request): data = return render(request, "index.html", context=)
Визначення змінних
Тег дозволяє визначити змінну та використовувати її всередині блоку тега. Наприклад:
В даному випадку визначено дві змінні: name та age, які ми можемо використовувати всередині блоку . . Однак поза цим блоком ці змінні використовуватися не можуть.
Дати
Тег дозволяє вивести системний час. Як параметр тегу now передається формат даний, який вказує, як форматувати час та дату.
Django on METANIT.COM
Символ "Y" передає рік у вигляді чотирьох цифр, "y" бере з року останні дві цифри. "F" - повна назва місяця, "N" -скорочена назва місяця. "j" – день місяця. "P" – час. Усі можливі формати для виведення дати та часу можна переглянути в документації
Варто зазначити, що як час Django бере значення змінної файлу settinds.py , яка за умовчанням має таке визначення:
Тобто відраховується щодо UTC. Це може бути не завжди зручним. І відповідно, ми можемо змінити її значення на потрібне. Наприклад, налаштування для московського часового поясу:
TIME_ZONE = 'Europe/Moscow'
Наслідування шаблонів (extends). Мітки include
На попередніх заняттях ми детально описали шаблон index.html для головної сторінки сайту. Давайте відредагуємо ще один about.html із виведенням інформації про сайт. У найпростішому варіанті його можна представити так:
DOCTYPE html>
html>
head>
title>{{title}}/title>
/head>
body>
ul>
li>a href="">Головна/a>/li>
{% for m in menu %}
{% if
not forloop.last %}li>{% else %}li class="last">{% endif %}
a href="">{{m.title}}/a>
/li>
{% endfor %}
/ul>
h1>{{title}}/h1>
/body>
/html>
Тобто я просто скопіював початок шаблону з index.html та вставив у файл about.html.
Відредагуємо функцію about у файлі views.py, додавши передачу списку пунктів menu:
def про(request): return render(request,
'women/about.html',
{'title': 'Про сайт',
'menu': menu})
Після запуску тестового веб-сервера та переходу за URL-адресою:
побачимо сторінку «Про сайт» із виведенням головного меню.
Проте, як ви вже здогадалися, дублювання інформації у різних шаблонах порушує відомий принцип:
DRY – don't repeat yourself (не повторюйся).
Для усунення цього недоліку зазвичай створюється базовий (загальний) шаблон, що містить загальні елементи типових сторінок сайту, а вже потім він розширюється (доповнюється деталями) шаблонами окремих сторінок. Таке розширення називається успадкування шаблонів. І зараз ми на конкретному прикладі побачимо, як це можна зробити.
Якщо перейти в документацію по фільтрам та тегам шаблонів фреймворку Django, то серед тегів можна зустріти такі:
Я докладно про них розповідав у курсі шаблонізатора Jinja2:
Але тут повторюся, тому що абсолютно нічого складного в наслідуванні шаблонів немає.
Отже, на початку ми з вами визначимо базовий шаблон. Його зазвичай створюють на рівні всього проекту. Тому створимо каталог templates в папці sitewomen, а в ньому файл з ім'ям base.html.Однак якщо ми зараз спробуємо звернутися до цього шаблону, наприклад, у функції представлення про:
def про(request): return render(request,
'base.html',
{'title': 'Про сайт',
'menu': menu})
то побачимо помилку, що шаблон не було знайдено. Це пов'язано з тим, що маршрут templates/base.html не є стандартним і його потрібно явно прописати для шаблонизатора. Для цього потрібно перейти до файлу settings.py пакета конфігурації, знайти параметр TEMPLATES та в колекції DIRS прописати шлях до каталогу templates наступним чином:
TEMPLATES =
[
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [ BASE_DIR / 'templates',
],
'APP_DIRS': True, . },
]
Все, тепер при оновленні сторінки "Про сайт" ми побачимо відображення базового шаблону.
Повернемо колишній шаблон до функцій about:
def про(request): return render(request,
'women/about.html',
{'title': 'Про сайт',
'menu': menu})
Давайте тепер загальні елементи сторінок сайту винесемо до базового шаблону base.html. Для цього я скопіюю всі файли about.html і подивимося, що тут у нас спільне. Очевидно, весь початок, включаючи відображення головного меню. А ось заголовок h1 та решту сторінки всередині тега body будемо вважати змінюваною. Тому замість тега h1 ми пропишемо спеціальний шаблонний тег block наступним чином:
{% block content %}
{% endblock %}
Тут content – це назва блоку, замість якого підставлятиметься вміст із успадкованих шаблонів.
Все, на цьому базовий шаблон у нас із вами завершено. Залишилося лише розширити його для шаблонів index.html та about.html. Спочатку перейдемо у файл index.html і найпершим рядком пропишемо ще один шаблонний тег extends:
А нижче все приберемо, крім відображення заголовка 1-го рівня та списку статей. Ця інформація повинна бути розміщена в блоці вмісту базового шаблону. Тому тут, у дочірньому нам слід перевизначити цей блок вміст наступним чином:
{% block content %}
h1>{{title}}/h1>
ul>
{% for p in posts %}
{% if p.is_published %}
li>
h2>{{p.title}}/h2>
p >{{p.content}}/p>
p >a href="">Читати пост/a>/p>
{% if
not forloop.last %}
hr>
{% endif %}
/li>
{% endif %}
{% endfor %}
/ul>
{% endblock %}
Тобто ми просто уклали в цей тег те, що має бути поміщене в блок вмісту базового шаблону.
Давайте подивимося, як це працюватиме. Перейдемо на головну сторінку сайту та бачимо повний вміст HTML-документу, який ми з вами визначили у базовому шаблоні base.html та у дочірньому index.html.
За аналогією опишемо розширення у шаблоні about.html:
{% extends 'base.html' %}
{% block content %}
h1>{{title}}/h1>
{% endblock %}
Переходимо за посиланням на сторінку «Про сайт» та бачимо повноцінну HTML-сторінку із заголовком 1-го рівня. В результаті ми з вами уникнули дублювання в окремих шаблонах і можемо досить просто визначати сторінки сайту, просто розширюючи базовий шаблон base.html.
Мітки include
Крім розширення шаблонів, можна ще робити включення одного шаблону в інший. Про що тут мова і навіщо це потрібно? Давайте уявимо, що ми хотіли б на головній сторінці нашого сайту (у шаблоні index.html) додатково відображати рубрики по відомим жінкам у вигляді наступної навігаційної панелі з посилань:
nav>
a href="#">Актриси/a> | a href="#">Співачки/a> | a href="#">Спортсменки/a>
/nav>
Причому робити це зверху перед списком, і внизу після списку. В результаті ми отримуємо дублювання фрагмента. Якраз цього уникнути, застосовується тег include, який дозволяє додавати в шаблон дані з іншого шаблону. Давайте це зробимо.
Спочатку ми створимо підкаталог includes у папці templates/women нашого проекту для кращої організації структури файлів шаблонів. Усередині каталогу includes розмістимо файл nav.html і скопіюємо в нього тег nav. А у шаблоні index.html підключимо цей файл за допомогою тега include наступним чином:
{% extends 'base.html' %}
{% block content %}
{% include 'women/includes/nav.html' %}
h1>{{title}}/h1>
ul>
{% for p in posts %}
{% if p.is_published %}
li>
h2>{{p.title}}/h2>
p >{{p.content}}/p>
p >a href="">Читати пост/a>/p>
{% if
not forloop.last %}
hr>
{% endif %}
/li>
{% endif %}
{% endfor %}
/ul>
{% include 'women/includes/nav.html' %}
{% endblock %}
Причому зробили це у двох місцях. При оновленні головної сторінки побачимо той самий результат, що раніше, але при цьому усунули дублювання фрагментів у шаблоні index.html.
Слід зазначити, що при включенні шаблон nav.html має доступ до всіх параметрів, які передаються шаблону index.html. Наприклад, у ньому можна вивести заголовок:
Якщо нам потрібно заборонити передачу змінних, то після шляху до шаблону в тезі include слід додатково прописати ключове слово only:
{% include 'women/includes/nav.html' only %}
А якщо потрібно при цьому передати окремі параметри, це можна зробити за допомогою ключового слова with наступним чином:
{% include 'women/includes/nav.html' only with title='заголовок' %}
У результаті отримуємо досить гнучкий інструмент включення фрагментів до наших шаблонів.
Відео на тему
Добрий, добрий Django із Сергієм Балакірєвим
#1. Django, що це таке? Інструментальні засоби
#2. Установка Django. Створення проекту
#3. Модель MTV. Додавання першої програми
#4. Маршрутизація та функції подання
#5. Налагодження проекту Django у Pycharm
#6. Динамічні URL-адреси. Конвертери користувача
#7. GET- та POST-запити. Оброблювачі винятків запитів
#8. Перенаправлення (redirect). Функція reverse
#9. Шаблони, початок. Функції render() та render to string()
#10. Передача даних (змінних) у шаблони
#11. Стандартні шаблонні фільтри
#12. Теги шаблонів. Теги if та for
#13. Шаблонний тег url
#14. Наслідування шаблонів (extends). Мітки include
#15. Підключення статичних файлів
#16. Користувацькі теги шаблонів. Декоратори simple_tag та inclusion_tag
#17. Що таке БД, SQL та ORM. Створення першої моделі
#18. Створення та запуск файлів міграцій
#19. Концепція CURD. Додавання записів до таблиці БД.Модуль django-extensions
#20. Методи вибору записів із таблиць. Fields lookups
#21. Сортування, зміна та видалення записів
#22. Слаги (slug) в URL-адресах. Метод get_absolute_url()
#23. Створення користувача менеджера моделі
#24. Типи зв'язків між моделями ForeignKey, ManyToManyField, OneToOneField
#25. Створення зв'язку many-to-one багато до одного (ForeignKey)
#26. ORM-команди для зв'язку many-to-one
#27. Відображення постів за рубриками
#28. Додаємо зв'язок many-to-many (багато хто до багатьох)
#29. Додавання тегів на сайт
#30. Зв'язок one-to-one (один до одного)
#31. ORM-команди з класом Q
#32. Методи вибору записів. Методи exists() та count()
#33. Клас F, Value та метод annotate()
#34. Агрегуючі функції Count, Sum, Avg, Max, Min.
#35. Угруповання записів. Обчислення за СУБД
#36. Оптимізація сайту із Django Debug Toolbar
#37. Підключення адмін-панелі. Реєстрація моделей
#38. Налаштування відображення списку статей в адмін-панелі
#39. Поля користувача та дії в адмін-панелі
#40. Панель пошуку та панель фільтрації
#41. Налаштування форми редагування записів в адмін-панелі
#42. Налаштовуємо зовнішній вигляд адмін-панелі
#43. Що таке HTML-форми? Надсилання даних по GET та POST-запитам
#44. Використання форм не пов'язаних із моделями
#45. Відображення полів форми. Збереження переданих даних у БД
#46. Валідація полів форми. Створення валідатора користувача
#47. Форми, пов'язані з моделями
#48. Завантаження файлів на сервер. Класи FileField та ImageField
#49. Завантаження файлів із використанням моделей
#50. Відображення завантажених зображень у HTML-документі та адмін-панелі
#51. Введення у CBV (Class Based Views). Класи View та TemplateView