Как записать файл под flask
Перейти к содержимому

Как записать файл под flask

  • автор:

Загрузка файлов¶

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

  1. Тег помечается атрибутом enctype=multipart/form-data , а в форму помещается тег .
  2. Приложение получает доступ к файлу через словарь files в объекте запроса.
  3. Воспользуйтесь методом save() для того, чтобы сохранить временный файл в файловой системе для последующего использования.

Введение¶

Начнём с простейшего приложения, которое загружает файл в определённый каталог и отображает его пользователю. Вот начало нашего приложения:

import os from flask import Flask, request, redirect, url_for from werkzeug.utils import secure_filename UPLOAD_FOLDER = '/path/to/the/uploads' ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif']) app = Flask(__name__) app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER 

Сначала нужно выполнить серию импортов. Большая часть понятна, werkzeug.secure_filename() рассматривается чуть позже. UPLOAD_FOLDER — это путь, куда будут загружаться файлы, а ALLOWED_EXTENSIONS — это набор допустимых расширений. Теперь вручную добавим в приложение правило для URL. Обычно мы так не делаем, но почему мы делаем это сейчас? Причина в том, что мы хотим заставить веб-сервер (или наш сервер приложения) обслуживать эти файлы и поэтому нам нужно генерировать правила для связывания URL с этими файлами.

Почему мы ограничили список допустимых расширений? Наверное вам совсем не хочется, чтобы пользователи могли загружать что угодно, если сервер напрямую отправляет данные клиенту. В таком случае вам нужно быть уверенными в том, что пользователи не загрузят файлы HTML, которые могут вызвать проблему XSS (см. Cross-Site Scripting ( xss ) — межсайтовый скриптинг). Также убедитесь в том, что запрещены файлы с расширением .php , если сервер их выполняет. Правда, кому нужен PHP на сервере? 🙂

Следующая функция проверяет, что расширение файла допустимо, загружает файл и перенаправляет пользователя на URL с загруженным файлом:

def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS @app.route('/', methods=['GET', 'POST']) def upload_file(): if request.method == 'POST': file = request.files['file'] if file and allowed_file(file.filename): filename = secure_filename(file.filename) file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) return redirect(url_for('uploaded_file', filename=filename)) return '''  Upload new File 

Upload new File

'''

Что делает функция secure_filename() ? Мы исходим из принципа «никогда не доверяй тому, что ввёл пользователь». Это справедливо и для имени загружаемого файла. Все отправленные из формы данные могут быть поддельными и имя файла может представлять опасность. Сейчас главное запомнить: всегда используйте эту функцию для получения безопасного имени файла, если собираетесь поместить файл прямо в файловую систему.

Информация для профи

Может быть вам интересно, что делает функция secure_filename() и почему нельзя обойтись без её использования? Просто представьте, что кто-то хочет отправить следующую информацию в ваше приложение в качестве имени файла:

filename = "../../../../home/username/.bashrc" 

Если считать, что ../ — это нормально, то при соединении этого имени с UPLOAD_FOLDER , пользователь может получить возможность изменять на файловой системе сервера те файлы, который он не должен изменять. Нужно немного разбираться в устройстве вашего приложения, но поверьте мне, хакеры настойчивы 🙂

Посмотрим, как отработает функция:

>>> secure_filename('../../../../home/username/.bashrc') 'home_username_.bashrc' 

Осталась последняя вещь: обслуживание загруженных файлов. Начиная с Flask 0.5 для этого можно использовать соответствующую функцию:

from flask import send_from_directory @app.route('/uploads/') def uploaded_file(filename): return send_from_directory(app.config['UPLOAD_FOLDER'], filename) 

Другая возможность — зарегистрировать uploaded_file с помощью правила build_only и воспользоваться SharedDataMiddleware . Такой вариант будет работать и в более старых версиях Flask:

from werkzeug import SharedDataMiddleware app.add_url_rule('/uploads/', 'uploaded_file', build_only=True) app.wsgi_app = SharedDataMiddleware(app.wsgi_app,  '/uploads': app.config['UPLOAD_FOLDER'] >) 

Теперь, если запустить приложение, всё должно работать как положено.

Улучшение загрузки¶

Добавлено в версии 0.6.

Как на самом деле Flask обрабатывает загрузку? Если файл достаточно мал, он сохраняется в памяти веб-сервера. В противном случае он помещается во временное место (туда, куда укажет tempfile.gettempdir() ). Но как указать максимальный размер файла, после которого загрузка файла должна быть прервана? По умолчанию Flask не ограничивает размер файла, но вы можете задать лимит настройкой ключа конфигурации MAX_CONTENT_LENGTH :

from flask import Flask, Request app = Flask(__name__) app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 

Код выше ограничит максимальный размер файла 16 мегабайтами. Если передаваемый файл окажется больше, Flask сгенерирует исключение RequestEntityTooLarge .

Эта функциональность была добавлена во Flask 0.6, но может быть реализована и в более ранних версиях при помощи наследовании от класса request. За более подробной информацией обратитесь к документации Werkzeug об обработке файлов.

Индикаторы процесса загрузки¶

Многие разработчики придумывают считывать файл мелкими частями, сохранять процент загрузки в базу данных и давать возможность JavaScript считывать эти данные из клиента. Короче говоря, клиент спрашивает у сервера каждые 5 секунд, сколько уже было передано. Почувствовали иронию ситуации? Клиент спрашивает у сервера о том, что уже и так знает.

Сейчас существуют способы получше, которые работают быстрее и более надёжны. В последнее время в вебе многое изменилось и теперь можно использовать HTML5, Java, Silverlight или Flash, чтобы сделать загрузку удобнее со стороны клиента. Посмотрите на следующие библиотеки, предназначенные именно для этого:

  • Plupload — HTML5, Java, Flash
  • SWFUpload — Flash
  • JumpLoader — Java

Простейшее решение¶

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

Создание веб-приложения с помощью Flask в Python 3

Создание веб-приложения с помощью Flask в Python 3

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

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

Flask использует механизм шаблонов Jinja для динамического создания HTML-страниц с использованием знакомых понятий в Python, таких как переменные, циклы, списки и т. д. Вы будете использовать эти шаблоны в рамках этого проекта.

С помощью этого обучающего руководства вы создадите небольшой веб-блог с использованием Flask и SQLite в Python 3. Пользователи приложения могут видеть все посты в вашей базе данных и нажимать на заголовки постов для просмотра их содержания. Кроме того, присутствует возможность добавлять новый пост в базу данных и редактировать или удалять существующий пост.

Предварительные требования

Перед началом выполнения этого руководства вам потребуется:

  • Локальная среда программирования Python 3. Следуйте инструкциям из обучающего руководства Установка и настройка локальной среды программирования для Python 3 для вашего локального компьютера. В этом обучающем руководстве мы назовем директорию проекта flask_blog .
  • Понимание концепций Python 3, таких как типы данных, условные выражения, циклы for, функции и другие. Если вы не знакомы с Python, воспользуйтесь нашей серией Программирование на Python 3.

