Код
#статьи

Фреймворк Flask: как он работает и зачем нужен

Пишем свой блог и учимся работать с HTML-шаблонами с помощью Python и Flask.

Иллюстрация: Катя Павловская для Skillbox Media

Язык Python — это лёгкая дорога в программирование. А Flask помогает проложить путь в веб-разработку и научиться писать сайты с помощью Python. Получается, он такой же лёгкий, как и Python? Да, но есть нюансы.

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

Всё, что нужно знать о Flask в Python:


Что такое Flask

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

У Flask много преимуществ, которые выделяют его среди других фреймворков:

  • простой синтаксис — это всё-таки Python;
  • удобные шаблоны — можно быстро создавать прототипы веб-приложений;
  • куча инструментов для гибкой настройки сайтов под любые нужды.
Логотип Flask
Изображение: Wikimedia Commons

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

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

Flask входит в топ-15 самых популярных фреймворков для веб-разработки среди опытных программистов. Рядом с ним в рейтинге находятся Django, Express.js, Laravel, Ruby on Rails, Spring и ASP.NET. И, конечно, на Flask написано немало популярных сайтов. Вот лишь несколько примеров:

  • Pinterest — одна из крупнейших социальных сетей для обмена изображениями и идеями;
  • Netflix — один из крупнейших сервисов видеостриминга в мире;
  • Uber — сервис вызова такси и автомобильного транспорта;
  • Reddit — один из самых популярных новостных UGC-агрегаторов;
  • Twilio — платформа для разработки приложений для обмена сообщениями.

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

Чем Flask лучше других фреймворков

У Flask есть ряд особенностей, за которые его любят веб-разработчики. Давайте их перечислим:

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

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

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

Как установить Flask

Чтобы установить Flask, сначала нужно установить Python. Приступим.

Установка Python

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

Установка PIP

Если вы скачиваете официальную версию Python или пакет Anaconda, у вас автоматически установится PIP. Это менеджер пакетов для Python, который позволяет управлять сторонними библиотеками. Нам он понадобится, чтобы установить Flask.

Чтобы проверить, есть ли у вас PIP, введите в консоли:

pip --version

или

python3 -m pip --version

В ответ на экран выведется версия PIP. Если ничего не происходит, значит, PIP у вас не установлен. Исправим это:

python -m ensurepip --default-pip

Снова проверим, появился ли в системе менеджер пакетов. Если всё равно что-то не получается, попробуйте найти решение проблемы на Stack Overflow — или обратитесь к астрологу :)

Установка Flask

Теперь поставим сам Flask. Делается это очень просто:

pip install Flask

Начнётся процесс загрузки Flask, после которого он будет готов к использованию. Если вам нужна конкретная версия Flask, установить её можно, указав её номер с помощью дополнительного параметра ==<version>.

pip install Flask==<version>

Например, мы можем установить версию 2.0.1:

pip install Flask==2.0.1

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

pip show flask

или создадим Python-файл и впишем туда такую строку:

import flask

Теперь запустим интерпретатор и убедимся, что программа исполняется без ошибок.

Как создать простой сайт на Flask

Приступим к коду. Для начала нам понадобится основа для приложения. Создадим новый файл с именем app.py. Это и будет наше Flask-приложение.

На первом этапе импортируем класс Flask из библиотеки Flask:

from flask import Flask

Затем создадим экземпляр класса Flask:

app = Flask(__name__)

Здесь мы передаем аргумент __name__ конструктору класса, этот аргумент скажет Flask, где находится наше приложение. Так Flask сможет определить местоположение шаблонов и статических файлов, о которых речь пойдёт дальше. Если вы ещё не особо знакомы с классами в Python, советуем прочитать нашу статью об объектно-ориентированном программировании на Python.

Создаём первый маршрут

Весь бэкенд строится на маршрутах — или URL-адресах. Они помогают задавать удобную структуру и понятное поведение веб-приложениям.

Для пользователя маршруты — это отдельные «вкладки» на сайте. Например, если зайти на сайт Skillbox, откроется его главная страница www.skillbox.ru. А если кликнуть на любой курс, мы перейдём на другую страницу сайта с другим URL-адресом, таким как www.skillbox.ru/course/profession-python. Видим, что к адресу нашего сайта добавился текст: /course/profession-python/. Эта «приписка» и перенесла нас на другую страницу с другим содержимым. Получается, маршруты позволяют создавать разные страницы с разным наполнением в рамках одного сайта.

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

