Поделиться через


Шаг 3. Обслуживание статических файлов, добавление страниц и использование наследования шаблонов с приложением Django

Предыдущий шаг. Руководство (шаг 2). Создание приложения Django с представлениями и шаблонами страниц

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

На этом шаге вы научитесь делать следующее:

  • с помощью шаблонов элементов Visual Studio быстро добавлять новые файлы различных типов с удобным стереотипным кодом (шаг 3.1);
  • настраивать проект Django для обработки статических файлов (шаг 3–2),
  • добавлять дополнительные страницы в приложение (шаг 3–3);
  • использовать наследование шаблона для создания заголовка и панели навигации, которая используется на разных страницах (шаг 3–4).

Шаг 3–1. Знакомство с шаблонами элементов

По мере разработки приложения Django обычно добавляется множество файлов Python, HTML, CSS и JavaScript. Для каждого типа файла (а также таких файлов, как web.config, которые могут понадобиться при развертывании) Visual Studio предоставляет удобные шаблоны элементов для начала работы.

Чтобы просмотреть доступные шаблоны, перейдите в Обозреватель решений, щелкните правой кнопкой мыши папку, в которой нужно создать элемент, и выберите Добавить>Новый элемент.

Add new item dialog in Visual Studio.

Чтобы использовать шаблон, выберите желаемый шаблон, укажите имя файла и нажмите Добавить. При добавлении элемента таким образом автоматически добавляется файл в проект Visual Studio и отмечает изменения для системы управления версиями.

Вопрос. Как Visual Studio определяет, какой шаблон элемента предложить?

Ответ. Файл проекта Visual Studio (PYPROJ) содержит идентификатор типа проекта, который помечает его как проект Python. Visual Studio использует идентификатор типов, чтобы отображать только шаблоны элементов, подходящие для типа проекта. Таким образом Visual Studio может предоставить обширный набор шаблонов элементов для множества типов проектов без необходимости каждый раз запрашивать их сортировку.

Шаг 3–2. Обработка статических файлов из приложения

В веб-приложении, созданном на Python (при помощи любой платформы), файлы Python всегда выполняются на сервере веб-узла. Файлы Python никогда не передаются на компьютер пользователя. Другие файлы, такие как файлы CSS и JavaScript, используются исключительно браузером. Поэтому, когда они запрашиваются, сервер узла просто доставляет их в исходном виде. Такие файлы называются статическими файлами, Django может доставлять их автоматических без необходимости написания кода.

По умолчанию в проекте Django настроена обработка статических файлов из папки приложения static с помощью следующих строк в файле settings.py проекта Django:

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/

STATIC_URL = '/static/'

STATIC_ROOT = posixpath.join(*(BASE_DIR.split(os.path.sep) + ['static']))

Файлы в папке static можно систематизировать с помощью любой предпочитаемой структуры папок, а затем ссылаться на них с помощью относительных путей в этой папке. Попробуйте это сделать: следуйте описанным ниже шагам, чтобы добавить CSS-файл в приложение и использовать таблицу стилей в шаблоне index.html:

  1. В обозревателе решений в проекте Visual Studio щелкните папку HelloDjangoApp правой кнопкой мыши, выберите Добавить>Новая папка и назовите папку static.

  2. Щелкните папку static правой кнопкой мыши и выберите Добавить>Новый элемент. В появившемся диалоговом окне выберите шаблон Таблица стилей, укажите имя файла site.css и нажмите Добавить.

    Add new item dialog for static file.

    Файл site.css появится в проекте и откроется в редакторе. Структура папок должна походить на изображенную ниже:

    Static file structure as shown in Solution Explorer.

  3. Замените содержимое файла site.css следующим кодом и сохраните файл:

    .message {
        font-weight: 600;
        color: blue;
    }
    
  4. Замените содержимое файла templates/HelloDjangoApp/index.html приложения следующим кодом. Этот код заменяет использованный на шаге 2 элемент <strong> на <span>, который ссылается на класс стилей message. Использование класса стилей обеспечивает большую гибкость при задании стиля элемента. (Если вы не переместили файл index.html во вложенную папку в templates и используете VS 2017 версии 15.7 или более ранних, ознакомьтесь с пунктом о пространстве имен шаблонов на шаге 2–4.)

    <html>
        <head>
            <title>{{ title }}</title>
            {% load static %} <!-- Instruct Django to load static files -->
            <link rel="stylesheet" type="text/css" href="{% static 'site.css' %}" />
        </head>
        <body>
            <span class="message">{{ message }}</span>{{ content }}
        </body>
    </html>
    
  5. Запустите проект для просмотра результатов. После его завершения остановите сервер и при необходимости зафиксируйте изменения в системе управления версиями (как описано в шаге 2).