Шаг 1 — Установка Flask

На этом этапе вы активируете вашу среду Python и установите Flask с помощью установщика пакетов pip .

Если вы еще не активировали среду программирования, убедитесь, что находитесь в директории проекта ( flask_blog ), и с помощью следующей команды активируйте среду:

После активации среды программирования в вашей командной строке появится префикс env , и она будет выглядеть следующим образом:

Данный префикс служит индикатором того, что среда env активна (имя среды может быть другим, в зависимости от того, как вы назвали ее при создании).

Примечание. Вы можете использовать Git, систему контроля версий, для эффективного управления и отслеживания процесса разработки вашего проекта. О том, как использовать Git, вы можете узнать из нашей статьи Введение в Git: установка, использование и ответвления.

Если вы используете Git, рекомендуем игнорировать вновь созданную директорию env в файле .gitignore , чтобы избежать отслеживания файлов, не связанных с проектом.

Теперь вы можете установить пакеты Python и изолировать ваш код проекта от основной системы Python. Это делается с помощью pip и python .

Чтобы установить Flask, запустите следующую команду:

После завершения установки запустите следующую команду, чтобы подтвердить установку:

Используйте интерфейс командной строки python с опцией -c для выполнения кода Python. Далее вы импортируете пакет flask с помощью import flask; и затем распечатываете версию Flask через переменную flask.__version__ .

В результате вы увидите номер версии, который будет выглядеть примерно так:

Output
1.1.2

Вы создали папку проекта, виртуальную среду и установили Flask. Теперь вы готовы переходить к настройке базового приложения.

Шаг 2 — Создание базового приложения

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

В директории flask_blog откройте файл с именем hello.py для редактирования. Используйте nano или любой другой текстовый редактор:

Этот файл hello.py будет служить минимальным примером того, как обрабатывать запросы HTTP. Внутри него импортируйте объект Flask и создайте функцию, которая возвращает ответ HTTP. Напишите следующий код внутри файла hello.py ​​​:

flask_blog/hello.py

from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return 'Hello, World!' 

В предыдущем блоке кода необходимо предварительно импортировать объект Flask из пакета flask . Затем вы создаете ваш экземпляр приложения Flask с именем app . Вы передаете специальную переменную __name__ , которая содержит имя текущего модуля Python. Она указывает экземпляру его расположение. Это необходимо, так как Flask устанавливает ряд путей за кадром.

Создав экземпляр app , вы начинаете используете его для обработки поступающих веб-запросов и отправки ответов пользователю. @app.route ​​​ — это декоратор, который превращает стандартную функцию Python в функцию просмотра Flask, конвертирующую возвращаемое значение функции в ответ HTTP, который отображается клиентом HTTP, например веб-браузером. Вы передаете значение ‘/’ в @app.route() ​​​ для обозначения того, что эта функция будет отвечать на веб-запросы для URL / , который является основным URL-адресом.

Функция просмотра hello() возвращает строку ‘Hello, World!’ в качестве ответа.

Сохраните и закройте файл.

Для запуска вашего веб-приложения сначала укажите Flask, где искать приложение (в вашем случае файл hello.py ) с помощью переменной среды FLASK_APP :

Затем запустите его в режиме разработки с помощью переменной среды FLASK_ENV :

И наконец, запустите приложение, используя команду flask run :

После запуска приложения вы увидите примерно следующее:

Output
* Serving Flask app "hello" (lazy loading) * Environment: development * Debug mode: on * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) * Restarting with stat * Debugger is active! * Debugger PIN: 813-894-335

В предыдущем выводе представлена следующая информация:

  • Название работающего приложения.
  • Среда, в которой работает приложение.
  • Debug mode: on означает, что отладчик Flask работает. Эта функция полезна при разработке, так как при возникновении проблем она выдает детализированные сообщения об ошибке, что упрощает работу по их устранению.
  • Приложение работает локально на URL http://127.0.0.1:5000/ , где 127.0.0.1 — это IP-адрес localhost вашего компьютера, а :5000 — номер порта.

Откройте браузер и введите URL ​​​​​​ http://127.0.0.1:5000/ ​​​​​​. Вы получите строку Hello, World! в качестве ответа. Это подтверждает то, что ваше приложение успешно работает.

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

Теперь вы можете оставить сервер разработки работать в терминале и открыть другое окно терминала. Перейдите в папку проекта, где находится файл hello.py ​​​, активируйте виртуальную среду, установите переменные среды FLASK_ENV и FLASK_APP , а затем выполните следующие шаги (эти команды перечислены ранее на этом шаге).

Примечание. При открытии нового терминала важно помнить об активации виртуальной среды и настройке переменных среды FLASK_ENV и FLASK_APP .

Если сервер разработки приложения Flask работает, невозможно запустить еще одно приложение Flask с помощью такой же команды flask run . Это связано с тем, что flask run по умолчанию использует номер порта 5000 , следовательно, когда он занят, невозможно запустить другое приложение, поэтому вы увидите ошибку аналогичную этой:

Output
OSError: [Errno 98] Address already in use

Для решения этой проблемы нужно либо остановить работающий в настоящий момент сервер с помощью команды CTRL+C , а затем снова задать команду flask run , или, если вам нужно,чтобы оба сервера работали одновременно, передать другой номер порта в аргумент -p , например запустить другое приложение через порт 5001 , используя следующую команду:

Теперь у вас есть небольшое веб-приложение Flask. Вы запустили ваше приложение и вывели информацию в браузере. Далее вы будете использовать файлы HTML в вашем приложении.

Шаг 3 — Использование шаблонов HTML

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

Flask предлагает вспомогательную функцию render_template() , которая позволяет использовать механизм шаблонов Jinja. Это упрощает работу с HTML благодаря написанию вашего кода HTML в файлах .html , а также использованию логики в вашем коде HTML. Вы будете использовать файлы HTML (шаблоны) для создания всех страниц вашего приложения, например главной страницы, где будут отображаться текущие посты блога, страницы поста блога, страницы, на которой пользователь сможет добавить новый пост и т. д.

На этом этапе вы создадите свое основное приложение Flask в новом файле.

Сначала в директории flask_blog с помощью nano или другого редактора создайте и отредактируйте файл app.py . Здесь будет хранить весь код, который вы будете использовать для создания приложения с блогом:

В этом новом файле вы сможете импортировать объект Flask для создания экземпляра приложения Flask так же, как вы делали ранее. Кроме того, вы сможете импортировать вспомогательную функцию render_template() , позволяющую поставлять файлы шаблонов HTML, существующих в папке templates , которую вы создадите. Файл будет иметь единичную функцию просмотра, отвечающую за обработку запросов по основному маршруту / . Добавьте следующее содержимое:

