Блог на Django #16: Создание шаблонов для представлений

Итак, представления и URL-шаблоны для приложения blog были созданы. Теперь нужно добавить шаблоны для отображения постов так, чтобы их было удобно читать пользователям.

Создайте следующие директории и файлы в папке приложения blog:

blog/
  templates/ 
    blog/ 
      base.html 
      post/ 
	list.html 
	detail.html

Эта файловая структура для шаблонов. Файл base.html включает основной HTML-код сайта. В нем содержимое разделено между главной областью с контентом и сайдбаром. Файлы list.html и detail.html будут наследовать base.html для отрисовки списка постов и представления поста соответственно.

В Django есть мощный язык шаблонов, который позволяет обознаиать, как именно данные будут отображаться. Он основан на тегах, переменных и фильтрах шаблона:

  • Теги управляют рендерингом шаблона и выглядят так {% tag %}.
  • Переменные шаблона заменяются значениями при отрисовке и выглядят так {{ variable }}.
  • Фильтры позволяют изменять отображаемые переменные и выглядят так {{ variable|filter }}.

Все встроенные теги и фильтры шаблона перечислены здесь https://doc.djangoproject.com/en/2.0/ref/templates/builtins/.

Отредактируем файл base.html и добавим следующий код:

{% load static %}  
  
<!DOCTYPE html>  
<html>  
<head>  
 <title>{% block title %}{% endblock %}</title>  
 <link href="{% static 'css/blog.css' %}" rel="stylesheet">  
</head>  
<body>  
 <div id="content">  
  {% block content %}  
      {% endblock %}  
    </div>  
 <div id="sidebar">  
 <h2>My blog</h2>  
 <p>This is my blog.</p>  
 </div></body>  
</html>

{% load static %} сообщает Django, что нужно загрузить теги шаблона static, предоставленные приложением django.contrliv.staticfiles, которое можно найти в INSTALLED_APPS. После загрузки фильтр шаблон {% static %} можно использовать во всем шаблоне. С помощью фильтра можно включать статичные файлы, например файл blog.css. Он находится в коде в папке static/. Скопируйте стили из кода внизу в то же место, где хранится проект, чтобы применить стили CSS.

blog/ 
  static/ 
    css/ 
      blog.css

blog.css

* {  
    box-sizing:border-box;  
}  
  
a {  
    text-decoration: none;  
}  
  
body,  
html {  
    height: 100%;  
  margin: 0;  
}  
  
h1 {  
    border-bottom: 1px solid lightgrey;  
  padding-bottom: 10px;  
}  
  
.date,  
.info {  
    color: grey;  
}  
  
.comment:nth-child(even) {  
    background-color: whitesmoke;  
}  
  
#content,  
#sidebar {  
    display: inline-block;  
  float: left;  
  padding: 20px;  
  height: 100%;  
}  
  
#content {  
    width: 70%;  
}  
  
#sidebar {  
    width: 30%;  
  background-color: lightgrey;  
}

Также используются два тега {% block %}. Они сообщают Django, что в этой области нужно определить блок. Наследуемые шаблоны могут заполнять эти блоки контентом. С их помощью определены блоки title и content.

Отредактируем файл post/list.html, чтобы он выглядел следующим образом:

{% extends "blog/base.html" %}  
  
{% block title %}My Blog{% endblock %}  
  
{% block content %}  
  <h1>My Blog</h1>  
  {% for post in posts %}  
    <h2>  
      <a href="{{ post.get_absolute_url }}">  
       {{ post.title }}  
      </a>  
    </h2> 
    <p class="date">  
      Published {{ post.publish }} by {{ post.author }}  
    </p>  
    {{ post.body|truncatewords:30|linebreaks }}  
  {% endfor %}  
{% endblock %}

Тег шаблона {% extends %} сообщает Django, чтобы он наследовал шаблон blog/base.html. Затем контентом заполняются блоки title и content базового шаблона. Происходит перебор по постам, в результате чего отображаются их название, дата, автор и тело, включая ссылку в названии к каноническому URL поста. В теле применяются два фильтра шаблона: truncateword обрезает значение до заданного количества слов, а linebreaks конвертирует вывод в строки HTML с переносами. Можно объединять сколько угодно фильтров шаблона. Каждый будет применяться к выводу предыдущего.

Откройте терминал и выполните команду python manage.py runserver для запуска сервера разработки. Откройте https://127.0.0.1:8000/blog/ в бразуере, чтобы увидеть, как все работает. Для отображения постов здесь они должны быть со статусом Published. Появится следующее:
Отображение постов в django

Теперь нужно отредактировать файл post/detail.html:

{% extends "blog/base.html" %}  
  
{% block title %}{{ post.title }}{% endblock %}  
  
{% block content %}  
  <h1>{{ post.title }}</h1>  
  <p class="date">  
    Published {{ post.publish }} by {{ post.author }}  
  </p>  
  {{ post.body|linebreaks }}  
{% endblock %}

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

Отображение поста в django

И посмотрите на URL — его структура должны быть приблизительно такой /blog/2019/11/23/who-was-django-reinhardt/. Это значит, что ссылки подходят для SEO-оптимизации.