Django 5 для начинающих

Прогресс по курсу:  9/1004

2.7 Шаблоны, часть 2.
4 из 16 шагов пройдено
0 из 56 баллов  получено

Расширение шаблонов НТМL-страниц на основе базового шаблона

Нередко шаблоны должны иметь одинаковую базовую структуру, одни и те же блоки, при этом определять для отдельных блоков различное содержимое. Это позволяет сформировать единообразный стиль сайта, когда веб-страницы имеют одни и те же структурные элементы - меню, хедер, футер, сайдбары и так далее.

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

Определим шаблон, который назовем base.html и расположим в папке templates:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>{% block title %}Default title{% endblock title %}</title>
</head>
<body>
    <div><a href="/">Главная</a> | <a href="/about">О нас</a></div>
    <h1>{% block header %}{% endblock header %}</h1>
    <div>{% block content %}{% endblock content %}</div>
    <div>MyCorp. 2023. All rights reserved.</div>
</body>
</html>

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

С помощью элементов {% block название_блока %} {% endblock название_блока %} определяются отдельные блоки шаблонов. При этом для каждого блока определяется открывающий элемент {% block название_блока %} и закрывающий элемент {% endblock название_блока %}.

Например, блок title:

{% block title %}Default title{% endblock title %}

Когда другие шаблоны будут применять данный шаблон, то они могут определить для блока title какое-то свое содержимое. Для каждого блока можно определить содержимое по умолчанию. Так, для блока title это строка Default title. И если другие шаблоны, которые будут использовать данный шаблон, не определят содержимое для блока title, то данный блок будет использовать строку Default title.

Подобным образом здесь определены блоки header и content. Содержимое по умолчанию для блоков определять не обязательно. Самих блоков при необходимости можно определить сколько угодно.

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

Теперь применим этот базовый шаблон. Изменим шаблон templates/blog/index.html:

{% extends "base.html" %}
{% block title %}Index{% endblock title %}
{% block header %}Главная{% endblock header %}

С помощью выражения {% extends "base.html" %} определяем, какой базовый шаблон будет расширяться. Затем определяется содержимое для блоков title и header. Стоит отметить, что необязательно указывать содержимое для всех блоков базового шаблона.

Также изменим шаблон about.html:

{% extends "base.html" %}
{% block title %}О нас{% endblock title %}
{% block header %}О нас{% endblock header %}

{% block content %}
    <p>Телефон: +12345677890</p>
    <p>Email: admin@admin.com</p>
{% endblock content %}


Этот шаблон также расширяет базовый шаблон base.html. В отличие от index.html здесь также определяется содержимое для блока content.

Таким образом, подобная функциональность позволяет нам избежать повторения одних и тех же элементов в разных шаблонах. И в то же время если нам потребуется что-то изменить, например, структуру страницы или какой-то общий элемент, то достаточно это сделать в одном файле - base.html.

Пусть в файле views.py имеются функции, которые используют эти шаблоны:

from django.shortcuts import render


def index(request):
    return render(request, "blog/index.html")


def about(request):
    return render(request, "blog/about.html")


А в файле urls.py эти функции сопоставляются с определенными маршрутами:

from django.urls import path
from blog import views

urlpatterns = [
    path("", views.index),
    path("about/", views.about),
]

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

В итоге если нам потребуется изменить структуру всех веб-страниц сайта, добавить новые элементы или убрать старые, то достаточно будет изменить один базовый шаблон.

 


  • Комментария
Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий

С Django сталкиваюсь впервые, именно этот урок достаточно тяжело понять, с учетом того, что только что изучили синтаксис вставки кода Python в html.
Местами не хватает хотя бы примитивной практики в виде ввода текста:
1. Для раздела 2.3 можно сделать практику в виде ввода команд в терминал (runserver, django-admin и т.д)
2. Для раздела 2.5 можно добавить не только создание паттернов в urls.py, но и работу в views.py, где мы создаем с нуля функции для редиректов
3. Для раздела 2.6 можно также добавить практику в виде:
Как вывести в тэге <p> значение по какому-либо условию при следующих входных данных x=... y=...?
Как создать список в шаблоне из значений в листе example_list?
Как вставить комментарий в виде одной строки?

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

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

Изменен Ильдар Хайруллин

@Ильдар_Хайруллин, спасибо, мы всегда положительно относимся к любой критике и стараемся улучшать курс с учётом предложений и замечаний учащихся. Ваши предложения вполне здравые, постараемся сделать такие задачи, так-же будут добавлены и другие задачи.

Тут я так понимаю должно быть указано "about/" ?

Так как при таком вызове работать правильно не будет:

@Максим_Михеев, Спасибо, исправил. Вашей внимательности можно позавидовать)

Что значит эта ошибка ? С about выводит правильно, а тут такое 

@Дмитрий_Чекмасов, Проверяйте код шаблона templates/blog/index.html, скорее всего в нем ошибка.

@Илья_Перминов, можно тогда уточнить где именно надо было сделать изменения? Не совсем понятно, в теле body ?

@Дмитрий_Чекмасов, Можете прислать сюда содержимое шаблона templates/blog/index.html.

@Илья_Перминов

@Дмитрий_Чекмасов, в этом файле должны быть только эти три строки:

{% extends "base.html" %}
{% block title %}Index{% endblock title %}
{% block header %}Главная{% endblock header %}

@Дмитрий_Селезнев, я понял в чем было дело - я некоторый код, который раньше писали не удалял, а пытался закомментировать его так же как в питоне, поэтому и не работало. А так и такой вариант тоже работает

@Дмитрий_Чекмасов, такой вариант работает не правильно, посмотрите html-код страницы:

@Дмитрий_Селезнев, ну я имел в виду то, что показывает то что нужно в данном уроке

@Дмитрий_Чекмасов, только частично - заголовок у страницы не правильный - Учу Django, а должен быть Index.

@Дмитрий_Селезнев, да, но можно убрать теги <head>  и будет Index ) ну в общем, не буду спорить что код не совсем правильный, но при необходимости в каких-то случаях он может дать похожий результат