Поиск по сайту:

Как структурировать большое приложение Flask с помощью Flask Blueprints и Flask-SQLAlchemy


Автор выбрал программу Write for DOnations.

Введение

Flask-SQLAlchemy — это расширение Flask, которое упрощает использование SQLAlchemy с Flask, предоставляя инструменты и методы для взаимодействия с вашей базой данных в ваших приложениях Flask.

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

Например, в приложении для социальных сетей у вас могут быть маршруты для пользователей в файле с именем routes.py внутри каталога с именем users, а затем вы можете собрать базу данных модели для пользователей внутри модуля с именем users.py внутри каталога models. Затем вы можете сделать то же самое для сообщений, подписчиков, хэштегов, вопросов, ответов, рекламы, торговой площадки, платежей и других функций в своем большом приложении для социальных сетей. Если вы хотите отредактировать некоторую бизнес-логику в коде платежей, вы можете изменить код базы данных для платежей в файле, расположенном по адресу mysocialapp/models/payment.py, а затем изменить бизнес-логику в файле, расположенном в mysocialapp/payments/routes.py. Код каждой части приложения будет изолирован в разных файлах и каталогах, эффективно разделяя приложение на простые в управлении компоненты. Эта структура также помогает познакомить новых разработчиков с вашим приложением, чтобы они знали, где устранить проблему или добавить новую функцию.

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

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

Предпосылки

  • Локальная среда программирования Python 3, которую вы можете настроить, следуя руководству для вашего дистрибутива в серии Как установить и настроить локальную среду программирования для Python 3. В этом руководстве мы назовем каталог нашего проекта flask_app.
  • Понимание основных концепций Flask, таких как маршруты, функции просмотра и шаблоны. Если вы не знакомы с Flask, ознакомьтесь с разделом «Как использовать шаблоны в приложении Flask».
  • Понимание основных концепций HTML. Вы можете просмотреть нашу серию учебных пособий «Как создать веб-сайт с помощью HTML», чтобы получить базовые знания.
  • Понимание основных концепций Flask-SQLAlchemy, таких как настройка базы данных, создание моделей базы данных и вставка данных в базу данных. Дополнительные сведения см. в разделе Как использовать Flask-SQLAlchemy для взаимодействия с базами данных в приложении Flask.

Структура целевого приложения

К концу руководства вы создадите приложение Flask со следующей структурой:

.
└── flask_app
    ├── app
    │   ├── extensions.py
    │   ├── __init__.py
    │   ├── main
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   ├── models
    │   │   ├── post.py
    │   │   └── question.py
    │   ├── posts
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   ├── questions
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   └── templates
    │       ├── base.html
    │       ├── index.html
    │       ├── posts
    │       │   ├── categories.html
    │       │   └── index.html
    │       └── questions
    │           └── index.html
    ├── app.db
    └── config.py

Внутри вашего каталога flask_app у вас будет файл базы данных app.db и файл конфигурации config.py для вашего приложения Flask. Основное приложение Flask будет находиться в каталоге app, в котором будет специальный файл __init__.py, чтобы сделать его пакетом для правильной работы импорта, и оно будет содержать функция для создания экземпляра приложения Flask.

Каталог app будет содержать файл extensions.py для управления расширениями Flask, которые вы будете использовать в своем приложении (в этом руководстве Flask-SQLAlchemy является примером использования Расширение фляги). У вас также будут следующие каталоги:

  • main: основная схема основных маршрутов, таких как домашняя страница.
  • сообщения: схема управления сообщениями в блоге.
  • questions: схема вопросов для управления вопросами и ответами.
  • models: каталог, который будет содержать модели Flask-SQLAlchemy.
  • templates: каталог шаблонов, который будет содержать файлы для основного чертежа и каталог для каждого чертежа.

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

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

В каталоге flask_app активируйте виртуальную среду:

  1. source my_env/bin/activate

Активировав виртуальную среду, используйте pip для установки Flask и Flask-SQLAlchemy:

  1. pip install Flask Flask-SQLAlchemy

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

Output
Successfully installed Flask-2.1.2 Flask-SQLAlchemy-2.5.1 Jinja2-3.1.2 MarkupSafe-2.1.1 SQLAlchemy-1.4.39 Werkzeug-2.1.2 click-8.1.3 greenlet-1.1.2 itsdangerous-2.1.2

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

Шаг 2 — Создание файла конфигурации

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

В каталоге flask_app откройте новый файл с именем config.py. Этот файл будет содержать конфигурацию вашего приложения Flask:

  1. nano config.py

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

import os

basedir = os.path.abspath(os.path.dirname(__file__))


class Config:
    SECRET_KEY = os.environ.get('SECRET_KEY')
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URI')\
        or 'sqlite:///' + os.path.join(basedir, 'app.db')
    SQLALCHEMY_TRACK_MODIFICATIONS = False

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

Вы импортируете модуль os для доступа к вашей файловой системе. Вы используете os для установки базового каталога с os.path.abspath(os.path.dirname(__file__)) для правильной настройки пути к файлу базы данных.