flask_blog/app.py

from flask import Flask, render_template app = Flask(__name__) @app.route('/') def index(): return render_template('index.html') 

Функция просмотра index() возвращает результат вызова render_template() с index.html​​ в качестве аргумента. Это дает указание render_template() искать файл с именем index.html в папке шаблонов. И папка, и файл еще отсутствуют. Вы получите сообщение об ошибке, если запустите приложение на этом этапе. Тем не менее при запуске вы уже будете знать об этой часто встречающейся ошибке. Затем вы сможете исправить ошибку, создав необходимые папку и файл.

Сохраните и закройте файл.

Остановите сервер разработки на другом терминале, на котором работает приложение hello с помощью CTRL+C .

Перед запуском приложения убедитесь, что вы корректно указали значение для переменной среды FLASK_APP , так как вы больше не используете приложение hello :

После открытия URL http://127.0.0.1:5000/ в вашем браузере страница отладчика сообщит вам, что шаблон index.html не был найден. Основная строка кода, которая привела к этой ошибке, будет выделена. В данном случае это строка return render_template(‘index.html’) .

Если вы нажмете на эту строку, отладчик откроет код, и у вас будет дополнительный контекст для понимания и решения проблемы.

Отладчик Flask

Для устранения данной ошибки создайте директорию с именем templates внутри директории flask_blog . Затем внутри нее откройте файл с именем index.html​ ​​ для редактирования:

После этого добавьте следующий код HTML внутри index.html ​​:

flask_blog/templates/index.html

DOCTYPE html> html lang="en"> head> meta charset="UTF-8"> title>FlaskBlogtitle> head> body> h1>Welcome to FlaskBlogh1> body> html> 

Сохраните файл и используйте свой браузер для перехода на http://127.0.0.1:5000/ или обновите страницу. Теперь браузер должен отобразить текст Welcome to FlaskBlog в теге .

Помимо папки templates веб-приложения Flask также обычно имеют папку static для хостинга статичных файлов, таких как файлы CSS, файлы JavaScript и изображения, которые использует приложение.

Вы можете создать файл стилей style.css , чтобы добавить CSS в ваше приложение. Сначала создайте директорию с именем static внутри основной директории flask_blog :

Затем создайте другую директорию с именем css внутри директории static для хостинга файлов .css . Обычно это делается для упорядочивания статичных файлов в специальных папках. Например, файлы JavaScript обычно находятся в директории с именем js , изображения хранятся в директории images (или img ) и т. д. Следующая команда создает директорию css внутри директории static :

После этого откройте файл style.css в директории css для редактирования:

Добавьте следующее правило CSS в файл style.css :

flask_blog/static/css/style.css

h1  border: 2px #eee solid; color: brown; text-align: center; padding: 10px; > 

Код CSS добавит границу, изменит цвет на коричневый, выравняет текст по центру и добавит небольшое дополнение к меткам .

Сохраните и закройте файл.

Далее откройте файл шаблона index.html для редактирования:

Добавьте ссылку в файл style.css внутри раздела файла шаблона index.html :

flask_blog/templates/index.html

. . . head> meta charset="UTF-8"> link rel="stylesheet" href=">"> title>FlaskBlogtitle> head> . . . 

Для этого вы используете вспомогательную функцию url_for() ​​​ для генерирования подходящего расположения файла. Первый аргумент указывает, что вы связаны со статичным файлом, а второй — это путь файла внутри статичной директории.

Сохраните и закройте файл.

После обновления страницы индекса вашего приложения вы увидите, что цвет текста Welcome to FlaskBlog ​​​ теперь коричневый, расположен по центру и добавлен внутри границы.

Используйте язык CSS для оформления стиля приложения и придавайте ему более привлекательный вид с помощью своего собственного дизайна. Однако, если вы не веб-дизайнер или не знакомы с CSS, воспользуйтесь инструментарием Bootstrap, который предлагает простые в использовании компоненты для оформления приложения. В данном проекте мы будем использовать Bootstrap.

Вероятно, вы уже догадались, что создание другого шаблона HTML будет означать повторение основной части кода HTML, который уже написан вами в шаблоне index.html . Избежать ненужного повторения кода возможно благодаря файлу базового шаблона, из которого наследуются все ваши файлы HTML. Дополнительную информацию можно найти в статье Наследование шаблонов в Jinja.

Для создания базового шаблона сначала необходимо создать файл с именем base.html внутри директории templates :

Введите следующий код в шаблоне base.html ​​:

flask_blog/templates/base.html

doctype html> html lang="en"> head> meta charset="utf-8"> meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> title> title> head> body> nav class="navbar navbar-expand-md navbar-light bg-light"> a class="navbar-brand" href=">">FlaskBloga> button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> span class="navbar-toggler-icon">span> button> div class="collapse navbar-collapse" id="navbarNav"> ul class="navbar-nav"> li class="nav-item active"> a class="nav-link" href="#">Abouta> li> ul> div> nav> div class="container">  div>  script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous">script> script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous">script> script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous">script> body> html> 

Сохраните и закройте файл после редактирования.

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

Однако следующие выделенные части относятся к механизму шаблонов Jinja:

  • : блок, замещающий заголовок. Позже вы будете использовать его в других шаблонах для написания пользовательского заголовка для каждой страницы в приложении без перезаписи всего раздела каждый раз.
  • > : вызов функции, который возвращает URL для функции просмотра index() . Этот вариант отличается от прошлого вызова url_for() , который использовался для привязки статичного файла CSS. Он использует только один аргумент, а именно имя функции просмотра, и привязывается к маршруту, связанному с функцией вместо статичного файла.
  • : еще один блок, который будет замещен контентом в зависимости от дочернего шаблона (шаблоны, которые наследуются из base.html ), который заменит его.

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

Замените его содержание на следующее:

flask_blog/templates/index.html

  h1> Welcome to FlaskBlog h1> 

В этой новой версии шаблона index.html вы используете тег для наследования из шаблона base.html . Затем вы расширите его, заменив блок content в базовом шаблоне на содержимое блока content из предыдущего блока кода.

Этот блок content содержит тег с текстом Welcome to FlaskBlog внутри блока title , который в свою очередь заменяет оригинальный блок title в шаблоне base.html текстом Welcome to FlaskBlog . Так вы можете избежать повторения одного и того же текста дважды, так как он используется и в качестве названия страницы, и в качестве заголовка, который появляется под панелью навигации, унаследованной от базового шаблона.

Наследование шаблона также дает возможность использовать код HTML из других шаблонов (в данном случае base.html ) без повторения его при каждой необходимости.

Сохраните и закройте файл, а затем обновите страницу индекса в браузере. Вы увидите страницу с панелью навигации и оформленным заголовком.

Страница индекса с Bootstrap

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

Шаг 4 — Настройка базы данных

