DevGang
Авторизоваться

Python Flask: полное руководство от основ до продвинутого уровня

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

Анатомия маршрутизации Flask

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

Декоратор @app.route()

По своей сути декоратор @app.route() — это функция Python, которую Flask предоставляет для связывания шаблона URL с функцией. Декоратор принимает путь URL в качестве первого аргумента и, опционально, методы (например, GET, POST) в качестве другого. Когда Flask получает запрос, он сопоставляет URL с этими шаблонами и вызывает связанную функцию. Вот более подробный взгляд на простое определение маршрута:

@app.route('/welcome-astronaut')
def welcome_astronaut():
    return 'Welcome to the Interstellar Space Station!'

В этом примере @app.route('/welcome-astrunaut') сообщает Flask, что всякий раз, когда веб-браузер запрашивает наш URL-адрес, заканчивающийся на /welcome-astrunaut, он должен вызывать функцию welcome_astronaut и отвечать «Welcome to the Interstellar Space Station!».

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

@app.route('/astronaut/<username>')
def show_astronaut_profile(username):
    # Imagine fetching astronaut details from a cosmic database here
    return f'Galactic Explorer Profile: {username}'

В приведенном выше маршруте <username> действует как заполнитель для любого имени, введенного в URL. Flask фиксирует это как переменную username и передает ее в функцию show_astronaut_profile. Этот динамический подход позволяет создавать персонализированный контент с минимальными усилиями.

Указание методов HTTP во Flask

Чтобы разрешить маршруту обрабатывать различные методы HTTP, вы включаете параметр methods в декоратор @app.route(), передавая список методов, которые вы хотите принять. Например, если вы создаете страницу отправки формы, вы можете захотеть обрабатывать как запросы GET, так и запросы POST; GET для получения формы и POST для ее отправки.

Вот как вы можете указать эти методы в своем маршруте:

@app.route('/mission-application', methods=['GET', 'POST'])
def mission_application():
    if request.method == 'POST':
        # Process the mission application submission
        # For example, save applicant details to a database or perform eligibility calculations
        return 'Application for the Mars Mission submitted successfully!'
    # If it's not a POST request, render the mission application form
    return render_template('mission_application_form.html')

В этом примере маршрут /mission-application служит порталом для начинающих астронавтов или сторонников миссии, чтобы подать заявку на путешествие на Марс. Функция mission_application обрабатывает как просмотр формы заявки (через запрос GET), так и отправку формы (через запрос POST). После успешной отправки пользователь получает подтверждение того, что его заявка на миссию на Марс была успешно отправлена, что делает взаимодействие интересным и тематическим для концепции исследования космоса.

Обработка различных методов HTTP

Приведенный выше шаблон типичен для веб-форм и подобных сценариев, где вам может потребоваться отобразить страницу для запросов GET и выполнить действия для запросов POST. Однако гибкость Flask с методами HTTP также позволяет разрабатывать RESTful API, где вы можете использовать такие методы, как PUT, DELETE и т.д., для управления ресурсами.

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

@app.route('/planets', methods=['POST'])
def add_planet():
    # Code to add a new planet to the database
    return 'Planet added to the catalog', 201

@app.route('/planets/<int:planet_id>', methods=['GET'])
def get_planet(planet_id):
    # Code to return details of a specific planet
    return 'Planet details retrieved'

@app.route('/planets/<int:planet_id>', methods=['PUT'])
def update_planet(planet_id):
    # Code to update existing planet details in the database
    return 'Planet information updated'

@app.route('/planets/<int:planet_id>', methods=['DELETE'])
def delete_planet(planet_id):
    # Code to remove a planet from the database
    return 'Planet removed from the catalog', 204