Вы используете класс с именем Config и устанавливаете значения конфигурации, используя переменные класса. Здесь вы устанавливаете три конфигурации:

  • SECRET_KEY: длинная случайная строка, используемая Flask в качестве секретного ключа или ключа, используемого для защиты сеансов, которые запоминают информацию от одного запроса к другому. Пользователь может получить доступ к информации, хранящейся в сеансе, но не может изменить ее, если у него нет секретного ключа, поэтому вы никогда не должны позволять никому получать доступ к вашему секретному ключу. Просмотрите объект os.environ, используя его метод get(). (Хотя вам не нужно устанавливать секретный ключ, чтобы следовать этому руководству, вы можете просмотреть примечание в конце этого списка для получения инструкций о том, как установить секретный ключ.)
  • SQLALCHEMY_DATABASE_URI: URI базы данных указывает базу данных, с которой вы хотите установить соединение с помощью SQLAlchemy. В этом случае вы либо получаете его из переменной среды DATABASE_URI, либо устанавливаете значение по умолчанию. Значение URI по умолчанию здесь соответствует формату sqlite:///path/to/app.db. Вы используете функцию os.path.join(), чтобы соединить базовый каталог, который вы создали и сохранили в переменной basedir, и app.db имя файла. При этом создание приложения Flask без установки переменной среды DATABASE_URI по умолчанию будет подключаться к файлу базы данных app.db в вашем каталоге flask_app. Файл будет создан при создании таблиц базы данных. Если вы хотите установить URI базы данных для другого механизма SQL, см. Шаг 2 в разделе «Как использовать Flask-SQLAlchemy для взаимодействия с базами данных в приложении Flask».
  • SQLALCHEMY_TRACK_MODIFICATIONS: конфигурация для включения или отключения отслеживания изменений объектов. Вы устанавливаете его в False, чтобы отключить отслеживание и использовать меньше памяти. Для получения дополнительной информации вы можете прочитать страницу конфигурации в документации Flask-SQLAlchemy.

Примечание. В этом руководстве вы не будете устанавливать секретный ключ, потому что вы не будете использовать функции, требующие секретного ключа. Однако, если вам нужно установить секретный ключ, вы можете установить его следующим образом (для Windows используйте set вместо export):

  1. export SECRET_KEY="your secret key"

Точно так же вы можете установить URI базы данных следующим образом (используйте set в Windows):

  1. export DATABASE_URI="postgresql://username:password@host:port/database_name"

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

Шаг 3 — Создание фабрики приложений Flask

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

На этом этапе руководства структура вашего каталога flask_app выглядит следующим образом (исключая каталог виртуальной среды):

.
├── flask_app
   └── config.py

Основной код вашего приложения будет находиться внутри каталога проекта, который будет пакетом Python. В этом руководстве мы назовем его app, но вы можете использовать имя своего проекта или другое распространенное имя каталога, например src, core, или что-то подобное.

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

Чтобы сделать каталог проекта app пакетом Python, вы создадите внутри него специальный файл __init__.py, который помечает каталоги как пакеты Python. Этот файл __init__.py будет содержать код для вашей функции фабрики Flask, которую вы будете использовать для установки и создания экземпляра приложения Flask, в котором вы связываете все свои чертежи вместе. Думайте о фабричной функции как о центральной функции, в которой все ваши компоненты Flask (чертежи) объединены в одно приложение и которую вы можете использовать для создания разных экземпляров приложений Flask для разных целей с разными конфигурациями. Например, вы можете использовать фабричную функцию для создания экземпляра приложения Flask для тестирования с соответствующими конфигурациями для тестирования.

Внутри вашего каталога flask_app создайте новый каталог app:

  1. mkdir app

Затем откройте новый файл __init__.py в каталоге app:

  1. nano app/__init__.py

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

from flask import Flask

from config import Config

def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)

    # Initialize Flask extensions here

    # Register blueprints here

    @app.route('/test/')
    def test_page():
        return '<h1>Testing the Flask Application Factory Pattern</h1>'

    return app

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

В этом файле вы импортируете класс Flask из пакета flask. Затем вы импортируете класс конфигурации Config из файла config.py, который вы создали в каталоге flask_app на предыдущем шаге.

Функция create_app() — это функция фабрики приложений Flask. Он создает экземпляр приложения с именем app из класса Flask(), используя знакомую строку app=Flask(__name__). Вы настраиваете приложение, импортируя значения конфигурации из объекта с помощью метода app.config.from_object(), передавая ему значение параметра config_class, который содержит Config в качестве значения по умолчанию. Вы будете инициализировать свои расширения Flask под комментарием # Инициализировать расширения Flask здесь и зарегистрировать свои схемы приложений под комментарием # Зарегистрировать схемы здесь после их создания.

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

Наконец, фабричная функция create_app() возвращает экземпляр приложения, созданный вами с помощью строки return app.

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

Находясь в каталоге flask_app с активированной виртуальной средой, вы сообщите Flask, где находится фабричная функция, передав имя каталога основного приложения app в качестве значения переменная окружения FLASK_APP. Затем вы установите для переменной среды FLASK_ENV значение development, чтобы запустить приложение в режиме разработки и получить доступ к отладчику. Дополнительные сведения об отладчике Flask см. в разделе Как обрабатывать ошибки в приложении Flask.

Во-первых, установите пакет app в качестве места, где Flask должен искать фабричную функцию create_app():

  1. export FLASK_APP=app

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

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

  1. export FLASK_ENV=development

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

  1. flask run