На этом этапе вы настроите базу данных для хранения данных, в случае с вашим приложением — это посты блога. Вы также наполните базу несколькими примерами.

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

Поскольку данные в SQLite хранятся в таблицах и столбцах, а ваши данные в основном состоят из постов блога, в первую очередь вам понадобится создать таблицу с именем posts и необходимыми столбцами. Вы создадите файл .sql , содержащий команды SQL для создания таблицы posts с несколькими столбцами. Затем вы будете использовать этот файл для создания базы данных.

Откройте файл с именем schema.sql внутри директории flask_blog :

Введите следующие команды SQL в этом файле:

flask_blog/schema.sql

DROP TABLE IF EXISTS posts; CREATE TABLE posts ( id INTEGER PRIMARY KEY AUTOINCREMENT, created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, title TEXT NOT NULL, content TEXT NOT NULL ); 

Сохраните и закройте файл.

Первая команда SQL — это DROP TABLE IF EXISTS posts; .Она удаляет все уже существующие таблицы с именем posts , чтобы не создавать путаницу. Обратите внимание, что при использовании этих команд SQL будет удалено все содержимое базы данных, поэтому не записывайте ничего важного в веб-приложении до окончания изучения этого руководства и экспериментируйте с финальным результатом. Далее, команда CREATE TABLE posts ​​​ используется для создания таблицы posts со следующими столбцами:

  • id : целое число, которое представляет собой первичный ключ. В базе данных будет присвоено уникальное значение каждой записи (посту блога).
  • created : время создания поста блога. NOT NULL означает, что столбец не может быть пустым, а значение DEFAULT — это CURRENT_TIMESTAMP​​​ , т. е. время добавления поста в базу. Точно так же как и в случае с id , вам не нужно указывать значение для этого столбца, так как он будет заполнен автоматически.
  • title : заголовок поста.
  • content : содержание поста.

Теперь, когда у вас есть схема SQL в файле schema.sql , вы сможете использовать ее для создания базы данных с помощью файла Python, который сформирует файл базы данных SQLite .db . Откройте файл с именем init_db.py внутри директории flask_blog с помощью любого предпочитаемого редактора:

А затем добавьте следующий код.

flask_blog/init_db.py

import sqlite3 connection = sqlite3.connect('database.db') with open('schema.sql') as f: connection.executescript(f.read()) cur = connection.cursor() cur.execute("INSERT INTO posts (title, content) VALUES (?, ?)", ('First Post', 'Content for the first post') ) cur.execute("INSERT INTO posts (title, content) VALUES (?, ?)", ('Second Post', 'Content for the second post') ) connection.commit() connection.close() 

Сначала вы импортируете модуль sqlite3 , а затем открываете соединение с файлом базы данных database.db , который будет создан сразу после запуска файла Python. После этого используйте функцию open() для открытия файла schema.sql . Далее вы оформляете его содержание с помощью метода executescript() , при котором выполняется несколько операторов SQL одновременно, что формирует таблицу posts . Вы создаете объект курсор, который позволяет вам использовать метод execute() для выполнения двух операторов SQL INSERT , чтобы добавить два поста блога в таблицу posts . И наконец, вы вносите изменения и закрываете соединение.

Сохраните и закройте файл, а затем запустите его в терминале с помощью команды python :

После завершения выполнения файла новый файл с именем database.db появится в директории flask_blog . Это означает, что вы успешно настроили свою базу данных.

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

Шаг 5 — Отображение всех постов

Теперь, когда вы настроили базу данных, можно изменить функцию просмотра index() , чтобы отображать все посты, внесенные в базу данных.

Откройте файл app.py , чтобы произвести следующие изменения:

Для первого изменения необходимо импортировать модуль sqlite3 в верхней части файла:

flask_blog/app.py

import sqlite3 from flask import Flask, render_template . . . 

Далее вы создадите функцию, которая обеспечивает подключение к базе данных, и вернете ее. Добавьте ее непосредственно после импорта:

flask_blog/app.py

. . . from flask import Flask, render_template def get_db_connection(): conn = sqlite3.connect('database.db') conn.row_factory = sqlite3.Row return conn . . . 

Эта функция get_db_connection() открывает соединение с файлом базы данных database.db , а затем устанавливает атрибут row_factory в sqlite3. Row , чтобы получить доступ к столбцам на основе имен. Это означает, что подключение к базе данных будет возвращать строки, которые ведут себя как обычные словари Python. И наконец, функция возвращает объект подключения conn , который вы будете использовать для доступа к базе данных.

После определения функции get_db_connection() необходимо изменить функцию index() следующим образом:

flask_blog/app.py

. . . @app.route('/') def index(): conn = get_db_connection() posts = conn.execute('SELECT * FROM posts').fetchall() conn.close() return render_template('index.html', posts=posts) 

В этой новой версии функции index() сначала откройте подключение к базе данных, используя функцию get_db_connection() , которую вы определили ранее. После этого выполните запрос SQL, чтобы выбрать все записи из таблицы posts . Вы применяете метод fetchall() , чтобы доставить все строки результата запроса. Это вернет список постов, внесенных в базу данных на предыдущем шаге.

Вы закрываете подключение к базе данных, используя метод close() , и возвращаете результат отображения шаблона index.html . Вы также передаете объект posts в качестве аргумента, который содержит результаты, полученные из базы данных. Это откроет вам доступ к постам блога в шаблоне index.html .

После внесения этих изменений сохраните и закройте файл app.py .

Теперь, после передачи постов, доставленных из базы данных в шаблон index.html , вы можете использовать цикл for для отображения каждого поста на странице индекса.

Откройте файл index.html :

Затем измените его следующим образом:

flask_blog/templates/index.html
h1> Welcome to FlaskBlog h1> a href=«#«> h2>>h2> a> span class=«badge badge-primary«>>span> hr>

В данном случае синтаксис — это цикл for Jinja , который аналогичен циклу for Python, за исключением того, что позже он закрывается с помощью синтаксиса . Вы используете этот синтаксис для создания цикла для каждого элемента в списке posts , который был передан функцией index() в строке return render_template(‘index.html’, posts=posts) . Внутри этого цикла for вы отображаете название поста в заголовке ​​​ в теге (позже вы будете использовать этот тег для привязки каждого поста в отдельности).

Вы отображаете заголовок с помощью буквального разделителя переменной ( > ​​​​​​). Не забывайте, что post представляет собой объект словарного типа, поэтому вы сможете получить доступ к заголовку поста с помощью post[‘title’] . Также вы отображаете дату создания поста помощью такого же метода.

После редактирования файла сохраните и закройте его. Затем перейдите на страницу индекса в браузере. Вы увидите на своей странице два поста, которые вы добавили в базу данных.

Страница индекса с отображенными постами