В этом примере маршрут /planets служит конечной точкой для управления каталогом планет. Эта настройка позволяет энтузиастам космоса, астрономам или менеджерам баз данных добавлять новые планеты (POST), извлекать сведения о конкретных планетах (GET), обновлять информацию о существующих планетах (PUT) и удалять планеты из каталога (DELETE). Каждая операция повышает интерактивность базы данных, приглашая пользователей вносить свой вклад и исследовать богатое хранилище знаний о вселенной. Этот API, хотя и практичен, также пробуждает воображение, позволяя пользователям взаимодействовать с необъятностью космоса через структурированный интерфейс RESTful.

Искусство шаблонизации Jinja2: воплощение данных в жизнь

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

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

Быстрое погружение в шаблонизацию

Рассмотрим HTML-файл с именем welcome.html, хранящийся в папке templates:

<!DOCTYPE html>
<html>
    <head>
        <title>Welcome Page</title>
    </head>
    <body>
        <h1>Welcome, {{ name }}!</h1>
    </body>
</html>

Синтаксис {{ name }} обозначает заполнитель переменной. При рендеринге этого шаблона с помощью Flask:

@app.route('/welcome/<name>')
def welcome(name):
    return render_template('welcome.html', name=name)

Flask извлекает файл welcome.html, заменяет {{ name }} значением переменной name, указанной в URL-адресе, и предоставляет пользователю настроенную страницу.

Расширяем крылья Flask: сила расширений

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

Популярные расширения Flask

  • Flask-SQLAlchemy: упрощает операции с базой данных, предлагая уровень ORM для сопоставления классов Python с таблицами базы данных.
  • Flask-WTF: предоставляет инструменты для работы с формами, включая защиту от CSRF и интеграцию с WTForms для проверки.
  • Flask-Login: управляет аутентификацией пользователей, обработкой входов в систему и поддержанием пользовательских сеансов.

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

Начало работы с Flask

Flask построен на двух основных компонентах: Werkzeug, библиотеке веб-приложений WSGI, и Jinja2, движке шаблонов. Его часто называют микрофреймворком, поскольку он сохраняет ядро ​​просто, но расширяемо с помощью многочисленных расширений.

Установка

Чтобы начать работу с Flask, вам сначала необходимо его установить. Предполагая, что в вашей системе установлен Python, вы можете установить Flask с помощью pip:

pip install Flask

Первое веб-приложение

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

Подготовка среды

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

  1. Создайте новый каталог для своего проекта и перейдите в него.
  2. Настройте виртуальную среду для зависимостей Python:
python3 -m venv venv
source venv/bin/activate

3. Установите Flask и компоненты Flask, выполнив:

pip install Flask Flask-SQLAlchemy Flask-Login flask-wtf email_validator

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

/your-flask-app
    ├── app.py                  # Main application file where Flask app is define
    ├── /models                 # Hold the model for db
    │   └── users.py            # The user model
    ├── /forms                  # Hold the forms for our web application
    │   ├── login_form.py               
    │   └── register_form.py
    ├── /templates              # Directory for Jinja2 templates
    │   ├── login.html          # Template for the login page
    │   ├── register.html       # Template for the registration page
    │   └── index.html          # Template for the dashboard/index page
    ├── /instance               # Directory for db file (created upon first run)
    │   └── site.db.            # The db file (created upon first run)
    └── /venv                   # Virtual environment directory (optional but recommended)

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

  • app.py: это центральный файл — место, где ваше приложение Flask оживает. Он отвечает за определение и настройку вашего приложения, подключение URL-адресов к функциям Python и настройку расширений, таких как SQLAlchemy для взаимодействия с базой данных и LoginManager для обработки аутентификации пользователей. Он организует маршрутизацию приложения, функции просмотра и инициализацию базы данных.
  • /models: этот каталог является основой структуры данных вашего приложения, в нем размещаются модели, определяющие схему вашей базы данных. Например, файл users.py в этом каталоге описывает модель User, включающую как Flask-SQLAlchemy db.Model для взаимодействия с базой данных, так и Flask-Login UserMixin для функций аутентификации. Эта модель детализирует атрибуты пользователя, включая idusernameemail и password_hash, а также предоставляет методы для управления паролями.
  • /forms: здесь управляются пользовательский ввод и взаимодействие. Каталог включает классы форм, такие как LoginForm и RegisterForm, созданные с помощью Flask-WTF для определения полей форм и валидаторов. Такая настройка гарантирует, что пользовательские данные будут правильно собраны и проверены, что повышает безопасность и удобство использования.
  • /templates: содержащий шаблоны Jinja2, этот каталог обеспечивает динамическую визуализацию HTML. Шаблоны для входа, регистрации и панели инструментов определяются здесь, что позволяет создать богатый интерактивный пользовательский интерфейс. Язык шаблонов Jinja2 позволяет легко интегрировать логику Python непосредственно в HTML, облегчая создание адаптивных динамических веб-страниц.
  • /instance: эта папка, автоматически сгенерированная при первом запуске вашего приложения, обычно содержит файлы конфигурации и локальные базы данных, такие как site.db для SQLite. Дизайн Flask для поиска папки экземпляра помогает отделить ресурсы, специфичные для экземпляра, от основного кода приложения, что полезно для конфигурации, которая не должна быть передана в систему контроля версий.
  • /venv (необязательно, но рекомендуется): Виртуальная среда имеет решающее значение для управления зависимостями, специфичными для проекта, изолированными от глобальной среды Python. Это гарантирует, что библиотеки вашего проекта будут храниться отдельно, предотвращая конфликты версий и помогая в воспроизводимых настройках разработки.

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