При работающем сервере разработки перейдите по следующему URL-адресу в браузере:

http://127.0.0.1:5000/test/

Сайт загрузится с заголовком Testing the Flask Application Factory Pattern.

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

Шаг 4 — Создание чертежей фляги

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

На этом этапе руководства структура вашего каталога flask_app выглядит следующим образом (исключая каталог виртуальной среды):

.
├── flask_app
    ├── app
    │   └── __init__.py
    └── config.py

Создание основного чертежа и визуализация его шаблонов

Теперь вы создадите основной план приложения и визуализируете его шаблоны.

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

Перейдите в каталог flask_app в новом терминале. Затем создайте каталог с именем main для вашего основного проекта внутри каталога app:

  1. mkdir app/main

Затем откройте новый основной файл __init__.py в новом каталоге main:

  1. nano app/main/__init__.py

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

from flask import Blueprint

bp = Blueprint('main', __name__)

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

Здесь вы импортируете класс Blueprint из пакета flask. Затем вы используете этот класс для создания объекта схемы bp, передавая ему два аргумента: имя (в данном случае main) и специальный __name__ переменная, которая содержит имя текущего модуля Python.

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

Затем вы создадите файл routes.py в каталоге main схемы, в котором будут храниться маршруты основной схемы. Откройте новый файл routes.py в вашем основном каталоге чертежей:

  1. nano app/main/routes.py

Вы будете создавать маршруты, используя объект bp. Добавьте следующий маршрут в новый файл:

from app.main import bp


@bp.route('/')
def index():
    return 'This is The Main Blueprint'

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

Здесь вы импортируете объект схемы bp из основной схемы, к которой вы обращаетесь через app.main. В строке импорта app — это пакет проекта, main — основной пакет схемы, а bp — объект, который вы объявили в основной схеме схемы. файл __init__.py.

Вы используете объект bp для создания маршрута / и функцию просмотра index() с bp.route(), похожий на знакомый декоратор app.route().

Чтобы Flask использовал эти маршруты и сделал их импортируемыми непосредственно из схемы, вам необходимо импортировать этот файл routes.py в файл __init__.py вашей схемы. Откройте его для редактирования:

  1. nano app/main/__init__.py

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

from flask import Blueprint

bp = Blueprint('main', __name__)

from app.main import routes

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

С этим дополнением при регистрации чертежа будут также зарегистрированы его маршруты.

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

Откройте файл app/__init__.py, чтобы отредактировать фабричную функцию:

  1. nano app/__init__.py

Отредактируйте фабричную функцию create_app(), чтобы она соответствовала следующему блоку, добавив выделенные строки:

...
def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)

    # Initialize Flask extensions here

    # Register blueprints here
    from app.main import bp as main_bp
    app.register_blueprint(main_bp)

    @app.route('/test/')
    def test_page():
        return '<h1>Testing the Flask Application Factory Pattern</h1>'

    return app

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

Вы импортируете объект схемы bp из основной схемы и переименовываете его в main_bp для удобства чтения. Затем вы используете метод app.register_blueprint(), чтобы зарегистрировать этот основной план для того, чтобы Flask рассматривал его как часть приложения.

При работающем сервере разработки перейдите по следующему URL-адресу:

http://127.0.0.1:5000/

Страница загрузится с текстом This is The Main Blueprint, текстом, который вы вернули в основном маршруте.

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

Откройте файл routes.py основной схемы для модификации:

  1. nano app/main/routes.py

Отредактируйте файл с выделенными строками:

from flask import render_template
from app.main import bp

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

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

Здесь вы импортируете функцию render_template() и используете ее в маршруте для рендеринга файла шаблона с именем index.html.

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

Создайте каталог шаблонов внутри вашего каталога app:

  1. mkdir app/templates

Откройте новый файл с именем base.html в качестве базового шаблона:

  1. nano app/templates/base.html

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %} {% endblock %} - FlaskApp</title>
    <style>
        h2 {
            width: 100%;
        }

        .title {
            margin: 5px;
            width: 100%;
        }

        .content {
            margin: 5px;
            width: 100%;
            display: flex;
            flex-direction: row;
            flex-wrap: wrap;
        }

        .post {
            flex: 20%;
            padding: 10px;
            margin: 5px;
            background-color: #f3f3f3;
            inline-size: 100%;
        }

        .title a {
            color: #00a36f;
            text-decoration: none;
        }

        nav a {
            color: #d64161;
            font-size: 3em;
            margin-left: 50px;
            text-decoration: none;
        }

    </style>
</head>
<body>
    <nav>
        <a href="{{ url_for('main.index') }}">FlaskApp</a>
        <a href="#">Posts</a>
        <a href="#">Categories</a>
        <a href="#">Questions</a>
    </nav>
    <hr>
    <div class="content">
        {% block content %} {% endblock %}
    </div>
</body>
</html>

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

Этот базовый шаблон содержит шаблон HTML, который вы будете повторно использовать в других своих шаблонах.

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

Вы используете синтаксис blueprint_name.view_function_name для ссылки на маршрут при использовании функции url_for() со схемами. Индексная страница обрабатывается функцией просмотра index() в основной схеме; поэтому вы передаете main.index функции url_for() для создания ссылки.