Вопрос. Какое назначение у тега {% load static %}?

Ответ. Строка {% load static %} необходима для ссылки на статические файлы в таких элементах, как <head> и <body>. В примере, показанном в этом разделе, под "статическими файлами" понимается набор пользовательских тегов шаблонов Django, который позволяет ссылаться на статические файлы с помощью синтаксиса {% static %}. Без {% load static %} при выполнении приложения отобразится исключение.

Вопрос. Существуют ли соглашения для организации статических файлов?

Ответ. В папку static можно добавить дополнительные файлы CSS, JavaScript и HTML любым предпочитаемым образом. Типичный способ организации статических файлов — это создание вложенных папок fonts, scripts и content (для таблиц стилей и других файлов). Вне зависимости от выбранной структуры не забудьте включить эти папки в относительный путь к файлу в ссылках {% static %}.

Вопрос. Можно ли выполнить эту задачу без использования тега {% load static %}?

Ответ: Да, вы можете.

<html>
    <head>
        <title>{{ title }}</title>
        <link rel="stylesheet" type="text/css" href="../../static/site.css" />
    </head>
    <body>
        <span class="message">{{ message }}</span>{{ content }}
    </body>
</html>

Шаг 3–3. Добавление страницы в приложение

Добавление дополнительной страницы в приложение потребует следующих действий:

  • добавление функции Python, которая определяет представление;
  • добавление шаблона для исправления страницы;
  • добавление необходимой маршрутизации в файл urls.py проекта Django.

В следующих шагах описано добавление в проект "HelloDjangoApp" страницы "Дополнительные сведения" и создание ссылки на нее с домашней страницы:

  1. В Обозревателе решений щелкните правой кнопкой мыши папку templates/HelloDjangoApp. Нажмите Добавить>Новый элемент и выберите шаблон элемента HTML-страница. Присвойте файлу имя about.html и нажмите Добавить.

    Add new item dialog for about file.

    Совет

    Если в меню Добавить отсутствует команда Новый элемент, убедитесь, что вы остановили сервер, чтобы служба Visual Studio вышла из режим отладки.

  2. Замените содержимое файла about.html следующей разметкой (в шаге 3–4 вы замените явную ссылку на домашнюю страницу простой панелью навигации):

    <html>
        <head>
            <title>{{ title }}</title>
            {% load static %}
            <link rel="stylesheet" type="text/css" href="{% static 'site.css' %}" />
        </head>
        <body>
            <div><a href="home">Home</a></div>
            {{ content }}
        </body>
    </html>
    
  3. Откройте файл views.py приложения и добавьте функцию с именем about, которая использует шаблон:

    def about(request):
        return render(
            request,
            "HelloDjangoApp/about.html",
            {
                'title' : "About HelloDjangoApp",
                'content' : "Example app page for Django."
            }
        )
    
  4. Откройте файл urls.py проекта Django и добавьте следующую строку в массив urlPatterns:

    re_path(r'^about$', HelloDjangoApp.views.about, name='about'),
    
  5. Откройте файл templates/HelloDjangoApp/index.html и добавьте следующую строку перед элементом <body>, чтобы создать ссылку на страницу "Дополнительные сведения" (в шаге 3–4 вы замените эту ссылку панелью навигации):

    <div><a href="about">About</a></div>
    
  6. Сохраните все файлы с помощью команды меню Файл>Сохранить все или просто нажмите клавиши CTRL+SHIFT+S. (Технически этот шаг не требуется, так как при запуске проекта в Visual Studio файлы сохраняются автоматически. Однако об этой команде лучше знать.)

  7. Запустите проект, чтобы просмотреть результаты и проверить постраничную навигацию. После завершения закройте сервер.

Ответ. Несмотря на то что функция представления в файле views.py называется index, шаблоны маршрутизации URL-адресов в файле urls.py проекта Django не содержат регулярных выражений, которые совпадают со строкой "index". Чтобы выполнить сопоставление со строкой, вам понадобится дополнительная запись для шаблона ^index$.

Как показано в следующем разделе, для ссылки на имя шаблона в шаблоне страницы оптимально использовать тег {% url '<pattern_name>' %}. В таком случае Django создаст корректный URL-адрес. Например, замените <div><a href="home">Home</a></div> в about.html на <div><a href="{% url 'index' %}">Home</a></div>. Использование index работает, потому что первый шаблон URL-адреса в urls.py называется index (из-за аргумента name='index'). Вы также можете использовать home для обозначения второго шаблона.