@app.route('/')
def hello_world():
    return 'Hello, World!'

Так мы создали URL-адрес главной страницы сайта. Например, для Skillbox главной страницей будет www.skillbox.ru. Тут мы мысленно можем дописать слеш: www.skillbox.ru/.

Сам маршрут задаётся в строке @app.route('/'). Внутрь круглых скобочек мы по ходу статьи будем вписывать разные маршруты, а пока нам хватит стандартного.

Внутрь маршрута мы поместили функцию hello_world(), которая будет выполняться при обращении к корневому URL, или главной странице нашего сайта (ведь наш маршрут ведёт именно на неё). Функция возвращает строку Hello, World! в браузере.

Запускаем приложение

Теперь нам нужно запустить приложение:

if __name__ == '__main__':
    app.run()

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

Сохраняем файл app.py и запускаем его с помощью команды в консоли:

python app.py

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

* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Проверяем приложения

Чтобы взглянуть на работу нашего приложения, нужно перейти по адресу, который был указан в консоли — http://127.0.0.1:5000/. Вот что мы там увидим:

Скриншот: Skillbox Media

Ликуем — у нас всё получилось, сайт работает. Дальше будем усложнять наше приложение и начнём создавать блог.

Как создать блог на Flask

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

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

app.py

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
   return 'Hello, World!'

if __name__ == '__main__':
   app.run()

Создаём HTML-шаблон

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

Ещё немного об HTML-шаблонах

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

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

Если вы не знаете, как писать HTML-код, советуем прочитать нашу статью об HTML. А теперь создадим HTML-шаблоны: выделим под них папку templates и добавим в неё файл base.html со следующим содержимым:

<!DOCTYPE html>
<html>
  <head>
    <title>{% block title %}{% endblock %}</title>
  </head>
  <body>
    {% block content %}{% endblock %}
  </body>
</html>

Этот шаблон будет отправной точкой для всех остальных HTML-страниц. В нём мы прописали заголовок:

<head>
  <title>{% block title %}{% endblock %}</title>
</head>

и основной контент (тело) страницы:

<body>
  {% block content %}{% endblock %}
</body>

Вы, наверное, уже обратили внимание на странные элементы, а точнее теги {% block %} и {% endblock %}. Они как раз нужны, чтобы динамически добавлять туда новые элементы: другие HTML-блоки, JavaScript-код и тому подобное.

Теперь давайте создадим второй шаблон и назовём его index.html. Он будет наследовать элементы базового шаблона:

{% extends "base.html" %}

{% block title %}Home{% endblock %}

{% block content %}
  <h1>Welcome to my website!</h1>
  <p>This is the homepage.</p>
{% endblock %}

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

Используем HTML-шаблоны

Пришло время воспользоваться шаблонами. Изменим файл app.py и импортируем функцию render_template из библиотеки Flask, которая позволяет работать с шаблонами:

from flask import Flask, render_template

Изменим маршрут главной страницы и используем в нём новую функцию, чтобы отобразить шаблон index.html:

@app.route('/')
def index():
    return render_template('index.html')

Сохраним изменения в файлах app.py, index.html и base.html, а затем снова запустим наше приложение:

python app.py

Открываем браузер и переходим по адресу http://127.0.0.1:5000/. У нас отобразится содержимое шаблона index.html:

Скриншот: Skillbox Media

Подключаем базу данных

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

Мы будем использовать базу данных SQLite, потому что она занимает совсем немного места, легка в освоении и вообще клёвая. А главный плюс — её не нужно скачивать отдельно, потому что она сразу есть в Python.

Займёмся привычным делом — импортируем модуль SQLite3:

import sqlite3

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

def get_db_connection():
    conn = sqlite3.connect('database.db')
    conn.row_factory = sqlite3.Row
    return conn

Эта функция создаст подключение к базе данных database.db и установит режим получения результатов запросов в виде словаря Row, что позволит обращаться к столбцам базы данных по их именам.

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

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

def close_db_connection(conn):
    conn.close()

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

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

Здесь мы получаем подключение к базе данных с помощью функции get_db_connection(), выполняем запрос к таблице posts и получаем все записи, используя метод fetchall(). Затем мы закрываем подключение с помощью функции close_db_connection() и передаём полученные записи в шаблон index.html с помощью функции render_template().