Теперь создайте файл index.html, который вы визуализировали в функции просмотра index() основной схемы:

  1. nano app/templates/index.html

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

{% extends 'base.html' %}

{% block content %}
    <span class="title"><h1>{% block title %} The Home Page of FlaskApp {% endblock %}</h1></span>
    <div class="content">
        <h2>This is the main Flask blueprint</h2>
    </div>
{% endblock %}

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

Здесь вы расширяете базовый шаблон. Вы заменяете блок контента, используя заголовок <h1>, который также служит заголовком, и заголовок <h2>, указывающий, что индексная страница является частью основного плана Flask. .

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

http://127.0.0.1:5000/

Будет загружена страница, похожая на следующее изображение:

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

Создание схемы постов и рендеринг ее шаблонов

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

На этом этапе руководства структура вашего каталога flask_app выглядит следующим образом (исключая каталог виртуальной среды):

.
├── flask_app
    ├── app
    │   ├── __init__.py
    │   ├── main
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   └── templates
    │       ├── base.html
    │       └── index.html
    └── config.py

Чтобы создать новый план для сообщений в блоге, выполните те же действия, что и в предыдущем разделе.

Сначала создайте новый каталог posts для хранения файлов схемы:

  1. mkdir app/posts

Затем откройте новый файл __init__.py в новом каталоге posts:

  1. nano app/posts/__init__.py

Создайте объект схемы bp и импортируйте маршруты, которые вы создадите, в файл схемы routes.py:

from flask import Blueprint

bp = Blueprint('posts', __name__)


from app.posts import routes

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

В предыдущем блоке кода вы используете posts в качестве имени схемы. Вы также импортируете маршруты из файла routes.py, который вы еще не создали.

Затем откройте новый файл routes.py, в который вы поместите маршруты для схемы сообщений:

  1. nano app/posts/routes.py

Добавьте в этот файл следующие маршруты:

from flask import render_template
from app.posts import bp

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

@bp.route('/categories/')
def categories():
    return render_template('posts/categories.html')

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

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

В маршруте index вы визуализируете файл шаблона с путем posts/index.html, что означает, что Flask будет искать каталог с именем posts. в каталоге templates, а затем найдите файл index.html внутри каталога posts.

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

Теперь создайте новый каталог posts внутри вашего каталога шаблонов:

  1. mkdir app/templates/posts

Затем создайте новый файл index.html в каталоге posts. Это файл, который вы визуализируете в функции представления index() схемы сообщений:

  1. nano app/templates/posts/index.html

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

{% extends 'base.html' %}

{% block content %}
    <span class="title"><h1>{% block title %} The Posts Page {% endblock %}</h1></span>
    <div class="content">
        <h2>This is the posts Flask blueprint</h2>
    </div>
{% endblock %}

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

Здесь вы расширяете базовый шаблон. Вы также устанавливаете заголовок <h1> в качестве заголовка и заголовок <h2>, чтобы пометить страницу как часть плана сообщений.

Затем создайте новый файл categories.html в каталоге posts. Это файл, который вы визуализировали в функции просмотра categories() схемы сообщений:

  1. nano app/templates/posts/categories.html

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

{% extends 'base.html' %}

{% block content %}
    <span class="title"><h1>{% block title %} Categories {% endblock %}</h1></span>
    <div class="content">
        <h2>This is the categories page within the posts blueprint</h2>
    </div>
{% endblock %}

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

Вы расширяете базовый шаблон и устанавливаете заголовок <h1> в качестве заголовка и заголовок <h2>, чтобы пометить страницу как часть плана сообщений.

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

Откройте файл app/__init__.py, чтобы отредактировать фабричную функцию:

  1. nano app/__init__.py

Отредактируйте фабричную функцию create_app(), добавив выделенные строки:


def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)

    # Initialize Flask extensions here

    # Register blueprints here
    from app.main import bp as main_bp
    app.register_blueprint(main_bp)

    from app.posts import bp as posts_bp
    app.register_blueprint(posts_bp, url_prefix='/posts')

    @app.route('/test/')
    def test_page():
        return '<h1>Testing the Flask Application Factory Pattern</h1>'

    return app

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

Здесь вы импортировали объект схемы bp из пакета схемы сообщений и переименовали его в posts_bp для удобства чтения.

Вы регистрируете схему сообщений с помощью метода app.register_blueprint(), передавая ему объект схемы posts_bp. Вы также передаете ему значение /posts для параметра url_prefix, который будет префикс маршрутов схемы с этой строкой. Например, основной маршрут / схемы постов станет доступен через /posts/, а маршрут /categories будет через /сообщения/категории/.

Зарегистрировав план новых сообщений и запустив сервер разработки, используйте браузер для перехода по следующим URL-адресам:

http://127.0.0.1:5000/posts/
http://127.0.0.1:5000/posts/categories/

Заголовок The Posts Page будет загружаться для страницы http://127.0.0.1:5000/posts/. Заголовок «Категории» будет загружен для страницы http://127.0.0.1:5000/posts/categories/.

Чтобы ссылки «Записи» и «Категории» в панели навигации работали, откройте базовый шаблон для модификации:

  1. nano app/templates/base.html