Шаг 3–4. Использование наследования шаблона для создания заголовка и навигационной панели

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

Система шаблонов Django предоставляет два способа повторного использования определенных элементов в нескольких шаблонах: включение и наследование.

  • Включение. Это другие шаблоны страниц, которые вставляются в определенное место в ссылочном шаблоне, используя синтаксис {% include <template_path> %}. Чтобы динамически изменять путь в коде, можно воспользоваться переменной. Включения используются в основной части страницы для извлечения общего шаблона в конкретном расположении на странице.

  • Наследование. В начале шаблона страницы используется {% extends <template_path> %} для определения общего базового шаблона, на основе которого затем создается ссылочный шаблон. Наследование обычно используется для определения общего макета, панели навигации и других структур для страниц приложения, так чтобы ссылающиеся на них шаблоны могли только добавлять или изменять определенные области базового шаблона, называемые блоками.

В обоих случаях <template_path> относится к папке templates приложения (../ или ./ также разрешены).

Базовый шаблон отделяет блоки с помощью тегов {% block <block_name> %} и {% endblock %}. Если ссылающийся на него шаблон использует теги с тем же именем блока, содержимое его блока переопределяет содержимое базового шаблона.

Далее демонстрируется наследование:

  1. В папке приложения templates/HelloDjangoApp создайте новый HTML-файл. Щелкните правой кнопкой мыши папку templates/HelloDjangoApp, нажмите Добавить>Новый элемент и выберите шаблон элемента HTML-страница. Присвойте файлу имя layout.html и нажмите Добавить.

    Add new item dialog for layout file.

  2. Замените содержимое файла layout.html следующей разметкой. Обратите внимание, что в этом шаблоне содержится блок под названием "content", который необходимо заменить для всех страниц, на которые создается ссылка:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <title>{{ title }}</title>
        {% load static %}
        <link rel="stylesheet" type="text/css" href="{% static 'site.css' %}" />
    </head>
    
    <body>
        <div class="navbar">
           <a href="/" class="navbar-brand">Hello Django</a>
           <a href="{% url 'home' %}" class="navbar-item">Home</a>
           <a href="{% url 'about' %}" class="navbar-item">About</a>
        </div>
    
        <div class="body-content">
    {% block content %}{% endblock %}
            <hr/>
            <footer>
                <p>&copy; 2018</p>
            </footer>
        </div>
    </body>
    </html>
    
  3. Добавьте следующие стили в файл static/site.css приложения (в этом пошаговом руководстве мы не пытаемся продемонстрировать гибкость дизайна; эти стили просто позволяют получить интересные результаты):

    .navbar {
        background-color: lightslategray;
        font-size: 1em;
        font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
        color: white;
        padding: 8px 5px 8px 5px;
    }
    
    .navbar a {
        text-decoration: none;
        color: inherit;
    }
    
    .navbar-brand {
        font-size: 1.2em;
        font-weight: 600;
    }
    
    .navbar-item {
        font-variant: small-caps;
        margin-left: 30px;
    }
    
    .body-content {
        padding: 5px;
        font-family:'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    }
    
  4. Измените файл templates/HelloDjangoApp/index.html , чтобы ссылаться на базовый шаблон и сделать его пригодным для использования на странице. Добавьте следующую строку в строку 1 на HTML-странице (над html-тегом):

    {% extends "HelloDjangoApp/layout.html" %}
    
  5. Вы увидите, что с помощью наследования этот шаблон становится простым для реализации в теге текста для переопределения блока содержимого:

    {% block content %}
    <span class="message">{{ message }}</span>{{ content }}
    {% endblock %}
    
  6. Измените файл templates/HelloDjangoApp/about.html таким же образом, чтобы сделать шаблон макета доступным. Добавьте ту же строку из шага 1 на HTML-странице (над html-тегом):

    {% extends "HelloDjangoApp/layout.html" %}
    
  7. Затем, используя наследование, реализуйте шаблон в теге основного текста, чтобы переопределить блок содержимого:

    {% block content %}
    {{ content }}
    {% endblock %}
    
  8. Запустите сервер для просмотра результатов. После завершения закройте сервер.

    Running app showing the nav bar.

  9. Так как в приложение были внесены значительные изменения, самое время зафиксировать изменения в системе управления версиями.

Следующие шаги

Дополнительные подробности