Архив проекта: lesson-7-coolsite.zip
На предыдущем
занятии мы в целом познакомились с шаблонами в Django. Продолжим эту
тему и следующий важный шаг – это научиться подключать к шаблонам статические
файлы, например, оформление CSS или JavaScript и так далее. Здесь
есть свои тонкости. Как мы помним, наше приложение может работать в двух
режимах: отладки – на тестовом веб-сервере; эксплуатации – на реальном
веб-сервере. Так вот, в режиме отладки статические файлы Django ищет во всех
каталогах static приложений и во
всех возможных каталогах static внешних модулей (например,
админки). То есть, статические файлы при отладке совершенно спокойно можно
размещать в подкаталоге static нашего приложения. Но, в режиме
эксплуатации реальный веб-сервер будет брать все статические файлы из папки static, расположенной
в каталоге всего проекта. Но как появится такая папка со всеми необходимыми
файлами? Для этого, при подготовке проекта к эксплуатации, выполняется
специальная команда фреймворка Django:
python manage.py collectstatic
которая собирает
все статические файлы из разных приложений и модулей и помещает в одну общую
папку проекта.
Так вот, чтобы
корректно работал весь этот механизм, в пакете конфигурации необходимо
определить три константы:
- STATIC_URL – префикс URL-адреса для
статических файлов;
- STATIC_ROOT – путь к общей
статической папке, используемой реальным веб-сервером;
- STATICFILES_DIRS – список
дополнительных (нестандартных) путей к статическим файлам, используемых для
сбора и для режима отладки.
Для этого
откроем файл coolsite/settings.py и внизу уже
видим заданную константу STATIC_URL с префиксом
'/static/', который будет добавляться к URL статических
файлов. Этот префикс должен соответствовать имени папки, в которой
предполагается хранить статические файлы. Далее, определим путь к папке static всего проекта
(выделена красным) с помощью константы:
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
Наконец, при
необходимости, можем определить третью константу со списком нестандартных
путей, где также могут располагаться статические файлы:
В нашем случае
таких путей нет, поэтому список пуст.
Давайте теперь
создадим папку static в нашем приложении women и, также как и
для шаблонов, укажем в ней вложенный каталог women, чтобы не было
конфликтов имен между статическими файлами разных модулей и приложений. (В
действительности, Django просто найдет первый подходящий файл и
на этом остановится. Чтобы этот файл был тем, что нам нужен, как раз и
используется дополнительный каталог, который играет роль некоторого
пространства имен.)
В этом последнем
подкаталоге уже будем размещать файлы css – для файлов CSS; js – для файлов JavaScript; images – для общих
файлов изображений и так далее. Я создам подкаталог css для файла
стилей нашего сайта. И в нем размещу файл styles.css, который заготовил заранее,
чтобы не отвлекаться на CSS-оформление сайта, а сосредоточится на
изучении фреймворка Django. Вы сможете скачать весь этот проект с github и, при
необходимости, внимательно его изучить. Также создам подкаталог images и скопирую в
него все необходимые изображения для базового оформления сайта.
Все,
подготовительная часть завершена. Теперь мы можем использовать эти внешние
файлы в шаблонах нашего приложения. Для этого используется специальный тег static, который
сначала подключается в шаблоне:
А, затем, для
формирования URL к тому или
иному статическому файлу, используется конструкция:
{% static ' <путь к
файлу от папки static>' %}
Например, для
подключения css-файла в базовом
шаблоне base.html, следует
прописать:
<link type="text/css" href="{% static 'women/css/styles.css' %}" rel="stylesheet" />
При просмотре
страницы увидим следующий URL-адрес:
<link
type="text/css" href="/static/women/css/styles.css"
rel="stylesheet" />
И, щелкнув по
нему, убеждаемся, что он успешно загружается.
Отлично, это мы
сделали. Далее, я возьму заготовленные html-файлы для
базового шаблона страниц (base.html) и главной
страницы (index.html). Для более
детального ознакомления вы сможете их скачать по ссылке с github. Также я
добавил в БД знаменитых женщин и их биографии. Сделал это с помощью SQLiteStudio. После всех
этих изменений главная страница сайта выглядит так:
Конечно, вы
можете использовать свои шаблоны, принципиального значения это не будет иметь.
Часто для оформления сайтов используют онлайн-сервисы. Наиболее известный из
них
https://getbootstrap.com
Но я намеренно
не стал к нему обращаться, чтобы не усложнять изложение материала по Django.
Итак, на нашем
сайте выводится пока только заголовок и контент статей. Нам бы хотелось, чтобы
в списке контент выводился не полностью, а фрагментом, скажем, 50 слов или 100
символов. Как это сделать? Для таких целей в шаблонах предусмотрены специальные
фильтры, которые позволяют управлять фрагментами данных. Список всех фильтров
можно посмотреть на странице русскоязычной документации:
https://djbook.ru/rel3.0/ref/templates/builtins.html#ref-templates-builtins-filters
Использовать их
предельно просто. Смотрите, нам для правильного отображения страницы нужно,
во-первых, проставить теги абзацев при выводе постов. Это можно сделать с
помощью фильтра:
{{value|linebreaks}}
Здесь value – это некая переменная
шаблона, к которой применяется фильтр linebreaks. Этот фильтр
ставит тег перевода строки <br>, если строки в тексте следуют друг
за другом и тег абзаца <p>, если между строками имеется пустая
строка. Я добавлял текст в БД с пустыми строками, поэтому этот фильтр добавит
теги абзацев.
Конкретно, в
нашем шаблоне главной страницы index.html этот фильтр
запишется так:
<p>{{p.content|linebreaks}}</p>
Если теперь
обновить страницу, то увидим разбивку текста на абзацы. Отлично, это есть.
Следующее, что нам нужно – это ограничить размер постов в списке 50-ю словами.
За это отвечает фильтр:
{{value| truncatewords:<число слов>}}
И применим его в
нашем шаблоне следующим образом:
<p>{{p.content|linebreaks|truncatewords:50}}</p>
Смотрите, здесь
к контенту применяются сразу два фильтра: первый добавляет теги абзацев, а
второй обрезает текст до 50 слов. То есть, мы легко можем применить к переменной
множество фильтров для получения искомого результата. Обновим страницу и увидим
адекватное отображение списка актрис:
По аналогии
используются все остальные фильтры в шаблонах фреймворка Django.
В заключение я
отмечу одну важную особенность отображения информации на страницах шаблонов.
Например, если в текст статьи поместить какой-либо HTML-тег, например,
написать вначале в поле content «<h1>Анджелина
Джоли</h1>», то при
выводе мы увидим, что тег h1 был экранирован, то есть, заменен
спецсимволами. Это намеренное поведение Django с целью защиты
сайта от возможных хакерских атак. Если же нам все-таки нужно вывести статью
без экранирования тегов, то можно использовать фильтр:
{%
autoescape <on|off> %} контент {% endautoescape %}
Например, чтобы
отключить экранирование, в шаблоне index.html можем указать,
чтобы поле content выводилось как
есть со всеми тегами:
<p>
{% autoescape off %}
{{p.content|linebreaks|truncatewords:50}}
{% endautoescape %}
</p>
Вот так
используются различные фильтры в Django.