🐍 Самоучитель по Python для начинающих. Часть 23: Основы веб-разработки на Flask

Покажем, как писать маршруты и функции представления, использовать шаблоны и работать с базами данных. В конце статьи – 10 мини-проектов, от модулей инвентаризации и учета товаров до приложения для хранения заметок и блога.
6
🐍 Самоучитель по Python для начинающих. Часть 23: Основы веб-разработки на Flask

Flask – компактный фреймворк для быстрой разработки веб-приложений. Он предоставляет минимальную необходимую функциональность и не навязывает никаких строгих правил в отношении структуры и архитектуры приложения (как это делает Django).

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

Основные преимущества Flask:

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

Установка

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

        python -m venv fproject\venv
    

Перейдите в только что созданную директорию:

        cd fproject
    

Активируйте окружение:

        venv\scripts\activate
    

И установите Flask:

        pip install flask
    

Активировать виртуальное окружение нужно перед каждым сеансом работы с Flask.

🐍🎓 Библиотека собеса по Python
Подтянуть свои знания по Python вы можете на нашем телеграм-канале «Библиотека собеса по Python»
🐍🧩 Библиотека задач по Python
Интересные задачи по Python для практики можно найти на нашем телеграм-канале «Библиотека задач по Python»

Простейшее приложение на Flask

Напишем приложение, которое будет выводить традиционное приветствие Hello, World! в браузере. Сохраните этот код в файле app.py в директории fproject:

        from flask import Flask

app = Flask(__name__)

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

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

    

Этот код создает объект приложения Flask с помощью класса Flask и присваивает его переменной app. Декоратор @app.route('/') устанавливает маршрут для главной страницы нашего приложения, а метод def hello() определяет, что будет отображаться на этой странице.

if __name__ == '__main__': проверяет, запускается ли данный файл как самостоятельное приложение, или импортируется как модуль. В нашем случае он запускается как независимое приложение, поэтому вызывается метод app.run(), который запускает веб-сервер Flask.

Запустите приложение в командой строке:

        (venv) C:\Users\User\fproject>app.py

    

Откройте адрес http://localhost:5000/ в браузере:

🐍 Самоучитель по Python для начинающих. Часть 23: Основы веб-разработки на Flask

Flask по умолчанию использует порт 5000. При желании его можно изменить на более привычный 8000:

        app.run(port=8000)
    

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

        app.run(debug=True)
    

Для остановки сервера нажмите Ctrl+C.

Маршруты в Flask

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

        from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
    return 'Это главная страница.'

@app.route('/about')
def about():
    return 'Здесь будет информация об авторе сайта.'

@app.route('/blog')
def blog():
    return 'Это блог с заметками о работе и увлечениях.'

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

    

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

🐍 Самоучитель по Python для начинающих. Часть 23: Основы веб-разработки на Flask

Переменные в маршрутах

В URL можно передавать различные значения. Запустите этот код и перейдите по адресу, например, http://localhost:5000/user/EvilAdmin

        from flask import Flask

app = Flask(__name__)

@app.route('/user/<username>')
def user_profile(username):
    return f"Это профиль пользователя {username}"

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

    

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

🐍 Самоучитель по Python для начинающих. Часть 23: Основы веб-разработки на Flask

А так можно передать в маршруте целое число:

        from flask import Flask

app = Flask(__name__)

@app.route('/user/<int:user_id>')
def user_profile(user_id):
    return f"Это профиль пользователя с ID {user_id}"

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

    

Перейдите по адресу, например, http://localhost:5000/user/5:

🐍 Самоучитель по Python для начинающих. Часть 23: Основы веб-разработки на Flask
Ваш путь в IT начинается с Python
Онлайн-курс «Основы программирования на Python» от Proglib academy предлагает 32 практических урока с персональной обратной связью от экспертов, где вы создадите 4 реальных проекта для портфолио и получите все необходимые навыки для старта карьеры в IT.

GET- и POST-запросы

GET и POST – это HTTP-запросы, которые используются для отправки данных между клиентом и сервером.

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

POST-запрос используют для отправки данных на сервер. При выполнении POST-запроса клиент отправляет данные на сервер, а сервер их обрабатывает. POST-запросы обычно применяют для отправки форм, с данными из которых нужно что-то сделать на бэкенде.

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

        from flask import Flask, request, render_template

app = Flask(__name__)

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        # проверка логина и пароля
        return 'Вы вошли в систему!'
    else:
        return render_template('login.html')

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

    

Маршрут @app.route('/login', methods=['GET', 'POST']) обрабатывает и POST, и GET-запросы: в первом случае он отправит данные на сервер, во втором – просто выведет страницу с формой авторизации.

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

        {% extends 'base.html' %}

{% block content %}
  <div class="container">
    <div class="row justify-content-center mt-5">
      <div class="col-md-6">
        <div class="card">
          <div class="card-header">
            <h1 class="text-center">Вход на сайт</h1>
          </div>
          <div class="card-body">
            {% with messages = get_flashed_messages() %}
              {% if messages %}
                <div class="alert alert-danger">
                  <ul>
                    {% for message in messages %}
                      <li>{{ message }}</li>
                    {% endfor %}
                  </ul>
                </div>
              {% endif %}
            {% endwith %}
            <form method="post">
              <div class="mb-3">
                <label for="username" class="form-label">Логин:</label>
                <input type="text" class="form-control" id="username" name="username" required>
              </div>
              <div class="mb-3">
                <label for="password" class="form-label">Пароль:</label>
                <input type="password" class="form-control" id="password" name="password" required>
              </div>
              <div class="text-center">
                <button type="submit" class="btn btn-primary">Войти</button>
              </div>
            </form>
          </div>
        </div>
      </div>
    </div>
  </div>
{% endblock %}
    

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