Измените тег <nav> с выделенными выражениями:

    <nav>
        <a href="{{ url_for('main.index') }}">FlaskApp</a>
        <a href="{{ url_for('posts.index') }}">Posts</a>
        <a href="{{ url_for('posts.categories') }}">Categories</a>
        <a href="#">Questions</a>
    </nav>

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

Вы связываетесь с индексом сообщений с помощью вызова функции url_for(posts.index) и со страницей категорий с помощью url_for(posts.categories).

Обновите любую страницу в своем приложении, чтобы активировать функции ссылки на публикации и категории.

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

Создание схемы вопросов и визуализация ее шаблонов

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

На этом этапе руководства структура вашего каталога flask_app выглядит следующим образом (исключая каталог виртуальной среды):

.
├── flask_app
    ├── app
    │   ├── __init__.py
    │   ├── main
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   ├── posts
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   └── templates
    │       ├── base.html
    │       ├── index.html
    │       └── posts
    │           ├── categories.html
    │           └── index.html
    └── config.py

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

  1. mkdir app/questions

Затем откройте новый файл __init__.py в новом каталоге questions:

  1. nano app/questions/__init__.py

Создайте объект схемы bp и импортируйте маршруты, которые вы позже создадите, в файл схемы routes.py:

from flask import Blueprint

bp = Blueprint('questions', __name__)

from app.questions import routes

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

В предыдущем блоке кода вы используете questions в качестве имени схемы. Вы также импортируете маршруты из файла routes.py, который вы еще не создали.

Затем откройте новый файл routes.py, в который вы поместите маршруты для схемы вопросов:

  1. nano app/questions/routes.py

Добавьте в этот файл следующие маршруты:

from flask import render_template
from app.questions import bp

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

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

Вы создаете маршрут /, используя объект схемы questions, отображая файл шаблона с именем index.html внутри каталога с именем questions, который вы создадите в папке шаблонов.

Создайте каталог questions внутри каталога templates, а затем откройте в нем файл index.html:

  1. mkdir app/templates/questions
  2. nano app/templates/questions/index.html

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

{% extends 'base.html' %}

{% block content %}
    <span class="title">
        <h1>{% block title %} Questions {% endblock %}</h1>
    </span>
    <div class="questions">
        <h2>Questions Blueprint</h2>
    </div>
{% endblock %}

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

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

Теперь откройте app/__init__.py, чтобы зарегистрировать схему вопросов в фабричной функции create_app():

  1. nano app/__init__.py

Отредактируйте фабричную функцию create_app(), добавив выделенные строки:


def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)

    # Initialize Flask extensions here

    # Register blueprints here
    from app.main import bp as main_bp
    app.register_blueprint(main_bp)

    from app.posts import bp as posts_bp
    app.register_blueprint(posts_bp, url_prefix='/posts')

    from app.questions import bp as questions_bp
    app.register_blueprint(questions_bp, url_prefix='/questions')

    @app.route('/test/')
    def test_page():
        return '<h1>Testing the Flask Application Factory Pattern</h1>'

    return app

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

Вы регистрируете схему вопросов так же, как и схему сообщений, добавляя к ее маршрутам префикс /questions.

Когда ваш сервер разработки запущен, используйте браузер для перехода по следующему URL-адресу:

http://127.0.0.1:5000/questions/

На странице будут отображаться заголовки вопросов и вопросов.

Теперь вы сделаете ссылку «Вопросы» функциональной. Откройте базовый шаблон для редактирования панели навигации:

  1. nano app/templates/base.html

Измените тег <nav> с выделенным выражением:

    <nav>
        <a href="{{ url_for('main.index') }}">FlaskApp</a>
        <a href="{{ url_for('posts.index') }}">Posts</a>
        <a href="{{ url_for('posts.categories') }}">Categories</a>
        <a href="{{ url_for('questions.index') }}">Questions</a>
    </nav>

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

Здесь вы ссылаетесь на индексную страницу вопросов, используя вызов функции url_for(questions.index).

Обновите любую страницу в приложении, чтобы активировать функцию ссылки «Вопросы» на панели навигации.

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

Шаг 5 — Добавление моделей Flask-SQLAlchemy в ваше приложение Flask

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

На этом этапе руководства структура вашего каталога flask_app выглядит следующим образом (исключая каталог виртуальной среды):

.
├── flask_app
    ├── app
    │   ├── __init__.py
    │   ├── main
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   ├── posts
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   ├── questions
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   └── templates
    │       ├── base.html
    │       ├── index.html
    │       ├── posts
    │       │   ├── categories.html
    │       │   └── index.html
    │       └── questions
    │           └── index.html
    └── config.py

Создание файла для управления расширениями Flask и интеграции Flask-SQLAlchemy

Чтобы добавить расширение Flask-SQLAlchemy в свое приложение, вы сначала добавите модуль Python с именем extensions.py, в котором вы будете настраивать различные расширения Flask, в свое app каталог.

Откройте новый файл extensions.py в каталоге app:

  1. nano app/extensions.py

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

from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()

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

Здесь вы импортируете класс SQLAlchemy() из пакета Flask-SQLAlchemy, а затем используете его для создания объекта базы данных db без аргументов.

Вы будете использовать этот объект db для интеграции SQLAlchemy с приложением Flask, которое вы создаете в своей фабричной функции. Откройте файл app/__init__.py, чтобы отредактировать заводскую функцию:

  1. nano app/__init__.py