Но перед тем как использовать базу данных, её нужно инициализировать и создать таблицу posts.

У нашего учебного поста будет три поля с данными: уникальный идентификатор (ID), заголовок и текст поста. Назовём их соответственно — id, title и content:

def init_db():
    conn = get_db_connection()
    conn.execute('CREATE TABLE IF NOT EXISTS posts (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, content TEXT NOT NULL)')
    conn.close()

Функция execute() создаст нам таблицу posts с полями id, title и content. У каждого из этих полей будет собственный тип данных: целое число, строка и строка соответственно.

Мы задали полю id специальный параметр AUTOINCREMENT, чтобы при добавлении нового поста его айдишник автоматически увеличивался на 1. А параметр PRIMARY KEY нужен для уточнения, что строки в таблице уникальные и не пустые.

Инициализировать базу данных нужно в самом начале. Во Flask мы можем сделать это перед первым запросов к базе данных с помощью следующего кода:

@app.before_first_request
def before_first_request():
    init_db()

Здесь мы используем декоратор @app.before_first_request, который указывает, что функция before_first_request() вызывается перед тем, как запустится рендер шаблонов.

Готово — наше приложение подключено к базе данных SQLite, а мы можем переходить дальше. Но сперва убедимся, что всё работает. Сохраняем изменения и запускаем приложение:

python app.py

Если перейти по адресу http://127.0.0.1:5000/, то может показаться, что ничего не изменилось. Но если посмотреть в папку с файлами, то можно увидеть там новый файл — database.db. Это и есть наша база данных.

Скриншот: Skillbox Media

Создаём шаблон для поста

Настало время сделать новый и прекрасный шаблон — для постов. Он будет простым: заголовок, текст и ссылка на главную страницу. Создадим в папке templates файл post.html и добавим следующий код:

<!DOCTYPE html>
<html>
<head>
    <title>{{ post.title }}</title>
</head>
<body>
    <h1>{{ post.title }}</h1>
    <p>{{ post.content }}</p>
    <a href="{{ url_for('index') }}">Back to index</a>
</body>
</html>

В момент рендеринга в эту HTML-страницу мы будем передавать пост, который достали из базы данных. У этого поста будут заголовок (title) и основной текст (content), а всё вместе будет лежать внутри объекта post.

Пока всё просто, но обратите внимание на новую функцию — url_for(). Она позволяет перейти на другой маршрут и отрисовать другую HTML-страницу. В нашем случае, если мы нажмём на ссылку Back to index, запустится функция index(), которая перенаправит нас на главную страницу (маршрут /) и отрисует шаблон index.html.

Теперь нам нужно сделать новый маршрут под один из постов в файле app.py:

@app.route('/<int:post_id>')
def get_post(post_id):
    conn = get_db_connection()
    post = conn.execute('SELECT * FROM posts WHERE id = ?', (post_id,)).fetchone()
    conn.close()
    return render_template('post.html', post=post)

Тут уже всё немного сложнее, но обо всём по порядку:

  • @app.route('/<int:post_id>') — задаём новый маршрут. Он будет выглядеть так: www.oursite.com/1. Единица будет указывать на индекс поста из базы данных. <int:post_id> — это ещё одно указание на то, что индекс поста должен быть целым числом (int), а не, например, строкой.
  • get_post(post_id) — передаём айдишник поста, который как раз и «встанет» в URL-адрес и добавится к запросу к базе данных.
  • post = conn.execute ('SELECT * FROM posts WHERE id =? ', (post_id,)).fetchone() — запрашиваем из базы данных пост по нашему айдишнику и берём одну строку функцией fetchone().
  • return render_template ('post.html', post=post) — рендерим HTML-шаблон и передаём туда полученный пост.

Давайте убедимся, что всё работает корректно и страница отрисовывается. Временно напишем «костыль» и вручную добавим пост (исключительно для проверки):

@app.route('/<int:post_id>')
def get_post(post_id):
    conn = get_db_connection()
    conn.execute('INSERT INTO posts (title, content) VALUES ("Random Title", "Lorem ipsum dolor sit amet consectetur adipiscing elit")')
    post = conn.execute('SELECT * FROM posts WHERE id = ?', (post_id,)).fetchone()
    conn.close()
    return render_template('post.html', post=post)

Наш «костыль» — это четвёртая строка. Здесь мы сами вставляем новую строку в базу данных с помощью запроса INSERT. Теперь перейдём по адресу http://127.0.0.1:5000/1:

Скриншот: Skillbox Media

Круто — всё отрисовалось, кнопка «Назад» работает! Идём дальше и не забываем удалить «костыль».

Выводим все посты на главную

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

<!DOCTYPE html>
<html>
<head>
    <title>Blog</title>
</head>
<body>
    <h1>Blog</h1>
    <ul>
        {% for post in posts %}
        <li><a href="{{ url_for('get_post', post_id=post['id']) }}">{{ post['title'] }}</a></li>
        {% endfor %}
    </ul>
</body>
</html>

Главный движ у нас происходит в теге <ul>: мы идём по всем элементам списка posts и для каждого создаём заголовок со ссылкой на пост. При нажатии на ссылку вызывается функция url_for(), а ей передаётся функция-рендер get_post() и ID поста.

Ещё мы немного декорировали заголовок самой страницы. Можете сравнить с прошлой версией.

Если перезапустить приложение, то мы не увидим новых постов, потому что их просто нет в базе данных. Но можно опять заполнить всё вручную. Изменим функцию index():

@app.route('/')
def index():
    conn = get_db_connection()
    conn.execute('INSERT INTO posts (title, content) VALUES ("Why I love Flask", "This is so cool!!!")')
    conn.execute('INSERT INTO posts (title, content) VALUES ("Cats >> Dogs", "It was a joke because they are all so adorable.")')
    posts = conn.execute('SELECT * FROM posts').fetchall()
    conn.close()
    return render_template('index.html', posts=posts)

Видим результат:

Скриншот: Skillbox Media

Правда, если перейти по ссылке, то ничего не отобразится, но и это мы со временем исправим.

Создаём новые посты

Отображение постов работает, осталось добавить возможность создавать новые посты. Для этого создадим новый HTML-шаблон и метод для рендеринга.

В папке templates создаём новый файл add_post.html:

{% extends 'base.html' %}

{% block content %}
  <h1>Add New Post</h1>
  {% with messages = get_flashed_messages() %}
    {% if messages %}
      <ul class="flashes">
        {% for message in messages %}
          <li>{{ message }}</li>
        {% endfor %}
      </ul>
    {% endif %}
  {% endwith %}
  <form method="post">
    <label for="title">Title</label><br>
    <input type="text" id="title" name="title"><br>
    <label for="content">Content</label><br>
    <textarea id="content" name="content"></textarea><br>
    <input type="submit" value="Submit">
  </form>
{% endblock %}

Он будет наследовать файл base.html, а внутри содержать форму, где пользователь указывает заголовок и тело поста. Если он вдруг введёт некорректные данные, то мы покажем ему сообщение об ошибке с помощью флеш-сообщений (когда некорректно заполненное поле подсвечивается красным и у вас нет возможности отправить заполненную форму).

Теперь добавим новый маршрут в файл app.py:

@app.route('/new', methods=['GET', 'POST'])
def new_post():
    if request.method == 'POST':
        title = request.form['title']
        content = request.form['content']

        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('add_post.html')

Этот маршрут обрабатывает GET- и POST-запросы по адресу /new. Если запрос выполняется методом GET, то функция просто отображает форму для ввода данных с помощью шаблона add_post.html. А если запрос выполняется методом POST, мы достаём заголовок и тело поста из формы, а затем добавляем их в базу данных. В конце — редиректим (то есть перенаправляем) пользователя обратно на главную.

Подробнее об HTTP-запросах вы можете прочитать в нашей статье.

Чтобы все эти функции работали, мы также должны их импортировать в начале файла:

from flask import Flask, render_template, request, redirect, url_for

Теперь давайте сохраним свои наработки и запустим приложение:

python app.py

Переходим по адресу http://127.0.0.1:5000/ и видим, что опять ничего не изменилось:

Скриншот: Skillbox Media

Попробуем перейти по адресу http://127.0.0.1:5000/new:

Скриншот: Skillbox Media

Ура! Мы видим нашу форму! Давайте впишем туда что-нибудь и нажмём Submit:

Скриншот: Skillbox Media

Нас перекинуло на главную страницу — и на ней находится наш новый пост. Ура! Всё наконец-то работает!

Скриншот: Skillbox Media

К тому же теперь мы можем перейти по ссылке и посмотреть пост целиком:

Скриншот: Skillbox Media