🐍 Самоучитель по Python для начинающих. Часть 23: Основы веб-разработки на Flask

Шаблонизатор Jinja2

Шаблоны в Flask используются для динамического формирования веб-страниц. Шаблоны представляют собой HTML страницы, в которые можно передавать любые данные с бэкенда. К шаблонам можно подключать любые CSS-фреймворки типа Bootstrap и Tailwind, и любые JS-скрипты.

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

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

Наследование работает так:

  • Базовый шаблон, который обычно называется base.html, содержит общую разметку для сайта.
  • В base.html подключаются локальные и CDN-фреймворки (CSS, JS), задаются фоновые изображения и фавикон.
  • Дочерние шаблоны наследуют этот базовый шаблон и дополняют его своим собственным контентом.

Продемонстрируем наследование на примере. Сохраните в папке templates два файла. Это содержимое файла base.html – в нем подключается CSS-фреймворк Bootstrap, кастомные стили custom.css из статической папки static, иконки Font Awesome:

        <!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>{% block title %}{% endblock %}</title>
    <!-- Bootstrap стили -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <!-- иконки fontawesome -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
    <!-- кастомные стили -->
    <link rel="stylesheet" href="{{ url_for('static', filename='custom.css') }}">
</head>
<body>

<!-- навигация -->
<nav class="navbar navbar-expand-lg navbar-light bg-light">
    <div class="container">
        <a class="navbar-brand" href="#">Мой личный сайт</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse"
                data-bs-target="#navbarNav" aria-controls="navbarNav"
                aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse justify-content-end"
             id="navbarNav">
            <ul class="navbar-nav">
                <li class="nav-item">
                    <a class="nav-link" href="#">Главная</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Обо мне</a>
                </li>
            </ul>
        </div>
    </div>
</nav>

<!-- контент дочерних шаблонов -->
<div class="container my-3">
    {% block content %}
    {% endblock %}
</div>

</body>
</html>

    

Шаблон base.html также содержит верхнее меню для навигации по сайту – это меню будут наследовать все дочерние шаблоны. Вот пример дочернего шаблона about.html:

        {% extends 'base.html' %}

{% block title %}Мое резюме{% endblock %}

{% block content %}
    <div class="container my-5">
        <h1 class="text-center mb-4">Мое резюме</h1>
        <div class="row">
            <div class="col-md-6">
                <h2>Образование</h2>
                <h4>Московский политехнический институт</h4>
                <p class="mb-0">Бакалавр Computer Science</p>
                <p class="text-muted">2016 - 2020</p>
            </div>
            <div class="col-md-6">
                <h2>Опыт работы</h2>
                <h4>Web Developer - XYZ компания</h4>
                <p class="mb-0">2019 - н.в.</p>
                <p class="text-muted">- Разработка и поддержка веб-приложений</p>
                <p class="text-muted">- Работа с Python, Django, HTML/CSS, JavaScript, MySQL</p>
            </div>
        </div>
        <div class="row mt-5">
            <div class="col-md-6">
                <h2>Навыки</h2>
                <ul class="list-group">
                    <li class="list-group-item border-0 py-1"><i class="fa fa-cog"></i> Python</li>
                    <li class="list-group-item border-0 py-1"><i class="fa fa-cog"></i> Django</li>
                    <li class="list-group-item border-0 py-1"><i class="fa fa-cog"></i> HTML/CSS</li>
                    <li class="list-group-item border-0 py-1"><i class="fa fa-cog"></i> JavaScript</li>
                </ul>
            </div>
            <div class="col-md-6">
                <h2>Проекты</h2>
                <h4>Сайт для продажи автомобилей</h4>
                <p class="text-muted mb-0">- Разработка сайта с использованием Django</p>
                <p class="text-muted">- Интеграция с API маркетплейса для получения данных об автомобилях</p>
                <h4>Игровой блог</h4>
                <p class="text-muted mb-0">- Разработка блога с использованием Django</p>
                <p class="text-muted">- Возможность создавать учeтные записи пользователей и писать комментарии</p>
            </div>
        </div>
        <div class="row mt-5">
            <div class="col-md-6">
                <h2>Контакты</h2>
                <p class="mb-0"><i class="fa fa-phone"></i> Телефон: +990123456789</p>
                <p class="mb-0"><i class="fa fa-envelope"></i> Email: example@example.com</p>
                <p class="mb-0"><i class="fa fa-github"> GitHub: <a href="https://github.com/example"></i>example</a></p>
            </div>
            <div class="col-md-6">
                <h2>Языки</h2>
                <ul class="list-group">
                    <li class="list-group-item border-0 py-1"><i class="fa fa-check-circle"></i> Английский (C1)</li>
                    <li class="list-group-item border-0 py-1"><i class="fa fa-check-circle"></i> Немецкий (B2)</li>
                    <li class="list-group-item border-0 py-1"><i class="fa fa-check-circle"></i> Русский (родной)</li>
                </ul>
            </div>
        </div>
    </div>
{% endblock %}

    

Фон страницы шаблонизатор берет из файла static/customs.css:

        body {
    background-color: #e5e5e5;
}

    

А код для вывода страницы выглядит так:

        from flask import Flask, render_template

app = Flask(__name__)

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

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

    

Запустите приложение, откройте адрес http://localhost:5000/about:

🐍 Самоучитель по Python для начинающих. Часть 23: Основы веб-разработки на Flask
***

Отлично! Вы освоили основы веб-разработки на Flask и научились создавать многостраничные сайты.

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

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

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

МЕРОПРИЯТИЯ

Комментарии

 
 

ВАКАНСИИ

Добавить вакансию

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ

Подпишись

на push-уведомления