Отредактируйте файл, чтобы импортировать и инициализировать объект базы данных:

from flask import Flask

from config import Config
from app.extensions import db

def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)

    # Initialize Flask extensions here
    db.init_app(app)

    # Register blueprints here
    from app.main import bp as main_bp
    app.register_blueprint(main_bp)

    from app.posts import bp as posts_bp
    app.register_blueprint(posts_bp, url_prefix='/posts')

    from app.questions import bp as questions_bp
    app.register_blueprint(questions_bp, url_prefix='/questions')

    @app.route('/test/')
    def test_page():
        return '<h1>Testing the Flask Application Factory Pattern</h1>'

    return app

Здесь вы импортируете объект базы данных db из созданного ранее модуля app.extensions. Прежде чем регистрировать схемы, вы подключаете объект базы данных к экземпляру приложения app с помощью метода db.init_app(). При этом вы можете использовать свой объект db для создания и взаимодействия с моделями Flask-SQLAlchemy в вашем приложении.

Помните, что вы настроили Flask-SQLAlchemy с помощью объекта Config в файле config.py внутри вашего каталога flask_app. Вы можете открыть этот файл для быстрого напоминания:

  1. nano config.py
import os

basedir = os.path.abspath(os.path.dirname(__file__))

class Config:
    SECRET_KEY = os.environ.get('SECRET_KEY')
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URI')\
        or 'sqlite:///' + os.path.join(basedir, 'app.db')
    SQLALCHEMY_TRACK_MODIFICATIONS = False

Если вы не настроите переменную среды DATABASE_URI, объект db по умолчанию будет подключаться к файлу SQLite с именем app.db. который появится в вашем каталоге flask_app после создания таблиц базы данных. Закройте файл, когда закончите просмотр.

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

  1. export FLASK_APP=app
  2. export FLASK_ENV=development

Откройте оболочку Flask:

  1. flask shell

Импортируйте объект db из модуля app.extensions, затем распечатайте его:

  1. from app.extensions import db
  2. print(db)

Вы получите путь к базе данных, подобный следующему:

Output
<SQLAlchemy engine=sqlite:///your_path_to_flask_app/app.db>

Этот вывод означает, что объект db был правильно зарегистрирован. Если вы получаете сообщение об ошибке при запуске кода в оболочке Flask, убедитесь, что вы правильно зарегистрировали объект db в своей фабричной функции, прежде чем переходить к следующему разделу. Вы можете выйти из оболочки Flask, набрав exit().

Создание модели публикации и взаимодействие с ней

В больших приложениях у вас могут быть сотни таблиц базы данных, а это значит, что вам потребуется написать сотни моделей SQLAlchemy для управления ими. Помещение всех ваших моделей в один файл усложнит поддержку вашего приложения, поэтому вы разделите свои модели на отдельные файлы Python внутри каталога models. Каждый файл будет содержать модели и функции, относящиеся к определенной части вашего приложения. Например, вы можете поместить модели и функции для управления сообщениями в файл post.py в каталоге с именем models в каталоге app.

На этом этапе руководства структура вашего каталога flask_app выглядит следующим образом (исключая каталог виртуальной среды):

.
├── flask_app
    ├── app
    │   ├── extensions.py
    │   ├── __init__.py
    │   ├── main
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   ├── posts
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   ├── questions
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   └── templates
    │       ├── base.html
    │       ├── index.html
    │       ├── posts
    │       │   ├── categories.html
    │       │   └── index.html
    │       └── questions
    │           └── index.html
    └── config.py

Чтобы создать модель базы данных для сообщений в собственном файле, сначала создайте каталог с именем models внутри вашего каталога app:

  1. mkdir app/models

Затем откройте новый файл с именем post.py в каталоге ваших моделей:

  1. nano app/models/post.py

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

from app.extensions import db

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(150))
    content = db.Column(db.Text)

    def __repr__(self):
        return f'<Post "{self.title}">'

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

Вы импортируете объект базы данных db из модуля app.extensions. Затем вы создаете модель базы данных Flask-SQLAlchemy с именем Post, используя класс db.Model. В модели у вас есть столбец с целочисленным идентификатором в качестве первичного ключа (id), столбец для хранения строк для заголовка сообщения (title) и текстовый столбец для содержимое (content). Вы используете специальный метод __repr__(), чтобы предоставить строковое представление для каждого объекта записи, используя его заголовок. Чтобы узнать больше о Flask-SQLAlchemy, вы можете прочитать Как использовать Flask-SQLAlchemy для взаимодействия с базами данных в приложении Flask.

Затем откройте оболочку Flask, чтобы создать таблицу сообщений на основе модели сообщений:

  1. flask shell

Запустите следующий код, чтобы создать таблицу сообщений:

  1. from app.extensions import db
  2. from app.models.post import Post
  3. db.create_all()

Вы импортируете объект db из модуля app.extensions и модель Post из app.models.post. модуль. Затем вы используете метод create_all() для создания таблицы сообщений.

Код должен выполняться без вывода. Если вы получили сообщение об ошибке, проверьте файлы app/extensions.py и app/models/post.py и просмотрите предыдущие шаги, чтобы убедиться, что вы выполнили их так, как написано. .