Инициализируйте приложение Flask

Первым шагом является создание нового файла Python app.py, в котором мы настроим наше приложение Flask, настроим базу данных и инициализируем расширения Flask, такие как Flask-Login:

app.py (мы расширим этот файл позже)
# app.py

from flask import Flask
from flask_login import LoginManager
from models.users import db

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key_here'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db.init_app(app)

login_manager = LoginManager(app)
login_manager.login_view = 'login'

Определим модель пользователя

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

models/users.py
# models/users.py

from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()


class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    password_hash = db.Column(db.String(128))

    def set_password(self, password):
        self.password_hash = generate_password_hash(password)

    def check_password(self, password):
        if self.password_hash is None:
            return False
        return check_password_hash(self.password_hash, password)


def init_models(app):
    with app.app_context():
        db.create_all()

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

Мы определяем нашу модель User с помощью Flask-SQLAlchemy, превращая простой класс Python в надежную таблицу базы данных. Эта таблица включает поля для идентификации пользователя, такие как idusernameemail, и password_hash, с определенными ограничениями для поддержания уникальности и безопасности. Этот password_hash имеет решающее значение для защиты паролей пользователей путем их хранения в хешированном формате благодаря функциям безопасности Werkzeug.

Для дальнейшего повышения безопасности паролей наша модель включает методы для установки и проверки паролей. Метод set_password хеширует пароли перед их сохранением, а check_password обеспечивает соответствие попыток входа хешированным паролям в базе данных.

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

Функция user_loader необходима для интеграции Flask-Login, позволяя приложению извлекать данные пользователя для управления сеансом. Инициализируя нашу модель User и определяя эту функцию, мы позволяем Flask-Login поддерживать безопасные сеансы пользователей, что является краеугольным камнем аутентификации пользователей в приложениях Flask.

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

Функция User Loader

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


# app.py

from sqlalchemy.orm import Session
from models.users import init_models, User

# your existing app.py code continues here...

init_models(app)

@login_manager.user_loader
def load_user(user_id):
    with Session(db.engine) as session:
        return session.get(User, int(user_id))

Инициализация модели User с помощью init_models(app) — это важный первый шаг в настройке вашего приложения Flask. Этот процесс подготавливает вашу базу данных, гарантируя ее готовность к плавному хранению, извлечению и управлению пользовательскими данными. После настройки модели становится необходимым определение функции загрузчика пользователей с помощью @login_manager.user_loader. Эта функция, критически важная для аутентификации пользователей, извлекает экземпляры пользователей из базы данных с помощью идентификаторов пользователей. Flask-Login использует это для поддержания сеансов пользователей, вызывая его всякий раз, когда ему нужно идентифицировать сеанс пользователя.

Обновление вашего кода для использования Session.get() вместо Query.get() не только соответствует лучшим практикам для SQLAlchemy, но и проясняет границы транзакций в вашем приложении. Это обновление жизненно важно для обеспечения будущего вашего кода, особенно с учетом предстоящих изменений SQLAlchemy 2.0.

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

Создание маршрутов

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

  • Login: отображение формы входа и обработка отправок данных для входа.
  • Logout: выход из системы и перенаправление пользователя на страницу входа.
  • Register: отображение регистрационной формы и обработка регистрации пользователей.
  • Index/Dashboard: отображение персонализированной информационной панели вошедшим в систему пользователям.

Вот как вы определяете эти маршруты в app.py:

app.py

# app.py

from flask import render_template, redirect, url_for, flash
from flask_login import, login_required, login_user, logout_user, current_user
from forms.login_form import LoginForm
from forms.register_form import RegisterForm
from models.users import User, db

# your existing app.py code continues here...

@app.route('/')
@login_required
def index():
    if not current_user.is_authenticated:
        return redirect(url_for('login'))
    return render_template('index.html', title='Dashboard', username=current_user.username)


@app.route('/login', methods=['GET', 'POST'])
def login():
    if current_user.is_authenticated:
        return redirect(url_for('index'))
    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        if user and user.check_password(form.password.data):
            login_user(user, remember=True)  # Add remember=True parameter
            flash('Logged in successfully!', 'success')
            return redirect(url_for('index'))
        else:
            flash('Invalid username or password', 'danger')
    return render_template('login.html', form=form)


@app.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('login'))


@app.route('/register', methods=['GET', 'POST'])
def register():
    form = RegisterForm()
    if form.validate_on_submit():
        user = User(username=form.username.data, email=form.email.data)
        user.set_password(form.password.data)
        db.session.add(user)
        db.session.commit()
        flash('Registration successful! Please log in.', 'success')
        return redirect(url_for('login'))
    return render_template('register.html', form=form)

Формы

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

forms/login_form.py
# forms/login_form.py

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired


class LoginForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired()])
    password = PasswordField('Password', validators=[DataRequired()])
    submit = SubmitField('Login')
forms/register_form.py
# forms/register_form.py

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, EmailField
from wtforms.validators import DataRequired, Email


class RegisterForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired()])
    email = EmailField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    submit = SubmitField('Register')

Две распространенные формы в веб-приложениях — это формы входа и регистрации, каждая из которых служит определенной цели:

  • Формы входа: эти формы являются шлюзами для доступа пользователей к своим аккаунтам. Типичная форма входа включает поля для имени пользователя и пароля. Это простой, но важный компонент для аутентификации пользователей, гарантирующий, что доступ предоставляется только тем, у кого есть действительные учетные данные.
  • Регистрационные формы: используются для регистрации новых пользователей. Обычно они собирают больше информации, чем форма входа, например, имя пользователя, адрес электронной почты и пароль. Регистрационная форма является первым шагом в создании учетной записи пользователя, что делает ее необходимой для сбора начальных данных пользователя, обеспечивая при этом их действительность.

Шаблоны

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

templates/login.html
<!DOCTYPE html>
<html>
<head>
    <title>Login</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
</head>
<body>
    <div class="container mt-5">
        {% with messages = get_flashed_messages(with_categories=true) %}
            {% if messages %}
                {% for category, message in messages %}
                    <div class="alert alert-{{ category }} alert-dismissible fade show" role="alert">
                        {{ message }}
                        <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                            <span aria-hidden="true">&times;</span>
                        </button>
                    </div>
                {% endfor %}
            {% endif %}
        {% endwith %}

        <h1>Login</h1>
        <form method="POST" action="{{ url_for('login') }}">
            {{ form.csrf_token }}
            <div class="form-group">
                {{ form.username.label }}
                {{ form.username(class="form-control") }}
            </div>
            <div class="form-group">
                {{ form.password.label }}
                {{ form.password(class="form-control") }}
            </div>
            {{ form.submit(class="btn btn-primary") }}
        </form>
        <p class="mt-3">Don't have an account? <a href="{{ url_for('register') }}">Register</a></p>
    </div>
</body>
</html>
templates/register.html
<!DOCTYPE html>
<html>
<head>
    <title>Register</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
</head>
<body>
    <div class="container mt-5">
        <h1>Register</h1>
        <form method="POST" action="{{ url_for('register') }}">
            {{ form.csrf_token }}
            <div class="form-group">
                {{ form.email.label }}
                {{ form.email(class="form-control") }}
            </div>
            <div class="form-group">
                {{ form.username.label }}
                {{ form.username(class="form-control") }}
            </div>
            <div class="form-group">
                {{ form.password.label }}
                {{ form.password(class="form-control") }}
            </div>
            {{ form.submit(class="btn btn-primary") }}
        </form>
    </div>
</body>
</html>
templates/index.html
<!DOCTYPE html>
<html>
<head>
    <title>{{ title }}</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
</head>
<body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <a class="navbar-brand" href="#">First Flask App</a>
        <div class="collapse navbar-collapse" id="navbarNav">
            <ul class="navbar-nav ml-auto">
                <li class="nav-item">
                    <a class="nav-link" href="{{ url_for('logout') }}">Logout</a>
                </li>
            </ul>
        </div>
    </nav>

    <div class="container mt-5">
        <h1>Welcome, {{ username }}!</h1>
        <p>This is the dashboard.</p>
    </div>
</body>
</html>

Запуск вашего приложения Flask

Наконец, чтобы ваше приложение ожило, добавьте следующее в конец вашего app.py:

# app.py

# your existing app.py code continues here...

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

Эта команда запускает ваше приложение Flask. По умолчанию веб-сервер определен по адресу http://127.0.0.1:5000. Просто откройте этот адрес в своем веб-браузере.

Вот окончательная версия файла app.py:

# app.py

from flask import Flask, render_template, redirect, url_for, flash
from flask_login import LoginManager, login_required, login_user, logout_user, current_user
from sqlalchemy.orm import Session
from forms.login_form import LoginForm
from forms.register_form import RegisterForm
from models.users import init_models, User, db

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key_here'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db.init_app(app)

login_manager = LoginManager(app)
login_manager.login_view = 'login'
init_models(app)


@login_manager.user_loader
def load_user(user_id):
    with Session(db.engine) as session:
        return session.get(User, int(user_id))


@app.route('/')
@login_required
def index():
    if not current_user.is_authenticated:
        return redirect(url_for('login'))
    return render_template('index.html', title='Dashboard', username=current_user.username)


@app.route('/login', methods=['GET', 'POST'])
def login():
    if current_user.is_authenticated:
        return redirect(url_for('index'))
    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        if user and user.check_password(form.password.data):
            login_user(user, remember=True)  # Add remember=True parameter
            flash('Logged in successfully!', 'success')
            return redirect(url_for('index'))
        else:
            flash('Invalid username or password', 'danger')
    return render_template('login.html', form=form)


@app.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('login'))


@app.route('/register', methods=['GET', 'POST'])
def register():
    form = RegisterForm()
    if form.validate_on_submit():
        user = User(username=form.username.data, email=form.email.data)
        user.set_password(form.password.data)
        db.session.add(user)
        db.session.commit()
        flash('Registration successful! Please log in.', 'success')
        return redirect(url_for('login'))
    return render_template('register.html', form=form)


if __name__ == '__main__':
    app.run(debug=True)
Экран входа в систему
Экран входа в систему
Экран регистрации
Экран регистрации
Экран приборной панели
Экран приборной панели

Вы также можете найти весь код:

Источник

#Flask #Python
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу