Flask: различия между версиями

Содержимое удалено Содержимое добавлено
м пунктуация
Строка 1:
Flask - является микрофреймворком для создания вебсайтов на языке Python. В основу статьи положен перевод из официальной документации Flask. Поэтому в ней имеется обращение от первого лица, то есть от создателя фреймворка Армина Ронахера.<br>
 
Flask в данном контексте переводится как пороховой рожок, на это указывает официальное лого.
= Вводное слово =
 
== Что значит "«микро"»? ==
На мой взгляд "«микро"» в фреймворке относится не только к простоте и небольшому размеру базы, но это также может означать тот факт, что он не предлагает вам много проектных решений. Несмотря на то, что Flask использует нечто подобное ввиде шаблонизатора, мы не будем принимать подобные решения для вашего хранилища данных или других частей. Тем не менее, для нас термин "«микро"» не означает, что вся реализация должна вписываться в один файл.
<br /><br />
Одним из проектных решений во Flask является то, что простые задачи должны быть простыми; они не должны занимать много кода, и это не должно ограничивать вас. Поэтому мы сделали несколько вариантов дизайна, некоторые люди могут посчитать это удивительным и не общепринятым. Например, Flask использует локальные треды внутри объектов, так что вы не должны передавать объекты в пределах одного запроса от функции к функции, оставаясь в безопасном треде. Хотя это очень простой подход и позволяет сэкономить много времени, это также может вызвать некоторые проблемы для очень больших приложений, поскольку изменения в этих локальных тредах-объектов может произойти где угодно в том же треде. Для того, чтобы решить эти проблемы, мы не скрываем от вас локальные треды-объекты, вместо этого охватываем их и предоставляем вам много инструментов, чтобы сделать работу с ними настолько приятным насколько это возможно.
<br /><br />
Во Flask много вещей предварительно сконфигурированы, на основе общей базовой конфигурации. Например, шаблоны и статические файлы сохранены в подкаталогах в пределах исходного дерева. Вы также можете изменить это, но обычно вам этого не потребуется.
<br /><br />
Основная причина почему Flask называется “микрофреймворком” -«микрофреймворком» — это идея сохранить ядро простым, но расширяемым. В нем нет абстрактного уровня базы данных, нет валидации форм или всего такого, что уже есть в других библиотеках к которым вы можете обращаться. Однако Flask поддерживает расширения, которые могут добавить необходимую функциональность и имплеминтирует их так, как будто они уже были встроены изначально. В настоящее время уже есть расширения: формы валидации, поддержка закачки файлов, различные технологии аутентификации и многие другие.
 
== Безопасность ==
Строка 15 ⟶ 17 :
 
== Статус насчет Python 3 ==
Werkzeug и Flask будут портированы на Python 3. Мы обеспечим вас необходимыми подсказками, как модернизировать ваши приложения для третьей версии. В настоящий момент мы настоятельно рекомендуем разрабатывать под версиями 2.6 и 2.7 с активированными предупреждениями Python 3. Если Вы планируете в скором времени перейти на третью версию, мы рекомендуем прочитать [http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/ "«Как написать код, совместимый с Python3"»]
 
= Установка =
Имеются две зависимости:<br />
Jinja2 - — движок темплейтов<br />
Werkzeug - — набор инструментов WSGI, стандартного интерфейса Python для развертывания веб-приложений и взаимодействия между ними и различными серверами разработки.<br />
Virtualenv - — не является зависимостью. Это инструмент, который призван решить проблему обратной совместимости. Вы можете использовать различные версии Python или версии библиотек, это может вызвать конфликт зависимостей. Virtualenv решает эту проблему, создает изолированную среду для каждого проекта.
 
== Под Windows ==
Запустить командную строку cmd<br />
Проще всего установить при помощи скрипта easy_install. В командной строке должно получиться что-то вроде этого:<br />
<code>C:\Python27\python.exe C:\Python27\Scripts\easy_install-2.7-script.py Flask</code><br />
Установка зависимостей:<br />
<code>C:\Python27\python.exe C:\Python27\Scripts\easy_install-2.7-script.py Jinja2</code><br />
<code>C:\Python27\python.exe C:\Python27\Scripts\easy_install-2.7-script.py Werkzeug</code><br />
<code>C:\Python27\python.exe C:\Python27\Scripts\easy_install-2.7-script.py Virtualenv</code>
 
== Установка под Mac OSx ==
В терминале написать
<code>sudo easy_install Flask</code><br />
Установка зависимостей<br />
<code>sudo easy_install Jinja2</code><br />
<code>sudo easy_install Werkzeug</code><br />
<code>sudo easy_install Virtualenv</code><br />
 
= Краткая документация =
 
== Простейший Hello world ==
Создадим файл hello.py следующего содержания:
Строка 53 ⟶ 58 :
</source>
 
Проверим как установился Flask. Запустим скрипт:<br />
<code>C:\Python27\python.exe hello.py</code><br />
Наберите в браузере в адресной строке http://localhost:5000/ и увидите надпись Hello World!
 
 
== Разбор программы Hello world! ==
Рассмотрим, как работает программа, которую вы запустили выше:<br />
# Сначала мы импортируем Flask класс. Экземпляр этого класса будет нашим WSGI приложением. Первым аргументом является имя модуля приложения. Если вы используете один модуль (как в данном примере), вы должны использовать __name__, потому что в зависимости от того, было ли это начато как приложение или как импорт модуля, название будет другим ('__main__' по сравнению с реальным именем импорта).
# Далее мы создаем экземпляр этого класса. Мы передаем ему имя модуля или пакета. Это необходимо, так как Flask не знает, где искать шаблоны, статические файлы, и так далее.
# Затем мы используем route(). Декоратор говорит Flask, что URL должен вызывать нашу функцию.
# Функция задает имя, которое также используется для создания URL-адресов для этой функции, и возвращает сообщение, что мы хотим отобразить в браузере пользователя.
# Наконец, мы используем run() функцию для запуска локального сервера с нашим приложением. Условие __name__ == "«__main__"» означает, что сервер работает только в том случае, если скрипт выполняется непосредственно из Python интерпретатора и не используется в качестве импортированного модуля.
 
== Общедоступный сервер ==
Строка 74 ⟶ 79 :
 
Это говорит вашей операционной системе слушать все ip.
 
== Режим отладки ==
Run() метод хорош для начала разработки на локальном сервере. Однако вам потребуется перезапускать сервер вручную после каждого изменения в коде. Это не очень красиво и Flask может сделать лучше. Если вы включите Debug Mode, сервер сам будет перегружаться после каждого изменения в коде, и это также даст вам полезный отладчик, если что-то пойдет не так.<br />
Есть два способа включить режим отладки:<br />
<code>app.debug = True<br>
app.run()</code><br />
Или<br />
<code>app.run(debug=True)</code><br />
Оба метода дадут одинаковый эффект
 
'''Внимание'''<br />
Несмотря на то, что интерактивный отладчик не работает в разветвленной среде (что делает его практически невозможным в использовании на производственных серверах), он все же позволяет выполнить произвольной код. Это делает его одним из основных рисков в безопасности, и поэтому он никогда не должен быть использован на производственных машинах.
 
== Маршрутизация ==
Современные веб-приложения имеют красивые URL. Это помогает людям помнить их, особенно это удобно для приложений, которые используются в мобильных устройствах с медленным сетевым подключением. Если пользователь может попасть на страницу через URL минуя главную страницу, то более вероятно, что он вернется в следующий раз.<br />
Как вы видели выше, декоратор route() используется для связывания функций с URL. Вот несколько основных примеров:
<source lang="python">
Строка 131 ⟶ 137 :
 
=== Уникальные линки и редирект ===
Линки во Flask основаны на базе модуля маршрутизации от Werkzeug. Идея этого модуля заключается в обеспечении красивых и уникальных URL-адресов на основе правил ранее сформировавшихся в Apache и в HTTP серверах.<br />
Используйте два правила:
<source lang="python">
Строка 138 ⟶ 144 :
return 'The project page'
</source>
<br />
<source lang="python">
@app.route('/about')
Строка 144 ⟶ 150 :
return 'The about page'
</source>
Хоть эти примеры и выглядят очень похоже, они различаются по слэшу в конце URL. В первом случае, доступ без слэша вызывает редирект на канонические URL с обратным слэшем.<br />
Во втором случае, без обратного слэша, URL определяется, как путь к файлу на UNIX-подобных системах. Доступ к URL со слэшем будет перенаправляться на ошибку 404 "«не найдено"».<br />
Такое поведение позволяет пользователям получить доступ к странице, даже если они забыли ввести в конце обратный слэш. Кроме того, URL-адрес будет оставаться уникальным, и это поможет поисковым системам избегать повторного индексирования страницы.
 
Строка 175 ⟶ 181 :
Здесь также используется метод test_request_context(), который объяснен ниже. Он говорит Flask, как нужно обрабатывать запрос, даже если мы взаимодействуем через шел Python. Почему мы используем построение URL вместо их жесткого задания в шаблонах? На то есть три хорошие причины:
* Реверсирование, зачастую является более описательным методом и позволяет изменять URL на одном дыхании.
* Автоматическое экранирование специальных символов, уникода. Вам даже не придется задумываться над этим.
* Если ваше приложение находится вне корневой URL (например, /myapplication вместо /), функция url_for () будет это правильно обрабатывать для вас.
 
Строка 188 ⟶ 194 :
show_the_login_form()
</source>
Если присутствует GET, тогда HEAD будет добавлен автоматически. Вам не нужно об этом заботиться. Также будьте уверены, что HEAD поддерживает HTTP RFC зависимости, так что вы можете полностью игнорировать HTTP спецификации.<br />
Если вы ничего не знаете про HTTP методы, приводим небольшую справку:
* GET<br />
Браузер сообщает серверу, что желает получить информацию со страницы и просит отправить ее. Возможно, это самый распространенный метод.
* HEAD<br />
Браузер сообщает серверу, что желает получить информацию, но интересуется только заголовком, а не содержанием страницы. Приложение допускает запрос, в случае если GET был получен.
* POST<br />
Браузер сообщает серверу, что хочет запостить новую информацию по данному URL и сервер должен быть уверен, что сохранит ее и сделает один раз. Так обычно передается информация из HTML форм на сервер.
* PUT<br />
Очень схоже с POST, но сервер может инициировать сохранение информации несколько раз, переписывая старые значения более одного раза. Вы можете задаться вопросом: "«Для чего это нужно?"». Есть несколько хороших причин, чтобы делать это таким образом. Учтите, что соединение может быть потеряно во время передачи: в этой ситуации система между браузером и сервером может затребовать передачу во второй раз. С POST это невозможно, так как запрос возможен только один раз.
* DELETE<br />
Удаление информации в полученной локации.
* OPTIONS<br />
Быстрый способ для клиента выяснить какой из методов поддерживается по данному URL. Начиная с Flask 0.6 эта возможность имплементирована автоматически.
<br /><br />
Самое интересное в том, что HTML4 и XHTML1 поддерживают методы GET и POST. Но с использованием JavaScript и будущих стандартов HTML можно использовать другие методы. Кроме того HTTP стал весьма популярным в последнее время и браузеры - — уже не единственные клиенты, использующие протокол HTTP. Например, многие системы контроля версий используют его.
 
== Статические файлы ==
Динамическим веб-приложениям также требуются статические файлы. Обычно это css и javascript файлы. В идеале, ваш веб-сервер уже настроен, чтобы их обслуживать, но если вам потребуется, вы можете изменить настройки во Flask.
Просто создайте папку с названием static в вашем пакете или рядом с модулем и она будет доступна в /static по применению.<br />
Для генерации адресов для статических файлов, используйте специальное имя 'static':
<source lang="python">
Строка 215 ⟶ 221 :
 
== Рендеринг шаблонов ==
Создание HTML из Python  — это не удовольствие, а громоздкий процесс. Так как HTML обладает своей свободой, вы должны озаботиться безопасностью своего приложения. В связи с этим Flask автоматически настраивает для нас Jinja2 (механизм шаблонов).
<br />
Чтобы создать шаблон, можно использовать метод render_template(). Все, что вам нужно сделать,  — это указать имя шаблона и переменные, которые вы хотите передать в шаблоны как ключевые аргументы. Вот простой пример того, как сделать шаблон:
<source lang="python">
from flask import render_template
Строка 226 ⟶ 232 :
return render_template('hello.html', name=name)
</source>
Flask будет искать шаблоны в папке шаблонов. Таким образом, если ваше приложение представляет собой модуль, эта папка находится рядом с этим модулем, если же это пакет, то на самом деле внутри вашего пакета:<br />
Случай с модулем:
<source lang="python">
Строка 234 ⟶ 240 :
</source>
 
Случай с пакетом:<br />
<source lang="python">
/application
Строка 250 ⟶ 256 :
{% endif %}
</source>
Внутри шаблонов, вы также имеете доступ к реквестам, сессиям и g-объектам, а также можете использовать get_flashed_messages() функцию. G-объекты, имеется ввиду, если вам необходимо сохранить информацию для ваших нужд, смотрите документацию [http://flask.pocoo.org/docs/patterns/sqlite3/#sqlite3 "«Использование SQLite 3 во Flask"»].<br />
Шаблоны особенно полезны, если используется наследование. [http://flask.pocoo.org/docs/patterns/templateinheritance/#template-inheritance Прочтите документацию как используется наследование в шаблонах.] Наследование в шаблонах позволяет сохранить некоторые элементы на каждой страницы (например: заголовок, навигация и футер).<br />
Включено автоматическое экранирование, что позволит избежать проблем, если имя содержит HTML-теги. Если доверяете переменной, а вы знаете, что это будет безопасно в HTML (например, потому что оно пришло от модуля, который преобразует вики-разметки в HTML), вы можете пометить его как безопасный с помощью Markup класса или с помощью |safe фильтра в шаблоне. В документации Jinja 2 представлено несколько примеров.
<br /><br />
Вот пример, как работает класс разметки:
<source lang="python">
Строка 266 ⟶ 272 :
 
== Доступ к данным запроса ==
Для веб-приложений крайне важно реагировать на данные клиента отправляя их на сервер. Flask обеспечивает этой информацией - — глобальный объект запроса. Если у вас есть некоторый опыт работы с Python, вы можете быть удивлены, как этот объект может быть глобальным, и как Flask удается оставаться потоко-безопасным. Ответ заключается в контекстных локалах:
 
=== Локальные контексты (Context Locals) ===
'''Инсайдерская информация'''
Строка 272 ⟶ 279 :
прочитайте этот раздел, в противном случае, пропустите его.
 
Некоторые объекты во Flask - — глобальные, но это не обычный вид глобальных объектов. Эти объекты являются на самом деле прокси к объектам, которые являются локальными для конкретного контекста. Это труднопроизносимо. Но на самом деле довольно легко понять.<br />
Представьте, что контекст обрабатывает поток. Приходит запрос и веб-сервер решает породить новый поток (или что-то другое, основной объект может иметь дело с параллельными системами в отличие от потоков). Когда Flask начинает свою внутреннюю обработку запросов, он выясняет, какой текущий поток является активным контекстом и связывает текущее приложение и WSGI среду в этом контексте (потоке). Он делает это умно, таким образом, чтобы одно приложение может вызвать другое приложение без разрушения.<br />
Итак, что же это значит для вас? В принципе, пока вы тестируете, вы можете полностью это игнорировать. Но вы можете заметить, что код, который зависит от объекта запроса может внезапно сломаться, потому что нет объекта запроса. Решением является создание объекта запроса для себя и привязка его к контексту. Самое простое решение для тестирования, это использование контекст менеджера test_request_context() В сочетании с постановкой, он свяжет тестовый запрос, так что вы можете взаимодействовать с ним. Вот пример:
<source lang="python">
Строка 320 ⟶ 327 :
 
=== Загрузка файла ===
Через Flask легко использовать загрузку файлов. Просто убедитесь, что не забыли поставить атрибут <code>enctype="multipart/form-data"</code> в вашей HTML форме, иначе браузер не передаст файлы. <br />
Загруженные файлы сохраняются в память сервера или во временное хранилище в файловой системе. Вы можете получить доступ к этим файлам через атрибут <code>files</code> в объекте запроса. Каждый загруженный файл хранится в этом словаре. Он ведет себя так же, как стандартный объект <code>file</code> в Python, но имеет метод save(), который позволяет сохранить этот файл в файловую систему сервера. Вот простой пример, показывающий, как это работает:
<source lang="python">
Строка 346 ⟶ 353 :
 
=== Cookies ===
Доступ к куки осуществляется через их атрибут. Для установки кукис, используйте метод set_cookie в объектах запроса. Данный атрибут представляет из себя словарь со всеми переданными клиентскими кукис. Если вы хотите использовать сессии, то не используете куки напрямую, вместо них лучше использовать сессии Flask, что добавит вам некоторую безопасность поверх кукис. <br /><br />
Чтение кукис:
<source lang="python">
Строка 383 ⟶ 390 :
this_is_never_executed()
</source>
Это довольно бессмысленный пример, потому что пользователи будут перенаправлены со страницы индекса. Они не смогут получить доступ (получат ошибку 401 - — отказано в доступе), но это показывает, как это работает.
<br /><br />
По умолчанию черно-белые страницы ошибок показываются в каждом коде ошибок. Если вы хотите настроить страницу ошибки, вы можете использовать декоратор <code>errorhandler()</code>
<source lang="python">
Строка 395 ⟶ 402 :
 
== Об ответах ==
Возвращаемые значения от обозревающей функции автоматически преобразуется в объект-ответ. То есть если возвращаемое значение является строкой, оно конвертируется в объект-ответ со строкой в ответе тела, код ошибки "«200 OK"» и text/html mimetype. Логика преобразования для возвращаемого значения выглядит следующим образом:
# Если объект-ответ возвращает правильный тип, то это есть прямое возвращение непосредственно от обозревающей функции.
# Если это строка, объект-ответ создается с этими данными и параметрами по умолчанию.
Строка 414 ⟶ 421 :
return resp
</source>
 
== Сессии ==
В дополнение к объекту-запроса есть и второй объект под названием сессия, которая сохраняет информацию относящуюся к пользователю от одного запроса к другому. Это осуществляется поверх кукис и записывает куки криптографически. Это означает, что пользователь может посмотреть содержимое кукис, но не изменить его, так как они не знают закрытый ключ, который используется для подписи.
Строка 450 ⟶ 458 :
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
</source>
escape() - — указывается в этом примере, так как в данном случае не используется шаблонизатор. <br /><br />
'''Как сгенерировать хороший секретный ключ?'''<br />
Самый простой и наиболее доступный способ, сделать это на основе генератора псевдослучайных чисел.
<source lang="python">
Строка 459 ⟶ 467 :
</source>
Небольшое замечание о кукисах основанных на базе сессий: Flask примет значение, положит в объект-сессию и сериализует их в кукисы. Если вы обнаружили, что некоторые значения не сохранились между запросами, то учтите, что кукисы на самом деле активны, и вы не получите четкое сообщение об ошибке, поэтому проверяйте размер куки в ваших ответах на странице по сравнению с размером, который поддерживается веб-браузерами.
 
== Фидбэк, система флэшинга ==
Хорошие приложения и пользовательские интерфейсы, имеют систему обратной связи. Если пользователь не получает достаточно обратной связи, то в конечном итоге, он начнет ненавидеть ваше приложение. Flask дает простой путь, чтобы получить обратную связь с пользователем через флэшинг систему. Флэшинг система в основном записывает сообщения в конце запроса и доступна к нему на следующий (и только на следующий) запрос. Сообщение предоставляется обычно через разметку шаблона.<br />
Для флэш-сообщения используйте метод flash() А чтобы получить сообщение, можете использовать get_flashed_messages(), которые также доступны в шаблонах.<br />
Примеры использования можете посмотреть [http://flask.pocoo.org/docs/patterns/flashing/#message-flashing-pattern здесь]
 
== Логирование ==
Вы можете оказаться в ситуации, когда вы имеете дело с данными, которые по идее должны быть правильными, но на самом деле это не так. Например, некоторый клиентский код, который посылает HTTP-запрос к серверу. Это может быть вызвано манипуляциями с данными со стороны пользователя, или падение клиентского кода. Вполне нормально ответить на это ошибкой 400 Bad Request, но бывают ситуации, когда несмотря на ошибку, код должен продолжать работать.<br />
Если вы хотите видеть, что произошло что-то подозрительное, используйте логирование.
<source lang="python">
Строка 473 ⟶ 482 :
</source>
[http://docs.python.org/library/logging.html Здесь можете ознакомится с документацией по логированию.]
 
== Подключение WSGI Middlewares ==
Если вы хотите добавить WSGI middleware в ваше приложение, вы можете обернуть его внутри WSGI приложения. Например, если вы хотите добавить middleware от Werkzeug в работе, чтобы обойти ошибки в lighttpd, вы можете сделать это следующим образом:
Строка 485 ⟶ 495 :
# Когда пользователь вошел в систему, он может добавить новую запись на страницу, состоящую из текстового названия и некоторого HTML текста. Этот HTML не будет проверен, потому что мы доверяем пользователю.
# Страница отображает все записи в обратном порядке (новые сверху), и пользователь может добавлять новые записи из формы вверху, если он залогинился.
Мы будем использовать напрямую SQLite3, потому что этого достаточно для приложения такого размера. Для приложений большого размера лучше использовать SQLAlchemy, которая обрабатывает подключения к базе данных более разумным способом и дает много возможностей в обработке запросов. Кроме того, есть еще одна из самых популярных баз данных - — NoSQL, можно использовать ее, если она вам больше подходит.<br />
[[Файл:Flaskr.png]]
 
== Шаг 0: Создание каталогов ==
Вначале создадим каталоги, необходимые Вашему приложению:
Строка 508 ⟶ 519 :
</source> с именем <code>schema.sql</code> в только что созданный каталог <code>flaskr</code>.
 
Эта схема состоит из одной таблицы с названием <code>entries</code>. У каждой записи в таблице есть свой идентификатор <code>id</code>, заголовок <code>title</code> и текст <code>text</code>. <code>Id</code> &mdash; — автоматически увеличивающееся натуральное число и первичный ключ. Два строковых значения не должны быть неопределёнными и пустыми (<code>not null</code>).
 
== Шаг 2: Установочный код приложения ==
Строка 542 ⟶ 553 :
</source>
 
Для изменения значений по умолчанию таким способом можно установить в переменной окружения <code>FLASKR_SETTINGS</code> название конфигурационного файла для загрузки. Флаг <code>silent</code> (&laquo;«тихо, безмолвно&raquo;») отключает вывод сообщений Flask при отсутствии такой переменной окружения.
 
Секретный ключ (<code>SECRET_KEY</code>) необходим для безопасности клиентских сессий. Вдумчиво выбирайте ключевые слова: они должны быть настолько сложными, насколько это возможно.
Строка 548 ⟶ 559 :
Флаг отладки (<code>DEBUG</code>) включает или выключает интерактивный отладчик. Никогда не оставляйте режим отладки активным на производственном сервере, это позволит пользователям выполнять код на нём!
 
Добавим метод для подключения к указанной базе данных. Он может быть использован для соединения по запросу, а также из интерактивной оболочки Python или скрипта. Этот метод пригодится позже.
<source lang="python">
def connect_db():
Строка 559 ⟶ 570 :
app.run()
</source>
Для запуска приложения используйте команду <code>python flaskr.py</code>, выводящую сообщение о том, что сервер запустился, и адрес, по которому следует обращаться. Однако, открыв этот адрес в браузере, получим ошибку &laquo;«404 Страница не найдена&raquo;», ведь у нас пока нет содержимого для просмотра. Но на этом сосредоточимся чуть позже. Сначала нам нужна рабочая база данных.
 
== Шаг 3: Создание базы данных ==
 
Flaskr &mdash; — приложение на основе базы данных, а, точнее, реляционной базы данных. Такие системы нуждаются в схеме, сообщающей, как хранить информацию. Поэтому, важно создать такую схему перед первым запуском сервера.
 
Такая схема может быть создана передачей файла <code>schema.sql</code> в <code>sqlite3</code>:
<source lang="bash">sqlite3 /tmp/flaskr.db < schema.sql</source>
 
Минусом этого решения является то, что для установки требуется приложение <code>sqlite3</code>, которое установлено не в каждой системе. Кроме того, нужно указать путь к базе данных, где можно сделать ошибку. Хорошая идея &mdash; — добавить функцию, которая инициализирует базу данных в самом приложении.
 
Желая поступить так, сначала Вы должны импортировать функцию <code>contextlib.closing()</code> из пакета <code>contextlib</code>. При использовании Python 2.5 необходимо импортировать <code>with_statement</code> из пакета <code>__future__</code> (импорт из <code>__future__</code> всегда должен быть первым в списке):
Строка 576 ⟶ 587 :
</source>
 
Теперь мы можем создать функцию с названием <code>init_db()</code> для инициализации базы данных. Для этого используем функцию <code>connect_db</code>, определённую ранее.
<source lang="python">
def init_db():
Строка 585 ⟶ 596 :
</source>
 
<code>closing()</code> &mdash; — вспомогательная функция, позволяющая сохранить соединение открытым до конца блока <code>with</code>. Метод <code>open_resource()</code> поддерживает эту функциональность из коробки, так что его можно использовать в этом блоке. Функция открывает файл по пути (ваш flaskr каталог) и позволяет читать из него. Мы используем её здесь для выполнения скрипта с подключением к базе данных.
 
Соединяясь с базой данных, получаем объект связи (называемый <code>db</code>), предоставляющий нам курсор <code>cursor</code> с методом для выполнения всего сценария. В конце нужно подтвердить (<code>commit</code>) изменения. SQLite3 и другие транзакционные базы данных не подтверждают операций без Вашего особого распоряжения.
Строка 596 ⟶ 607 :
 
=== Поиск и устранение неисправностей ===
Получив сообщение об ошибке, что таблица не может быть найдена, убедитесь, что сделан вызов функции <code>init_db()</code> и правильно указаны названия таблиц (наиболее частая ошибка &mdash; — путаница с множественным и единственным числом в названиях таблиц).
 
== Шаг 4: Запрос подключения к базе данных ==
Строка 619 ⟶ 630 :
;Где поместить этот код?
 
: Если Вы следили за статьей, то, возможно, были озадачены, где поместить свой код на этом шаге и последующих? Логичным было бы сгруппировать вместе все функции на уровне модуля и поставить новые функции <code>before_request</code> и <code>teardown_request</code> ниже существующей функции <code>init_db</code>. Чтобы сориентироваться, посмотрите, как это организовано в [http://github.com/mitsuhiko/flask/tree/master/examples/flaskr/ оригинале]. Во Flask Вы можете поместить весь код Вашего приложения в один модуль Python. Но Вы не обязаны этого делать. Лучше этого не делать, если приложение становится большим и объемным.
 
== Шаг 5: Функции представления ==
Теперь, когда у нас уже есть соединения с базой данных, мы можем приступить к написанию функций представления. Нам понадобится четыре:
 
=== Вывод записей ===
Этот вывод показывает все записи сохраненные в базе данных. Он мониторит корневой каталог приложения и выбирает по заголовку и тексту из базы данных. Запись с наибольшим идентификатором (новейшая запись) будет сверху. Ряды возвращаемые от курсора являются кортежем с колонками, и выбираются специфично по запросу. Это хорошо для небольших приложений, как здесь, но вы можете конвертировать их в словарь. Если вы заинтересованы, чтобы сделать это, то посмотрите как это сделано в [http://flask.pocoo.org/docs/patterns/sqlite3/#easy-querying Easy Querying].<br />
Эта обзорная функция пропускает записи через словари в шаблоне show_entries.html и возвращает обработанное значение:
<source lang="python">
Строка 650 ⟶ 662 :
</source>
 
Обратите внимание, что мы проверяем, залогинен ли пользователь, по ключу (ключ <i>''logged_in</i>'' существует в пределах сессии и равен <i>''True</i>'').
 
'''Замечание о безопасности:'''
убедитесь, что вы используете знаки вопроса (?) при составлении SQL-запроса, аналогично примеру выше. Если при составлении запроса вы используете форматированные строки, ваше приложение может быть уязвимо к атакам типа sql-injection. См. [http://flask.pocoo.org/docs/patterns/sqlite3/#sqlite3 Using SQLite 3 with Flask ]
 
=== Функции login и logout ===
Эти функции используются для входа и выхода пользователей сайта. Login проверяет имя пользователя и его пароль и устанавливает для сессии параметр <i>''logged_in</i>''. Если вход пользователя произошел успешно, то этот значение этого параметра устанавливается равным <i>''True</i>'', и пользователь перенаправляется обратно на страницу <i>''show_entries</i>''. Кроме того, пользователю выдается сообщение о том, что он или она успешно зашел на сайт. Если же происходит ошибка, то шаблон страницы логина выдает сообщение об этом, и запрос к пользователю повторяется.
<source lang="python">
@app.route('/login', methods=['GET', 'POST'])
Строка 673 ⟶ 685 :
</source>
 
В свою очередь, функция logout удаляет параметр <i>''logged_in</i>'' из сессии. Здесь мы использовали следующий трюк: если мы будем использовать метод словаря (dict) ''pop()'', и передадим в него второй параметр (значение по умолчанию), то метод удалит ключ из словаря, если он там есть, и не сделает ничего, если его нет. Трюк полезен, потому что нам не нужно проверять, был залогинен ли пользователь.
<source lang="python">
@app.route('/logout')
Строка 792 ⟶ 804 :
 
= Ссылки =
http://flask.pocoo.org/docs/tutorial/ - оригинал приведенного здесь туториала<br />
http://flask.pocoo.org/docs/ - официальный вебсайт Flask<br />
http://groups.google.com/group/flask-russian - русскоязычная группа обсуждения Flask