Примечание. Функция db.create_all() не воссоздает и не обновляет таблицу, если она уже существует. Например, если вы хотите изменить свою модель, добавив новый столбец, и поэтому запускаете функцию db.create_all(), изменение, которое вы вносите в модель, не будет применено к таблице, если таблица уже существует в базе данных. Решение состоит в том, чтобы удалить все существующие таблицы базы данных с помощью функции db.drop_all(), а затем воссоздать их с помощью функции db.create_all() следующим образом:

  1. db.drop_all()
  2. db.create_all()

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

Затем запустите следующий код, чтобы создать десять случайных сообщений:

  1. import random
  2. for i in range(0, 10):
  3. random_num = random.randrange(1, 1000)
  4. post = Post(title=f'Post #{random_num}',
  5. content=f'Content #{random_num}')
  6. db.session.add(post)
  7. print(post)
  8. print(post.content)
  9. print('--')
  10. db.session.commit()

Вы импортируете объект базы данных db, модель базы данных Post и модуль Python random. Вы будете использовать этот модуль для генерации случайных чисел для создания образцов постов с разными заголовками и содержанием. Вы используете цикл for с функцией Python range() для повторения блока кода десять раз.

В цикле for вы используете метод random.randrange() для генерации случайного целого числа от 1 до 1000 и сохраните его в переменной с именем random_num. Затем вы создаете объект сообщения, используя модель Post, и используете случайное число в переменной random_num для создания образца заголовка и содержания сообщения.

Затем вы добавляете объект post в сеанс базы данных, распечатываете сам объект и его содержимое и фиксируете транзакцию.

Вы получите результат, аналогичный следующему, но с другими числами:

Output
<Post "Post #58"> Content #58 -- <Post "Post #55"> Content #55 -- <Post "Post #994"> Content #994 -- <Post "Post #394"> Content #394 -- <Post "Post #183"> Content #183 -- <Post "Post #633"> Content #633 -- <Post "Post #790"> Content #790 -- <Post "Post #883"> Content #883 -- <Post "Post #259"> Content #259 -- <Post "Post #581"> Content #581 --

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

Оставьте оболочку Flask запущенной и откройте новое окно терминала. Источник вашей среды и перейдите в папку вашего приложения.

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

  1. nano app/posts/routes.py

Отредактируйте импорт и маршрут индекса, добавив выделенные строки:

from flask import render_template
from app.posts import bp
from app.extensions import db
from app.models.post import Post


@bp.route('/')
def index():
    posts = Post.query.all()
    return render_template('posts/index.html', posts=posts)

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

Вы импортируете объект базы данных db и модель Post. Вы получаете все сообщения в базе данных, а затем передаете их в шаблон индекса сообщений.

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

  1. nano app/templates/posts/index.html

Отредактируйте файл, добавив выделенные строки:

{% extends 'base.html' %}

{% block content %}
    <span class="title"><h1>{% block title %} The Posts Page {% endblock %}</h1></span>
    <div class="content">
        <h2>This is the posts Flask blueprint</h2>
        {% for post in posts %}
            <div class="post">
                <p><b>#{{ post.id }}</b></p>
                <p class="title">
                    <b>
                        <a href="#">
                            {{ post.title }}
                        </a>
                    </b>
                </p>
                <div class="content">
                    <p>{{ post.content }}</p>
                </div>
                <hr>
            </div>
        {% endfor %}
    </div>
{% endblock %}

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

Здесь вы просматриваете сообщения и отображаете идентификатор, заголовок и содержимое каждого сообщения.

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

http://127.0.0.1:5000/posts/

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

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

Создание модели вопроса и взаимодействие с ней

Вы создали модель постов и взаимодействовали с ней в плане постов. Теперь вы добавите модель базы данных вопросов для управления вопросами и ответами.

На этом этапе руководства структура вашего каталога flask_app выглядит следующим образом (исключая каталог виртуальной среды):

.
├── flask_app
    ├── app
    │   ├── extensions.py
    │   ├── __init__.py
    │   ├── main
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   ├── models
    │   │   └── post.py
    │   ├── posts
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   ├── questions
    │   │   ├── __init__.py
    │   │   └── routes.py
    │   └── templates
    │       ├── base.html
    │       ├── index.html
    │       ├── posts
    │       │   ├── categories.html
    │       │   └── index.html
    │       └── questions
    │           └── index.html
    ├── app.db
    └── config.py

Чтобы создать модель базы данных вопросов, откройте новый файл с именем question.py в каталоге моделей:

  1. nano app/models/question.py

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

from app.extensions import db

class Question(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.Text)
    answer = db.Column(db.Text)

    def __repr__(self):
        return f'<Question {self.content}>'

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

Здесь вы импортируете объект базы данных db из модуля app.extensions. Затем вы создаете модель с именем Question, используя класс db.Model. В модели у вас есть целочисленный столбец идентификатора в качестве первичного ключа (id), текстовый столбец для содержания вопроса (content) и текстовый столбец для его ответа. (ответ). Затем вы используете специальный метод __repr__() для представления каждого вопроса с использованием его содержимого.

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

  1. flask shell

Запустите следующий код, чтобы создать таблицу вопросов и добавить в нее несколько вопросов и ответов:

  1. from app.extensions import db
  2. from app.models.question import Question
  3. db.create_all()
  4. q1 = Question(content='Why is the sky blue?', answer='Because... Why not?')
  5. q2 = Question(content='What is love?', answer='A portal to the underworld.')
  6. db.session.add_all([q1, q2])
  7. db.session.commit()

Код должен выполняться без вывода. Если вы получили сообщение об ошибке, проверьте файл app/models/question.py, чтобы убедиться, что код написан с правильным синтаксисом.

Вы импортируете объект базы данных и модель вопросов, затем используете db.create_all() для создания таблицы и, наконец, добавляете два объекта вопросов в сеанс базы данных и фиксируете транзакцию.

Выйдите из оболочки Flask:

  1. exit()

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

  1. nano app/questions/routes.py

Отредактируйте файл, добавив выделенные строки:

from flask import render_template
from app.questions import bp
from app.models.question import Question

@bp.route('/')
def index():
    questions = Question.query.all()
    return render_template('questions/index.html', questions=questions)

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

Здесь вы импортируете модель вопросов, получаете все вопросы из базы данных, а затем передаете их в шаблон индекса вопросов.

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

  1. nano app/templates/questions/index.html

Отредактируйте файл, добавив выделенные строки:

{% extends 'base.html' %}

{% block content %}
    <span class="title">
        <h1>{% block title %} Questions {% endblock %}</h1>
    </span>
    <div class="questions">
        <h2>Questions Blueprint</h2>

        <div class="question">
            <div class="new-question">
                <form method="POST">
                    <p>
                        <textarea id="q-content"
                                name="content"
                                placeholder="Question"
                                cols="30" rows="3"></textarea>
                    </p>
                    <textarea id="q-answer"
                            name="answer"
                            placeholder="Answer"
                            cols="30" rows="3"></textarea>
                    <p><input type="submit"></p>
                </form>
            </div>
            <div class="questions-list">
                {% for question in questions %}
                    <div class="question">
                        <h4>{{ question.content }}</h4>
                        <p>{{ question.answer }}</p>
                        <hr>
                    </div>
                {% endfor %}
            </div>
        </div>

    </div>
{% endblock %}

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

Здесь вы создаете форму с двумя текстовыми областями: одна для содержания вопроса и одна для ответа. Затем вы добавляете кнопку отправки для формы.

Под формой вы перебираете переменную questions, которую вы передали из индексного маршрута вопросов, отображая содержание каждого вопроса и ответ.

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

http://127.0.0.1:5000/questions/

Страница будет загружена с заголовком проекта, формой отправки и двумя примерами вопросов:

Однако заполнение и отправка формы приведет к ошибке HTTP 405 Method Not Allowed, поскольку форма отправляет запрос POST на индексный маршрут вопросов, а маршрут не принимать и не обрабатывать запросы POST. Чтобы решить эту проблему и сделать форму функциональной, вы измените индексный маршрут схемы вопросов и будете использовать данные формы для добавления новых вопросов в базу данных.

Откройте файл схемы вопросов routes.py:

  1. nano app/questions/routes.py

Отредактируйте файл, добавив выделенные строки:

from flask import render_template, request, url_for, redirect
from app.questions import bp
from app.models.question import Question
from app.extensions import db

@bp.route('/', methods=('GET', 'POST'))
def index():
    questions = Question.query.all()

    if request.method == 'POST':
        new_question = Question(content=request.form['content'],
                                answer=request.form['answer'])
        db.session.add(new_question)
        db.session.commit()
        return redirect(url_for('questions.index'))

    return render_template('questions/index.html', questions=questions)

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

Вы разрешаете методы GET и POST, передавая кортеж (GET, POST) в параметр methods. Вы обрабатываете запросы POST в условии if request.method == POST:. В нем вы создаете новый объект вопроса, используя содержимое, и отвечаете, отправленное пользователем, которое вы получаете из объекта request.form. Вы добавляете новый вопрос в сеанс базы данных, фиксируете транзакцию, а затем перенаправляете пользователя на индексную страницу вопросов.

Теперь форма будет работать, и вы сможете добавлять новые вопросы и ответы в свою базу данных. Вы можете протестировать эту функцию по URL-адресу http://127.0.0.1:5000/questions/.

Вы интегрировали Flask-SQLAlchemy со своим приложением, добавив каталог для моделей, чтобы упорядочить код.

Вы можете сравнить свои окончательные файлы с кодом, хранящимся в репозитории сообщества DigitalOcean.

Заключение

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

Пример веб-приложения теперь состоит из трех основных компонентов, которые можно расширять различными способами:

  • Основной план: вы можете добавить страницу с информацией или страницу контактов, чтобы пользователи могли связаться с владельцем приложения.
  • Схема сообщений: вы можете добавлять страницы для создания, редактирования, удаления и сортировки сообщений. Вы также можете добавлять теги к сообщениям, используя отношение базы данных «многие ко многим» с помощью Flask-SQLAlchemy.
  • План вопросов: вы можете добавить страницы для управления вопросами и использовать отношение базы данных «один ко многим» с Flask-SQLAlchemy, чтобы создать еще одну таблицу для ответов, чтобы вопрос мог иметь несколько решений.

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

Если вы хотите узнать больше о Flask, ознакомьтесь с другими руководствами из серии How To Build Web Applications with Flask.