Шаг 2. Создание приложения Flask с представлениями и шаблонами страниц
Предыдущий шаг. Руководство (шаг 1). Начало работы с веб-платформой Django в Visual Studio
В шаге 1 этого руководства вы создали приложение Flask с одной страницей и всем кодом в одном файле. Для дальнейшей разработки рекомендуется выполнить рефакторинг кода и создать структуру для шаблонов страниц. В частности, отделить код для представлений приложения от других аспектов, таких как код запуска.
На этом шаге вы научитесь делать следующее:
- рефакторинг кода приложения для разделения представлений и кода запуска (шаг 2.1);
- преобразование представления с помощью шаблона страницы (шаг 2.2).
Шаг 2.1. Рефакторинг проекта для поддержки дальнейшей разработки
В коде, созданном с помощью шаблона "Пустой веб-проект Flask", у вас есть один файл app.py, содержащий код запуска наряду с одним представлением. Для дальнейшей разработки приложения с несколькими представлениями и шаблонами будет лучше разделить эти аспекты.
В папке проекта создайте папку приложения с именем
HelloFlask
(щелкните правой кнопкой мыши проект в обозревателе решений и выберите Добавить>Новая папка.)В папке HelloFlask создайте файл с именем __init__.py и со следующим содержимым, которое создает экземпляр
Flask
и загружает представления приложения (которые будут созданы на следующем шаге):from flask import Flask app = Flask(__name__) import HelloFlask.views
В папке HelloFlask создайте файл с именем views.py со следующим содержимым. Имя views.py важно, так как вы использовали
import HelloFlask.views
в __init__.py; если имена не будут совпадать, во время выполнения возникнет ошибка.from flask import Flask from HelloFlask import app @app.route('/') @app.route('/home') def home(): return "Hello Flask!"
Помимо переименования функции и маршрутизации в
home
, этот код содержит код отрисовки страницы из app.py и импортирует объектapp
, объявленный в __init__.py.Создайте вложенную папку в HelloFlask с именем templates, которая пока остается пустой.
В корневой папке проекта переименуйте файл app.py в runserver.py и сделайте так, чтобы содержимое совпадало со следующим кодом:
import os from HelloFlask import app # Imports the code from HelloFlask/__init__.py if __name__ == '__main__': HOST = os.environ.get('SERVER_HOST', 'localhost') try: PORT = int(os.environ.get('SERVER_PORT', '5555')) except ValueError: PORT = 5555 app.run(HOST, PORT)
Структура проекта должна выглядеть следующим образом:
Выберите Отладка>Начать отладку (F5) или нажмите кнопку Веб-сервер на панели инструментов (браузер может отличаться), чтобы запустить приложение и открыть браузер. Попробуйте оба маршрута URL-адресов: / и/home.
Также можно установить точки останова в разных частях кода и перезапустить приложение для выполнения последовательности запуска. Например, задайте точку останова в первых строках runserver.py и *HelloFlask_*init_.py и в строке
return "Hello Flask!"
в views.py. Затем перезапустите приложение (Отладка>Перезапуск, CTRL+SHIFT+F5 или нажмите кнопку панели инструментов, показанную ниже) и запустите пошаговое выполнение кода (F10) или выполнение из каждой точки останова, нажав клавишу F5.По завершении остановите приложение.
Фиксация в системе управления версиями
После внесения изменений в код и их успешного тестирования можно просмотреть и зафиксировать изменения в системе управления версиями. В дальнейших шагах, когда вы получите напоминание о повторной фиксации изменений в системе управления версиями, вам будет необходимо вернуться к этому разделу.
Нажмите кнопку изменений в нижней части Visual Studio (выделена кружком ниже), чтобы перейти к Team Explorer.
В Team Explorer введите сообщение фиксации, например "Рефакторинг кода", и выберите Зафиксировать все. После завершения фиксации появится сообщение Фиксация <хэш> создана локально. Выполните синхронизацию, чтобы отправить изменения на сервер. Если вы хотите отправить изменения в удаленный репозиторий, выберите Синхронизировать, а затем нажмите Отправить в разделе Исходящие фиксации. Кроме того, вы можете накапливать несколько локальных фиксаций перед отправкой в удаленный репозиторий.
Вопрос. Как часто следует выполнять фиксации в системе управления версиями?
Ответ. При фиксации изменений в системе управления версиями создается запись в журнале изменений и точка, к которой можно вернуть репозиторий при необходимости. Кроме того, в каждой фиксации можно проверить конкретные изменения. Поскольку фиксации в Git стоят недорого, рекомендуется чаще выполнять фиксации, а не накапливать большое число изменений в одной фиксации. Фиксировать каждое небольшое изменение в отдельном файле тоже не стоит. Обычно фиксация выполняется при добавлении возможности, изменении структуры (как в этом шаге) или осуществлении некоторого рефакторинга кода. Кроме того, рекомендуется обсудить частоту и условия фиксаций с другими участниками команды.
Не стоит путать частоту фиксации и частоту отправки фиксаций в удаленный репозиторий. Несколько фиксаций можно накапливать в локальном репозитории перед отправкой в удаленный репозиторий. Частота фиксаций зависит от решения, принятого командой в отношении управления репозиторием.
Шаг 2.2. Использование шаблона для отображения страницы
Функция home
в views.py создает только ответы HTTP в простом текстовом формате для страницы. Тем не менее большинство реальных веб-страниц предоставляют ответы с большим количеством страниц HTML, которые часто содержат фактические данные. Основной причиной для определения представления с помощью функции является возможность создавать содержимое динамически.
Поскольку возвращаемое значение для представления — просто строка, можно создать любой нужный код HTML в строке, используя динамическое содержимое. Тем не менее, поскольку рекомендуется разделять разметку и данные, лучше разместить разметку в шаблоне и хранить данные в коде.
Для начинающих разработчиков рекомендуется изменить файл views.py так, чтобы он содержал следующий код, который использует встроенный HTML-код для страницы с некоторым динамическим содержимым:
from datetime import datetime from flask import render_template from HelloFlask import app @app.route('/') @app.route('/home') def home(): now = datetime.now() formatted_now = now.strftime("%A, %d %B, %Y at %X") html_content = "<html><head><title>Hello Flask</title></head><body>" html_content += "<strong>Hello Flask!</strong> on " + formatted_now html_content += "</body></html>" return html_content
Запустите приложение и обновите страницу несколько раз, чтобы увидеть, что дата и время обновляются. По завершении остановите приложение.
Чтобы преобразовать механизм отрисовки страницы для использования шаблона, создайте файл с именем index.html в папке templates со следующим содержимым, где
{{ content }}
— заполнитель или маркер заполнителя (также называется переменной шаблона), для которого необходимо указать значение в коде:<html> <head> <title>Hello Flask</title> </head> <body> {{ content }} </body> </html>
Измените функцию
home
так, чтобы она использовалаrender_template
для загрузки шаблона, и укажите значение для свойства content, для чего требуется указать именованный аргумент, соответствующий имени заполнителя. Flask автоматически выполняет поиск шаблонов в папке templates, поэтому путь к шаблону указывается относительно этой папки:def home(): now = datetime.now() formatted_now = now.strftime("%A, %d %B, %Y at %X") return render_template( "index.html", content = "<strong>Hello, Flask!</strong> on " + formatted_now)
Запустите приложение и просмотрите результаты. Обратите внимание, что встроенный HTML-код в значении
content
не преобразуется как HTML, так как модуль шаблонов (Jinja) автоматически экранирует HTML-содержимое. Автоматическое экранирование предотвращает случайные уязвимости к атакам путем внедрения кода. Разработчики часто собирают входные данные с одной страницы и используют их в качестве значения на другой странице с помощью заполнителя шаблона. Экранирование служит напоминанием о том, что HTML-код не рекомендуется хранить в коде.Соответственно, просмотрите файл templates\index.html, чтобы задать четкие заполнители для каждой части данных в разметке:
<html> <head> <title>{{ title }}</title> </head> <body> <strong>{{ message }}</strong>{{ content }} </body> </html>
Затем обновите функцию
home
для предоставления значений для всех заполнителей:def home(): now = datetime.now() formatted_now = now.strftime("%A, %d %B, %Y at %X") return render_template( "index.html", title = "Hello Flask", message = "Hello, Flask!", content = " on " + formatted_now)
Запустите приложение еще раз и просмотрите правильно выведенные данные.
Вы можете зафиксировать изменения в системе управления версиями и обновить удаленный репозиторий. Дополнительные сведения см. в разделе Шаг 2-1.
Вопрос. Следует ли хранить шаблоны страницы в отдельном файле?
Ответ. Хотя шаблоны обычно хранятся в отдельных HTML-файлах, вы также можете использовать встроенный шаблон. Чтобы сохранить четкое разделение между исправлением и кодом, рекомендуется использовать отдельный файл.
Вопрос. Следует ли использовать в шаблонах расширение файлов HTML?
Ответ. Использовать расширение HTML для файлов шаблона страницы совсем необязательно, так как вы всегда можете определить точный относительный путь к файлу в первом аргументе функции render_template
. Однако Visual Studio (и другие редакторы) обычно предоставляет такие функции, как завершение кода или разметка синтаксиса, для файлов HTML, что значительно важнее того, что шаблоны страниц не имеют формата HTML.
При работе с проектом Flask Visual Studio автоматически определяет, является ли HTML-файл, который вы редактируете, шаблоном Flask, и предоставляет несколько функций с автоматическим завершением. Например, когда вы начинаете вводить комментарий шаблона страницы Flask, {#
, Visual Studio автоматически предоставляет вам закрывающие символы #}
. В командах Закомментировать выделенный фрагмент и Раскомментировать выделенный фрагмент (в меню Изменить>Дополнительно или на панели инструментов) также используются комментарии шаблона, а не HTML.
Вопрос. Можно ли поместить шаблоны в дополнительные вложенные папки?
Ответ. Да, можно использовать вложенные папки и ссылаться на относительный путь в templates в вызовах render_template
. Это позволяет эффективно создавать пространства имен для шаблонов.
Следующие шаги
Дополнительные подробности
- Flask Quickstart - Rendering Templates (Краткое руководство по Flask — отрисовка шаблонов) (flask.pocoo.org)
- Исходный код, используемый в руководстве, на сайте GitHub: Microsoft/python-sample-vs-learning-flask