Но всё ещё есть проблема — нужно добавить кнопку Add new post, чтобы каждый раз не добавлять пост, вбивая в адресную строку наш URL. Для этого нам нужно добавить всего одну строчку в файл index.html:

<!DOCTYPE html>
<html>
<head>
    <title>Blog</title>
</head>
<body>
    <h1>Blog</h1>
    <a href="{{ url_for('new_post') }}"><button>Add New Post</button></a>
    <ul>
        {% for post in posts %}
        <li><a href="{{ url_for('get_post', post_id=post['id']) }}">{{ post['title'] }}</a></li>
        {% endfor %}
    </ul>
</body>
</html>

Мы создали кнопку, нажав которую, мы перейдём на страницу со ссылкой для создания нового поста. Проверяем:

Скриншот: Skillbox Media

Кликаем — переходим куда нужно:

Скриншот: Skillbox Media

Добавили новый пост:

Скриншот: Skillbox Media

Получаем готовый сайт

Наше приложение приобрело следующую структуру:

Blog Flask/
|-- templates/
|   |-- index.html
|   |-- base.html
|   |-- post.html
|   |-- add_post.html
|-- app.py
|-- database.db

В папке templates хранятся HTML-шаблоны: index.html, add_post.html, post.html и base.html. Файл app.py содержит основной код приложения Flask, в котором определены маршруты и функции для работы с базой данных. А файл database.db — это база данных SQLite.

Полный код каждого файла можно посмотреть ниже:

index.html:

<!DOCTYPE html>
<html>
<head>
    <title>Blog</title>
</head>
<body>
    <h1>Blog</h1>
    <a href="{{ url_for('new_post') }}"><button>Add New Post</button></a>
    <ul>
        {% for post in posts %}
        <li><a href="{{ url_for('get_post', post_id=post['id']) }}">{{ post['title'] }}</a></li>
        {% endfor %}
    </ul>
</body>
</html>

base.html:

<!DOCTYPE html>
<html>
  <head>
    <title>{% block title %}{% endblock %}</title>
  </head>
  <body>
    {% block content %}{% endblock %}
  </body>
</html>

post.html:

<!DOCTYPE html>
<html>
<head>
    <title>{{ post.title }}</title>
</head>
<body>
    <h1>{{ post.title }}</h1>
    <p>{{ post.content }}</p>
    <a href="{{ url_for('index') }}">Back to index</a>
</body>
</html>

add_post.html:

{% extends 'base.html' %}

{% block content %}
  <h1>Add New Post</h1>
  {% with messages = get_flashed_messages() %}
    {% if messages %}
      <ul class="flashes">
        {% for message in messages %}
          <li>{{ message }}</li>
        {% endfor %}
      </ul>
    {% endif %}
  {% endwith %}
  <form method="post">
    <label for="title">Title</label><br>
    <input type="text" id="title" name="title"><br>
    <label for="content">Content</label><br>
    <textarea id="content" name="content"></textarea><br>
    <input type="submit" value="Submit">
  </form>
{% endblock %}

app.py:

from flask import Flask, render_template, request, redirect, url_for
import sqlite3

app = Flask(__name__)

def get_db_connection():
    conn = sqlite3.connect('database.db')
    conn.row_factory = sqlite3.Row
    return conn

def close_db_connection(conn):
    conn.close()

def init_db():
    conn = get_db_connection()
    conn.execute('CREATE TABLE IF NOT EXISTS posts (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, content TEXT NOT NULL)')
    conn.close()

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

@app.route('/<int:post_id>')
def get_post(post_id):
    conn = get_db_connection()
    post = conn.execute('SELECT * FROM posts WHERE id = ?', (post_id,)).fetchone()
    conn.close()
    return render_template('post.html', post=post)

@app.route('/new', methods=['GET', 'POST'])
def new_post():
    if request.method == 'POST':
        title = request.form['title']
        content = request.form['content']

        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('add_post.html')

@app.before_first_request
def before_first_request():
    init_db()

if __name__ == '__main__':
    app.run()

Что запомнить

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

Вот некоторые важные вещи, которые стоит помнить при работе с фреймворком Flask:

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

Изучайте IT на практике — бесплатно

Курсы за 2990 0 р.

Я не знаю, с чего начать
Научитесь: Профессия Python-разработчик Узнать больше
Понравилась статья?
Да

Пользуясь нашим сайтом, вы соглашаетесь с тем, что мы используем cookies 🍪

Ссылка скопирована