Добро пожаловать на еще одну лекцию, где мы не будем бояться ни HTML, ни Django. Сегодня мы поговорим о наследовании шаблонов в Django. Если у вас уже начинают всплывать в голове ассоциации с наследованием классов в Python, то вы не так уж далеки от истины. Здесь тоже используется похожий принцип "зачем писать одно и то же десять раз, если можно написать это один раз и переиспользовать". Н у что, готовы окунуться в мир base.html и шаблонов?
Зачем нужно наследование шаблонов?
Вы когда-нибудь повторяли одни и те же строки кода на нескольких страницах? Например, копировали блок <header> из одной HTML-страницы в другую? Если да, то вы точно знаете, что это не только утомительно, но еще и чревато ошибками. А как только у вас появится необходимость изменить что-то, скажем, в футере вашего проекта, придется обновлять каждые HTML-файлы вручную. Боль, страдания, слезы...
Django предлагает элегантное решение через наследование шаблонов. Суть в том, чтобы создать один базовый шаблон — нечто вроде скелета, содержащего общий каркас для всех страниц, а затем расширять его с помощью более специфичных элементов. Это полностью соответствует DRY-принципу (Don't Repeat Yourself).
Концепция наследования шаблонов
Представьте многоэтажное здание. Основа здания — это ваш базовый шаблон. Он включает такие общие элементы, как шапка (header), навигация, футер, а также всю структуру, которая одинаково выглядит на всех страницах сайта. Каждый этаж здания — это дочерний шаблон, который наследует основной каркас, но добавляет свои уникальные особенности.
Для реализации этого в Django мы используем два ключевых элемента:
{% block %}— определяет области, которые можно переопределить в дочерних шаблонах.{% extends %}— позволяет дочернему шаблону унаследовать базовый.
Создаем базовый шаблон: base.html
Для начала создадим базовый шаблон, который будет являться общей основой всех страниц нашего сайта. Пусть это будет простой скелет сайта с шапкой, навигацией и футером:
<!-- templates/base.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}My Website{% endblock %}</title>
<link rel="stylesheet" href="{% static 'styles.css' %}">
</head>
<body>
<header>
<h1>My Site</h1>
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about/">About</a></li>
<li><a href="/contact/">Contact</a></li>
</ul>
</nav>
</header>
<main>
{% block content %}
<p>Welcome to my website!</p>
{% endblock %}
</main>
<footer>
<p>© 2023 My Website</p>
</footer>
</body>
</html>
Что здесь происходит:
- Мы задали общий каркас для сайта.
- В блоке
{% block title %}содержится заголовок страницы, который может быть изменен в дочерних шаблонах. - В блоке
{% block content %}мы зарезервировали место для уникального контента каждой страницы. - CSS-файлы подключены с использованием тега
{% static %}, который вы уже видели в предыдущих лекциях.
На этом этапе, base.html пока что не делает много волшебства, но это основа всей магии наследования.
Наследование базового шаблона
Теперь создадим дочерний шаблон для конкретной страницы, например, для "О нас" (About):
<!-- templates/about.html -->
{% extends 'base.html' %}
{% block title %}About Us | My Website{% endblock %}
{% block content %}
<h2>About Us</h2>
<p>We are a small company dedicated to making the world a better place.</p>
{% endblock %}
Что здесь происходит:
{% extends 'base.html' %}указывает, что этот шаблон наследуетbase.html.- В блоке
{% block title %}мы переопределяем заголовок страницы. - В блоке
{% block content %}добавляем уникальный контент для этой конкретной страницы.
Результат? Django собирает оба шаблона: base.html и about.html, создавая полноценный HTML-документ. Обновления в base.html автоматически применяются ко всем дочерним шаблонам. Удобно? Ещё как!
Пошагово: добавляем новый шаблон с наследованием
- Создайте базовый шаблон (например,
base.html), содержащий общие элементы страницы. - Определите блоки с помощью
{% block %}, которые могут быть переопределены. - Подключите дочерний шаблон к базовому с помощью
{% extends %}. - Переопределите блоки в дочерних шаблонах для добавления уникального контента.
Использование множества блоков
Вы можете добавлять сколько угодно блоков, если это необходимо. Например:
<!-- templates/base.html -->
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}My Website{% endblock %}</title>
</head>
<body>
<header>
{% block header %}
<h1>Default Header</h1>
{% endblock %}
</header>
<main>
{% block content %}{% endblock %}
</main>
<footer>
{% block footer %}
<p>© 2023 My Website</p>
{% endblock %}
</footer>
</body>
</html>
В дочерних шаблонах вы сможете переопределить любой из блоков: title, header, content или footer.
Практика: создаем страницу "Контакты"
В рамках практики создайте шаблон contact.html, который наследует base.html. Пусть он содержит уникальный заголовок и форму для отправки сообщений. Вот подсказка:
<!-- templates/contact.html -->
{% extends 'base.html' %}
{% block title %}Contact Us | My Website{% endblock %}
{% block content %}
<h2>Contact Us</h2>
<form action="/submit-contact/" method="post">
<label for="name">Name:</label>
<input type="text" id="name" name="name">
<label for="message">Message:</label>
<textarea id="message" name="message"></textarea>
<button type="submit">Submit</button>
</form>
{% endblock %}
Типичные ошибки (и как их избежать)
Одна из самых частых ошибок — забыть указать {% extends 'base.html' %} в дочернем шаблоне. В этом случае Django просто проигнорирует базовый шаблон. Если вы получаете пустую или неожиданно странную страницу, проверьте этот момент.
Еще одна проблема — неправильно указанный блок. Например, если вы назовете блок в base.html как content, а в дочернем шаблоне будете пытаться переопределить contents, ничего не произойдет. Django строго следит за совпадением имен блоков.
Если вы получаете ошибку "TemplateDoesNotExist", убедитесь, что Django правильно настроен для поиска шаблонов. Проверьте настройку DIRS в параметре TEMPLATES вашего файла settings.py.
Зачем это нужно в реальной жизни?
В реальных веб-приложениях вы часто имеете несколько страниц с одинаковым оформлением, но разным содержанием: главная страница, блог, страница "О нас", "Контакты" и так далее. Наследование шаблонов упрощает их управление и делает ваш код более читаемым.
Кроме того, использование базового шаблона позволяет легко добавлять новые элементы на всех страницах сайта. Например, если вы добавите новый пункт в меню base.html, он появится автоматически на всех страницах.
Теперь, когда вы освоили наследование шаблонов, ваш HTML-код стал на порядок более элегантным. Используйте этот инструмент с умом, и ваш проект будет радовать не только пользователей, но и ваших коллег!
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