Теперь, когда вы изменили функцию просмотра index() , чтобы отобразить все посты, находящиеся в базе данных на домашней странице приложения, вы можете переходить к отображению каждого поста на отдельной странице и разрешить пользователям переходить по ссылке к каждому отдельному посту.

Шаг 6 — Отображение отдельного поста

На этом шаге вы создадите новый маршрут Flask с функцией просмотра и новым шаблоном HTML для отображения отдельного поста блога по его ID.

К концу этого шага на URL http://127.0.0.1:5000/1 будет находиться страница, на которой отображается первый пост (так как его ID 1 ). На URL http://127.0.0.1:5000/ ID будет отображаться пост с соответствующим номером ID , если такой существует.

Откройте app.py для редактирования:

Поскольку позже в рамках данного проекта вам потребуется получить пост блога по его ID из базы данных в нескольких расположениях, вы создадите отдельную функцию с именем get_post() . Вы можете вызвать его, передав ID, и получить обратно пост блога, связанный с предоставленным ID, или создать ответ Flask с сообщением 404 Not Found​​​ , если пост блога не существует.

Для ответа в виде страницы 404 вам необходимо импортировать функцию abort() из библиотеки Werkzeug , установленной вместе с Flask в верхней части файла:

flask_blog/app.py

import sqlite3 from flask import Flask, render_template from werkzeug.exceptions import abort . . . 

Затем добавьте функцию get_post() сразу после функции get_db_connection() , созданной вами на предыдущем шаге:

flask_blog/app.py

. . . def get_db_connection(): conn = sqlite3.connect('database.db') conn.row_factory = sqlite3.Row return conn def get_post(post_id): conn = get_db_connection() post = conn.execute('SELECT * FROM posts WHERE >, (post_id,)).fetchone() conn.close() if post is None: abort(404) return post . . . 

Эта новая функция имеет аргумент post_id , который определяет, какой пост блога предназначен для возврата.

Внутри функции вы используете функцию get_db_connection() для открытия подключения к базе данных и выполнения запроса SQL, чтобы получить пост блога, связанный с указанным значением post_id . Вы добавляете метод fetchone() для получения результата и хранения его в переменной post , а затем закрываете подключение. Если переменная post имеет значение None ​​​, т. е. результат не найден в базе данных, вы используете функцию abort() , импортированную вами ранее, для ответа с помощью кода ошибки 404 , и функция завершит выполнение. Если же пост был найден, вы возвращаете значение переменной post .

Далее добавьте следующую функцию просмотра в конце файла app.py :

flask_blog/app.py

. . . @app.route('/') def post(post_id): post = get_post(post_id) return render_template('post.html', post=post) 

В этой новой функции просмотра вы добавляете правило переменной , чтобы указать, что часть после слеша ( / ) представляет собой положительное целое число (отмеченное конвертером int ), которое вам необходимо в функции просмотра. Flask распознает это и передает его значение аргументу ключевого слова post_id ​​ вашей функции просмотра post() . Затем вы используете функцию get_post() для получения поста блога, связанного с заданным ID, и хранения результата в переменной post , которую вы передаете шаблону post.html . Этот шаблон вы создадите вскоре.

Сохраните файл app.py и новый файл шаблона post.html для редактирования:

Введите следующий код в этом новом файле post.html . Это будет аналогично файлу index.html , за исключением того, что он будет отображать единичный пост, так же как и содержание поста:

flask_blog/templates/post.html

  h2> > h2> span class="badge badge-primary">>span> p>>p> 

Вы добавляете блок title , который вы определили в шаблоне base.html , чтобы заголовок страницы отражал заголовок поста, в то же время отображаемый в заголовке .

Сохраните и закройте файл.

Теперь вы можете переходить к следующим URL-адресам для просмотра двух постов из вашей базы данных вместе со страницей, которая указывает пользователю, что запрашиваемый пост блога не обнаружен (так как пост с номером ID 3 пока отсутствует):

http://127.0.0.1:5000/1 http://127.0.0.1:5000/2 http://127.0.0.1:5000/3 

Вернувшись на страницу индекса, вы осуществите привязку заголовка каждого поста к соответствующей странице. Сделать это можно с помощью функции url_for() . Сначала откройте шаблон index.html для редактирования:

Затем измените значение атрибута href с # на > , чтобы цикл for выглядел следующим образом:

flask_blog/templates/index.html

 a href=">"> h2>>h2> a> span class="badge badge-primary">>span> hr> 

Здесь вы передаете ‘post’ в функцию url_for() в качестве первого аргумента. Это имя функции просмотра post() , и поскольку она принимает аргумент post_id , вы присваиваете значение post[‘id’] . Функция url_for() возвращает правильный URL для каждого поста на основании его ID.

Сохраните и закройте файл.

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

Шаг 7 — Изменение постов

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

Создание нового поста

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

Откройте файл app.py для редактирования:

Сначала импортируйте следующее из фреймворка Flask:

  • Глобальный объект request для доступа к входящим данным запроса, которые будут подаваться через форму HTML.
  • Функция url_for() для генерирования URL-адресов.
  • Функция flash() для появления сообщения при обработке запроса.
  • Функция redirect() для перенаправления клиента в другое расположение.

Добавьте импортированные функции в ваш файл следующим образом:

flask_blog/app.py

import sqlite3 from flask import Flask, render_template, request, url_for, flash, redirect from werkzeug.exceptions import abort . . . 

Функция flash() хранит всплывающие сообщения в сеансе браузера клиента, что требует настройки секретного ключа. Этот секретный ключ используется для защищенных сеансов, что позволяет Flask запоминать информацию от одного запроса к другому, например, переходить от страницы нового поста к странице индекса. Пользователь может получить доступ к информации, хранящейся в сеансе, но не может изменить ее без секретного ключа. Поэтому никогда никому не передавайте доступ к вашему секретному ключу. Дополнительную информацию можно найти в документации Flask о сеансах.

Для настройки секретного ключа вам нужно добавить конфигурацию SECRET_KEY в ваше приложение через объект app.config . Добавьте ее непосредственно после определения app перед определением функции просмотра index() :

flask_blog/app.py

. . . app = Flask(__name__) app.config['SECRET_KEY'] = 'your secret key' @app.route('/') def index(): conn = get_db_connection() posts = conn.execute('SELECT * FROM posts').fetchall() conn.close() return render_template('index.html', posts=posts) . . . 

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

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

flask_blog/app.py

. . . @app.route('/create', methods=('GET', 'POST')) def create(): return render_template('create.html') 

Это создает маршрут /create , который принимает запросы GET и POST. Запросы GET принимаются по умолчанию. Для того чтобы также принимать запросы POST, которые посылаются браузером при подаче форм, вы передаете кортеж с приемлемыми типами запросов в аргумент methods декоратора @app.route() .

Сохраните и закройте файл.

Для создания шаблона откройте файл с именем create.html внутри папки templates :

Добавьте в новый файл следующий код:

flask_blog/templates/create.html

  h1> Create a New Post h1> form method="post"> div class="form-group"> label for="title">Titlelabel> input type="text" name="title" placeholder="Post title" class="form-control" value=">">input> div> div class="form-group"> label for="content">Contentlabel> textarea name="content" placeholder="Post content" class="form-control">>textarea> div> div class="form-group"> button type="submit" class="btn btn-primary">Submitbutton> div> form> 

Большая часть этого кода — стандартный HTML. Он будет отображать поле ввода для заголовка поста, текстовое пространство для содержания поста и кнопку для отправки формы.

Значением ввода заголовка поста является > , а текстовое пространство имеет значение > . Это сделано для того, чтобы вводимые вами данные не потерялись, если что-то пойдет не по плану. Например, если вы напишете длинный пост и забудете дать ему заголовок, отобразится сообщение, информирующее вас о том, что указание заголовка является обязательным. Это произойдет без потери уже написанного поста, так как он будет сохранен в глобальном объекте request , к которому у вас есть доступ в шаблонах.

Теперь, когда сервер разработки работает, используйте браузер для перехода к маршруту /create :

http://127.0.0.1:5000/create 

Вы увидите страницу Create a New Post​​​ (Создать новый пост) с полями для заголовка и содержания.

Страница создания нового поста

Эта форма подает запрос POST в функцию просмотра create() . Но в функции пока отсутствует код обработки запроса POST, поэтому после заполнения формы и ее отправки ничего не происходит.

Вы будете обрабатывать входящий запрос POST после отправки формы. Это можно сделать в функции просмотра create() . Вы можете отдельно обрабатывать запрос POST, проверяя значение request.method . Когда задано значение ‘POST’ ​​​, это означает, что полученный запрос — это запрос POST. Тогда вы можете переходить к извлечению отправленных данных, их проверке и внесению в базу.

Откройте файл app.py для редактирования:

Измените функцию просмотра create() следующим образом:

flask_blog/app.py

. . . @app.route('/create', methods=('GET', 'POST')) def create(): if request.method == 'POST': title = request.form['title'] content = request.form['content'] if not title: flash('Title is required!') else: conn = get_db_connection() conn.execute('INSERT INTO posts (title, content) VALUES (?, ?)', (title, content)) conn.commit() conn.close() return redirect(url_for('index')) return render_template('create.html') 

Выражением if вы обеспечиваете, что следующий за ним код выполняется только в случае, если запрос является запросом POST через сравнение request.method == ‘POST’ ​​​.

Затем вы извлекаете отправленные заголовок и содержание из объекта request.form , который дает вам доступ к данным формы в запросе. Если заголовок не указан, будет выполнено условие if not title , и отобразится сообщение для пользователя с информацией о необходимости заголовка. С другой стороны, если заголовок указан, вы открываете подключение с помощью функции get_db_connection() и вставляете полученные заголовок и содержание в таблицу posts .

Затем вы вносите изменения в базу данных и закрываете подключение. После добавления поста блога в базу данных вы перенаправляете клиента на страницу индекса с помощью функции redirect() , передавая URL, сгенерированный функцией url_for() со значением ‘index’ ​​ в качестве аргумента.

Сохраните и закройте файл.

Теперь перейдите к маршруту /create , используя ваш веб-браузер:

http://127.0.0.1:5000/create 

Внесите в форму любой заголовок и какой-либо контент. После отправки формы вы увидите новый пост, указанный на странице индекса.

И в заключение вам нужно отобразить всплывающие сообщения и добавить ссылку на панель навигации в шаблоне base.html для обеспечения простого доступа к этой новой странице. Откройте файл шаблона:

flask_blog/templates/base.html

nav class="navbar navbar-expand-md navbar-light bg-light"> a class="navbar-brand" href=">">FlaskBloga> button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> span class="navbar-toggler-icon">span> button> div class="collapse navbar-collapse" id="navbarNav"> ul class="navbar-nav"> li class="nav-item"> a class="nav-link" href="#">Abouta> li> li class="nav-item"> a class="nav-link" href=">">New Posta> li> ul> div> nav> div class="container">  div class="alert alert-danger">>div>   div> 

Сохраните и закройте файл. Теперь на панели навигации будет присутствовать элемент New Post , который связан с маршрутом /create .

Редактирование поста

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

Сначала вам нужно добавить новый маршрут в файл app.py . Его функция просмотра получит ID поста, который необходимо отредактировать. А URL будет представлен в формате / post_id /edit , где переменная post_id — это ID​​​ поста. Откройте файл app.py для редактирования:

Далее добавьте следующую функцию просмотра edit() в конце файла. Редактирование существующего поста аналогично созданию нового поста, поэтому эта функция просмотра будет такой же, как и функция просмотра create() :

flask_blog/app.py

. . . @app.route('//edit', methods=('GET', 'POST')) def edit(id): post = get_post(id) if request.method == 'POST': title = request.form['title'] content = request.form['content'] if not title: flash('Title is required!') else: conn = get_db_connection() conn.execute('UPDATE posts SET title = ?, content = ?' ' WHERE >, (title, content, id)) conn.commit() conn.close() return redirect(url_for('index')) return render_template('edit.html', post=post) 

Пост, который вы редактируете, определяется с помощью URL, а Flask будет передавать номер ID функции edit() через аргумент id . Вы добавляете это значение к функции get_post() , чтобы доставить пост, связанный с указанным ID, из базы данных. Новые данные будут поступать в запросе POST, который обрабатывается внутри условия if request.method == ‘POST’ .

Как и при создании нового поста, сначала вы извлекаете данные из объекта request.form , затем показываете всплывающее сообщение, если заголовок имеет пустое значение, в противном случае открываете подключение к базе данных. После этого вы обновляете таблицу posts , указывая новый заголовок и новое содержание, где ID поста в базе данных соответствует ID, который был указан в URL.

В случае запроса GET вы используете шаблон edit.html , передавая переменную post , которая содержит возвращенное значение функции get_post() . Вы будете это использовать для отображения существующих заголовка и содержания на странице редактирования.

Сохраните и закройте файл, а затем создайте новый шаблон edit.html :

Добавьте в новый файл следующий код:

flask_blog/templates/edit.html

  h1> Edit ">" h1> form method="post"> div class="form-group"> label for="title">Titlelabel> input type="text" name="title" placeholder="Post title" class="form-control" value=">"> input> div> div class="form-group"> label for="content">Contentlabel> textarea name="content" placeholder="Post content" class="form-control">>textarea> div> div class="form-group"> button type="submit" class="btn btn-primary">Submitbutton> div> form> hr> 

Сохраните и закройте файл.

Этот код пишется по той же схеме, за исключением синтаксиса > и > . Здесь отображаются данные, сохраненные в запросе, если он существует. В противном случае отображаются данные из переменной post , которая была передана в шаблон, содержащий данные текущей базы данных.

Теперь вы можете перейти к следующему URL для редактирования первого поста:

http://127.0.0.1:5000/1/edit 

Вы увидите страницу Edit “First Post”(Редактировать «Первый пост»).

Страница редактирования поста

Отредактируйте пост и отправьте форму, затем убедитесь, что пост был обновлен.

Теперь вам нужно добавить ссылку, которая указывает на страницу редактирования для каждого поста на странице индекса. Откройте файл шаблона index.html :

Отредактируйте файл, чтобы он выглядел в точности, как показано ниже:

flask_blog/templates/index.html
h1> Welcome to FlaskBlog h1> a href=«>«> h2>>h2> a> span class=«badge badge-primary«>>span> a href=«>«> span class=«badge badge-warning«>Editspan> a> hr>

Сохраните и закройте файл.

Удаление поста

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

Сначала вам нужно добавить новый маршрут / ID /delete , который принимает запросы POST, аналогично функции просмотра edit() . Ваша новая функция просмотра delete() будет получать ID поста для удаления из URL. Откройте файл app.py :

Добавьте следующую функцию просмотра внизу файла:

flask_blog/app.py

# . @app.route('//delete', methods=('POST',)) def delete(id): post = get_post(id) conn = get_db_connection() conn.execute('DELETE FROM posts WHERE >, (id,)) conn.commit() conn.close() flash('"<>" was successfully deleted!'.format(post['title'])) return redirect(url_for('index')) 

Эта функция просмотра принимает только запросы POST. Это означает, что навигация по маршруту / ID /delete в вашем браузере вернет ошибку, так как веб-браузеры по умолчанию настроены на запросы GET.

Но вы можете получить доступ к этому маршруту через форму, которая отправляет запрос POST, передающий ID поста, который вы хотите удалить. Функция получит значение ID и будет использовать его для получения поста из базы данных с помощью функции get_post() .

Затем вы открываете подключение к базе данных и выполняете команду SQL DELETE FROM для удаления поста. Вы вносите изменения в базу данных и закрываете подключение, одновременно отображая сообщение для пользователя, о том, что пост был успешно удален, и перенаправляете на страницу индекса.

Обратите внимание, что вы не отображаете шаблон. Это связано с тем, что вы просто добавите кнопку Delete на страницу редактирования.

Откройте файл шаблона edit.html :

Затем добавьте следующий тег после тега


и непосредственно перед строкой :

flask_blog/templates/edit.html

hr> form action=">" method="POST"> input type="submit" value="Delete Post" class="btn btn-danger btn-sm" onclick="return confirm('Are you sure you want to delete this post?')"> form> 

Вы используете метод confirm() для отображения сообщения подтверждения перед отправкой запроса.

Теперь снова перейдите на страницу редактирования поста блога и попробуйте удалить ее:

http://127.0.0.1:5000/1/edit 

В конце этого шага исходный код вашего проекта будет выглядеть, как код на этой странице.

Теперь пользователи вашего приложения могут писать новые посты и добавлять их в базу данных, редактировать и удалять существующие посты.

Заключение

В этом обучающем руководстве были представлены важные концепции фреймворка Flask Python. Вы научились создавать небольшое веб-приложение, запускать его на сервере разработки и предоставлять пользователю возможность вносить свои данные через параметры URL и веб-формы. Вы также использовали механизм шаблонов Jinja для повторного использования файлов HTML и использования логики в них. В конце этого обучающего руководства вы получили полностью функционирующий веб-блог, взаимодействующий с базой данных SQLite для создания, отображения, редактирования и удаления постов блога с использованием языка Python и запросов SQL.

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

У Flask есть множество расширений, созданных сообществом. Ниже представлен список расширений, который вы можете использовать для упрощения процесса разработки:

  • Flask-Login: управляет сеансом пользователя и обрабатывает вход и выход, а также запоминает вошедших в систему пользователей.
  • Flask-SQLAlchemy: упрощает использование Flask благодаря SQLAlchemy, инструментарию Python SQL и Object Relational Mapper для взаимодействия с базами данных.
  • Flask-Mail: помогает в решении задачи отправки сообщений электронной почты в приложении Flask.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Использование фреймворка Flask для реализации web-приложений

Работать я буду в PyCharm. Поэтому, первым делом я создаю свой проект и далее устанавливаю Flask через встроенный терминал с помощью команды pip install flask. Далее, я создал файл app1.py, где будет написано простое веб-приложение, отображающее HTML-код в браузере.
Открыв файл, я написал следующий код:

from flask import Flask
app = Flask ( __name__ )
return ‘

Hello, World!

В нем мы сначала импортируем объект Flask из пакета flask. Затем используем его для создания экземпляра приложения Flask, присвоив ему имя app. Мы передаем специальную переменную __name__, которая содержит имя текущего модуля Python. Это имя сообщает экземпляру, где он находится; это нужно, потому что Flask устанавливает некоторые пути за кулисами.

Создав экземпляр приложения, мы можем использовать его для обработки входящих веб запросов и отправки ответов пользователю. @app.route — это декоратор, который превращает обычную функцию Python в функцию просмотра Flask, который преобразует возвращаемое значение функции в HTTP-ответ, отображаемый HTTP-клиентом, например, веб браузером. Мы передаем значение ‘/‘ в @app.route (), чтобы указать, что эта функция будет отвечать на веб запросы для URL-адреса /, который является основным URL-адресом.

Функция просмотра hello() возвращает строку в качестве ответа HTTP.

Теперь у нас есть простое приложение Flask в файле Python с именем app1.py.

Далее, необходимо его запустить чтобы увидеть результат функции просмотра hello(), отображаемой в веб браузере. Как это сделать? Во встроенном терминале я прописываю команду set FLASK_APP=app1, благодаря которой я сообщаю Flask, где найти приложение app1. После, прописываю set FLASK_ENV=development, которая говорит о том, что я хочу запустить приложение в режиме разработки (чтобы можно было использовать отладчик для обнаружения ошибок). Наконец, я прописываю flask run. После запуска, вы увидите следующее:

* Serving Flask app ‘app1’ ( lazy loading )
* Environment: development
* Debug mode: on
* Restarting with stat
* Debugger is active!
* Debugger PIN: 188 — 110 — 549
* Running on http:// 127.0 . 0.1 : 5000 / ( Press CTRL+C to quit )

Эти выходные данные содержат несколько частей информации:
•Название приложения, которое вы запускаете («app1»).
•Среда, в которой выполняется приложение (development).
•Debug mode (Режим отладки): on означает, что отладчик Flask запущен. Это полезно при разработке, поскольку предоставляет подробные сообщения об ошибках, когда что-то идет не так, что упрощает поиск и устранение неисправностей.
•Приложение работает локально по URL-адресу http://127.0.0.1:5000/. 127.0.0.1 — это IP-адрес, который представляет локальный хост вашего компьютера, а: 5000 — это номер порта.
Далее, открываем браузер и введем URL-адрес http://127.0.0.1:5000/. Вы увидите текст “Hello, World!” в качестве ответа. Это подтверждает, что ваше приложение успешно работает.

Кроме этого, можно добавить несколько маршрутов для отображения разных страниц в зависимости от запрошенного URL.

Маршрут — это URL-адрес, который вы можете использовать, чтобы определить, что пользователь получает, когда посещает ваше веб приложение в своем браузере. Например, http://127.0.0.1:5000/ — это основной маршрут, который может использоваться для отображения главной страницы. URL-адрес http://127.0.0.1:5000/about может быть другим маршрутом, используемым для страницы «About», которая дает посетителю некоторую информацию о вашем веб приложении.

Для этого, в app1.py прописываем следующее:

Чтение и запись файлов в Python

Перед тем как прочесть или записать что-либо в файл, его следует открыть с помощью функции open() . При вызове эта функция создает объект типа File , с которым в дальнейшем можно работать.

open(file, mode, buffering, encoding)

Режим доступа mode — строка, в которой указывается для чего открывается файл:

  • ‘r’ — открытие на чтение (является значением по умолчанию)
  • ‘w’ — открытие на запись, содержимое файла удаляется; если файла не существует, создается новый
  • ‘x’ — если файла не существует — открытие на запись, иначе исключение
  • ‘a’ — открытие на дозапись, информация добавляется в конец файла
  • ‘b’ — открытие в двоичном режиме
  • ‘t’ — открытие в текстовом режиме (является значением по умолчанию)
  • ‘+’ — открытие на чтение и запись

Режимы могут быть объединены, то есть, к примеру, ‘rb’ — чтение в двоичном режиме. По умолчанию режим равен ‘rt’ .

Буферизация buffering (целое число): 0 — файл открывается без буферизации, 1 — с построчной буферизацией, больше одного — буферизация выполняется с указанным размером, отрицательное число — разер буфера будет равен системному.

И последний аргумент encoding задает кодировку, нужен только в текстовом режиме чтения файла.

Как только файл был открыт и появился файловый объект, можно получить следующую информацию:

  • file.closed — возвращает True если файл был закрыт
  • file.mode — возвращает режим доступа, с которым был открыт файл
  • file.name — возвращает имя файла
  • file.softspace — возвращает False , если при выводе содержимого файла следует отдельно добавлять пробел
>>> file = open('test.txt') >>> file.closed False >>> file.mode 'r' >>> file.name 'test.txt' >>> file.close()

Метод read() читает весь файл целиком, если был вызван без аргументов, и n символов, если был вызван с аргументом (целым числом n ). Запись в файл осуществляется с помощью метода write() . После окончания работы с файлом его обязательно нужно закрыть с помощью метода close() .

>>> helloFile = open('C:\\example\\hello.txt', 'w') >>> helloFile.write('Hello, world!\n') 14 >>> helloFile.close()
>>> helloFile = open('C:\\example\\hello.txt', 'r') >>> helloFile.read() 'Hello, world!\n' >>> helloFile.close()

Добавление информации в файл:

>>> helloFile = open('C:\\example\\hello.txt', 'a') >>> helloFile.write('It\'s nice to meet you.\n') 23 >>> helloFile.close()

Чтение всех строк из файла:

>>> helloFile.readlines() ['Hello, world!\n', "It's nice to meet you.\n"] >>> helloFile.close()

Построчное чтение из файла:

>>> helloFile = open('C:\\example\\hello.txt', 'r') >>> helloFile.readline() 'Hello, world!\n' >>> helloFile.readline() "It's nice to meet you.\n" >>> helloFile.close()

При считывании символ новой строки \n присутствует в конце каждой из строк. Его может не быть лишь в последней строке — это позволяет добиться однозначности: если метод возвращает пустую строку, значит достигнут конец файла; если строка содержит лишь символ \n значит это просто очередная строка.

Запись нескольких строк в файл (при использовании with закрывать файл не нужно):

>>> with open('test.txt', 'w') as file: . file.writelines(['First line\n', 'Second line'])
>>> with open('test.txt') as file: . file.readlines() ['First line\n', 'Second line']

Метод tell() возвращает позицию указателя, метод seek(offset, [from]) позволяет перейти на нужную позицию. Аргумент offset указывает на сколько байт перейти; аргумент from означает позицию, с которой начинается движение. 0 — означает начало файла, 1 — нынешняя позиция, 2 — конец файла.

Сохранение данных с помощью модуля shelve

>>> import shelve >>> shelfFile = shelve.open('data') >>> users = ['Иванов', 'Петров'] >>> mails = ['ivanov@mail.ru', 'petrov@mail.ru'] >>> shelfFile['users'] = users >>> shelfFile['mails'] = mails >>> shelfFile.close()
>>> os.listdir() ['data.bak', 'data.dat', 'data.dir', 'hello.txt']
>>> shelfFile = shelve.open('data') >>> shelfFile['users'] ['Иванов', 'Петров'] >>> shelfFile['mails'] ['ivanov@mail.ru', 'petrov@mail.ru'] >>> shelfFile.close()
  • Работа с файлами в Python, модуль shutil
  • Расширение «ESLint» для VS Code, часть 2 из 2
  • Расширение «ESLint» для VS Code, часть 1 из 2
  • Расширение «Prettier — Code formatter» для VS Code
  • Git. Символы конца строки EOL
  • Laravel. Файловое хранилище
  • Пользователь и группа www-data

Каталог оборудования

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Производители

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Функциональные группы

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Категории блога
Облако тегов

  • 1С:Предприятие (31)
  • API (29)
  • Bash (43)
  • CLI (118)
  • CMS (139)
  • CSS (50)
  • Frontend (75)
  • HTML (66)
  • JavaScript (150)
  • Laravel (72)
  • Linux (165)
  • MySQL (76)
  • PHP (125)
  • React.js (66)
  • SSH (27)
  • Ubuntu (68)
  • Web-разработка (509)
  • WordPress (73)
  • Yii2 (69)
  • БазаДанных (95)
  • Битрикс (66)
  • Блог (29)
  • Верстка (43)
  • ИнтернетМагаз… (84)
  • КаталогТоваров (87)
  • Класс (30)
  • Клиент (28)
  • Ключ (28)
  • Команда (84)
  • Компонент (60)
  • Конфигурация (63)
  • Корзина (32)
  • ЛокальнаяСеть (28)
  • Модуль (34)
  • Навигация (31)
  • Настройка (140)
  • ПанельУправле… (29)
  • Плагин (33)
  • Пользователь (26)
  • Практика (101)
  • Сервер (75)
  • Событие (27)
  • Теория (106)
  • Установка (66)
  • Файл (51)
  • Форма (58)
  • Фреймворк (192)
  • Функция (36)
  • ШаблонСайта (68)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *