From 4420a1a09757a53b0e3a934d439eeefb790f709f Mon Sep 17 00:00:00 2001 From: igor Date: Wed, 28 Jan 2026 04:44:23 +0000 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D1=82?= =?UTF-8?q?=D1=8C=20Home?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Home.md | 1446 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1446 insertions(+) create mode 100644 Home.md diff --git a/Home.md b/Home.md new file mode 100644 index 0000000..208f2cb --- /dev/null +++ b/Home.md @@ -0,0 +1,1446 @@ +# Создание веб-приложения на Python с использованием фреймворка Flask + + +С помощью этого руководства вы с нуля разработаете простое веб-приложение — мини-блог, в котором пользователь сможет создавать, просматривать, редактировать и удалять посты. Для этого в {{ yandex-cloud }} вы создадите виртуальную машину {{ compute-full-name }} и запустите на ней веб-сервер. + +Веб-приложение написано на языке [Python](https://www.python.org/) и использует СУБД [SQLite](https://sqlite.org/) для работы с данными. Визуальное оформление выполнено с помощью [инструментария Bootstrap](https://getbootstrap.com/). + +В качестве основы приложения выбран фреймворк [Flask](https://flask.palletsprojects.com/en/3.0.x/), как один из наиболее доступных фреймворков для создания веб-приложений на языке программирования Python. + +Фреймворк Flask позволяет создавать веб-приложения c использованием всего одного файла с исходным кодом, не требует соблюдения какой-то определенной структуры директорий или написания сложного шаблонного кода перед началом использования. Также Flask предоставляет набор инструментов [Werkzeug](https://werkzeug.palletsprojects.com/en/latest/) и [механизм шаблонов Jinja](http://jinja.palletsprojects.com/) для динамического создания HTML-страниц. + +Исходный код приложения доступен в файле [flask_blog.zip](https://github.com/yandex-cloud-examples/yc-web-app-python-flask/blob/main/flask_blog.zip). + +Схема работы создаваемого веб-приложения: + +![layout](../../_assets/tutorials/flask-layout.svg) + +1. HTTP-запросы поступают из браузера пользователя на виртуальную машину под управлением ОС Linux Ubuntu с установленным и запущенным веб-сервером Flask. +1. Веб-сервер передает запрос в веб-приложение, маршрутизатор которого в зависимости от URL запроса вызывает подходящую функцию-обработчик. +1. Функция-обработчик выполняет запрос к базе данных SQLite, чтобы получить или записать необходимые данные. +1. Полученные из БД данные функция передает в подходящий HTML-шаблон Jinja, который возвращает готовый HTML-код страницы. +1. Полученный HTML-код передается на веб-сервер, который в свою очередь передает этот код в браузер пользователя. + +Чтобы создать веб-приложение с помощью Flask: + +1. [Подготовьте облако к работе](#before-you-begin). +1. [Создайте и настройте виртуальную машину](#create-setup-vm). +1. [Создайте и запустите приложение](#create-app). +1. [Создайте и настройте шаблоны HTML](#html-templates). +1. [Настройте базу данных](#configure-data-base). +1. [Настройте отображение постов блога](#display-posts). +1. [Добавьте действия с постами](#add-post-actions). +1. [Подведите итоги](#results). + +Если веб-приложение вам больше не нужно, [удалите все используемые им ресурсы](#clear-out). + +## Перед началом работы {#before-you-begin} + +В {{ yandex-cloud }} оплачиваются только потребленные ресурсы и время их фактического использования, а для идентификации пользователя, оплачивающего такие ресурсы, нужен платежный аккаунт. + +В стоимость поддержки создаваемого приложения входят: + +* плата за использование публичного IP-адреса (см. [тарифы {{ vpc-full-name }}](../../vpc/pricing.md)); +* плата за вычислительные ресурсы и диски ВМ (см. [тарифы {{ compute-full-name }}](../../compute/pricing.md)). + +{% include [before-you-begin](../../_tutorials/_tutorials_includes/before-you-begin.md) %} + +### Создайте облачную сеть и подсеть {#create-network} + +В {{ yandex-cloud }} ресурсы связаны между собой и с интернетом при помощи [облачных сетей](../../vpc/concepts/network.md#network), в которых ресурсам выделяются [публичные](../../vpc/concepts/address.md#public-addresses) IP-адреса, а также диапазоны внутренних IP-адресов или [подсети](../../vpc/concepts/network.md#subnet). + +Чтобы создать виртуальную сеть и подсеть для вашего веб-сервера: + +{% list tabs group=instructions %} + +- Консоль управления {#console} + + 1. В [консоли управления]({{ link-console-main }}) выберите ваш каталог. + 1. В списке сервисов выберите **{{ ui-key.yacloud.iam.folder.dashboard.label_vpc }}**. + 1. Справа сверху нажмите кнопку **{{ ui-key.yacloud.vpc.networks.button_create }}**. + 1. В поле **{{ ui-key.yacloud.vpc.networks.create.field_name }}** укажите `webserver-network`. + 1. В поле **{{ ui-key.yacloud.vpc.networks.create.field_advanced }}** отключите опцию **{{ ui-key.yacloud.vpc.networks.create.field_is-default }}**. + 1. Нажмите кнопку **{{ ui-key.yacloud.vpc.networks.button_create }}**. + 1. На панели слева выберите ![subnets](../../_assets/vpc/subnets.svg) **{{ ui-key.yacloud.vpc.switch_networks }}**. + 1. Справа сверху нажмите **{{ ui-key.yacloud.common.create }}**. + 1. В поле **{{ ui-key.yacloud.vpc.subnetworks.create.field_name }}** укажите `webserver-subnet-{{ region-id }}-b`. + 1. В поле **{{ ui-key.yacloud.vpc.subnetworks.create.field_zone }}** выберите зону доступности `{{ region-id }}-b`. + 1. В поле **{{ ui-key.yacloud.vpc.subnetworks.create.field_network }}** выберите облачную сеть `webserver-network`. + 1. В поле **{{ ui-key.yacloud.vpc.subnetworks.create.field_ip }}** укажите `192.168.1.0/24`. + 1. Нажмите кнопку **{{ ui-key.yacloud.vpc.subnetworks.create.button_create }}**. + +- CLI {#cli} + + 1. Создайте сеть `webserver-network`: + + ```bash + yc vpc network create webserver-network + ``` + + Результат: + + ```text + id: enp1gg8kr3pv******** + folder_id: b1gt6g8ht345******** + created_at: "2023-12-20T20:08:11Z" + name: webserver-network + default_security_group_id: enppne4l2eg5******** + ``` + + Подробнее о команде `yc vpc network create` читайте в [справочнике CLI](../../cli/cli-ref/vpc/cli-ref/network/create.md). + + 1. Создайте подсеть в зоне доступности `{{ region-id }}-b`: + + ```bash + yc vpc subnet create webserver-subnet-{{ region-id }}-b \ + --zone {{ region-id }}-b \ + --network-name webserver-network \ + --range 192.168.1.0/24 + ``` + + Результат: + + ``` + id: e2li9tcgi7ii******** + folder_id: b1gt6g8ht345******** + created_at: "2023-12-20T20:11:16Z" + name: webserver-subnet-{{ region-id }}-b + network_id: enp1gg8kr3pv******** + zone_id: {{ region-id }}-b + v4_cidr_blocks: + - 192.168.1.0/24 + ``` + + Подробнее о команде `yc vpc subnet create` читайте в [справочнике CLI](../../cli/cli-ref/vpc/cli-ref/subnet/create.md). + +- API {#api} + + 1. Чтобы создать сеть, воспользуйтесь методом REST API [create](../../vpc/api-ref/Network/create.md) для ресурса [Network](../../vpc/api-ref/Network/index.md) или вызовом gRPC API [NetworkService/Create](../../vpc/api-ref/grpc/Network/create.md). + + 1. Чтобы создать подсеть, воспользуйтесь методом REST API [create](../../vpc/api-ref/Subnet/create.md) для ресурса [Subnet](../../vpc/api-ref/Subnet/index.md) или вызовом gRPC API [SubnetService/Create](../../vpc/api-ref/grpc/Subnet/create.md). + +{% endlist %} + +### Создайте группу безопасности {#create-sg} + +[Группы безопасности](../../vpc/concepts/security-groups.md) служат основным механизмом разграничения сетевого доступа в {{ yandex-cloud }} и помогают ограничить для облачных ресурсов несанкционированный трафик на уровне облачной сети. + +Создайте группу безопасности, разрешающую входящий TCP-трафик для портов `5000` и `22`, а также любой исходящий трафик. Порт `22` необходим для подключения к ВМ по SSH, порт `5000` по умолчанию используется для работы веб-сервера Flask. + +{% list tabs group=instructions %} + +- Консоль управления {#console} + + 1. В [консоли управления]({{ link-console-main }}) выберите ваш каталог. + 1. В списке сервисов выберите **{{ ui-key.yacloud.iam.folder.dashboard.label_vpc }}**. + 1. На панели слева выберите ![image](../../_assets/vpc/security-group.svg) **{{ ui-key.yacloud.vpc.label_security-groups }}**. + 1. Нажмите кнопку **{{ ui-key.yacloud.vpc.network.security-groups.button_create }}**. + 1. В поле **{{ ui-key.yacloud.vpc.network.security-groups.forms.field_sg-name }}** укажите имя `webserver-sg`. + 1. В поле **{{ ui-key.yacloud.vpc.network.security-groups.forms.field_sg-network }}** выберите созданную ранее сеть `webserver-network`. + 1. В блоке **{{ ui-key.yacloud.vpc.network.security-groups.forms.label_section-rules }}** [создайте](../../vpc/operations/security-group-add-rule.md) следующие правила для управления трафиком: + + | Направление
трафика | {{ ui-key.yacloud.vpc.network.security-groups.forms.field_sg-rule-description }} | {{ ui-key.yacloud.vpc.network.security-groups.forms.field_sg-rule-port-range }} | {{ ui-key.yacloud.vpc.network.security-groups.forms.field_sg-rule-protocol }} | {{ ui-key.yacloud.vpc.network.security-groups.forms.field_sg-rule-source }} /
{{ ui-key.yacloud.vpc.network.security-groups.forms.field_sg-rule-destination }} | {{ ui-key.yacloud.vpc.network.security-groups.forms.field_sg-rule-cidr-blocks }} | + | --- | --- | --- | --- | --- | --- | + | Входящий | `Flask` | `5000` | `TCP` | `{{ ui-key.yacloud.vpc.network.security-groups.forms.value_sg-rule-destination-cidr }}` | `0.0.0.0/0` | + | Входящий | `ssh` | `22` | `TCP` | `{{ ui-key.yacloud.vpc.network.security-groups.forms.value_sg-rule-destination-cidr }}` | `0.0.0.0/0` | + | Исходящий | `any` | `Весь` | `{{ ui-key.yacloud.vpc.network.security-groups.forms.value_any }}` | `{{ ui-key.yacloud.vpc.network.security-groups.forms.value_sg-rule-destination-cidr }}` | `0.0.0.0/0` | + + 1. Нажмите кнопку **{{ ui-key.yacloud.common.save }}**. + +- CLI {#cli} + + Выполните команду: + + ```bash + yc vpc security-group create \ + --name webserver-sg \ + --rule "description=Flask,direction=ingress,port=5000,protocol=tcp,v4-cidrs=[0.0.0.0/0]" \ + --rule "description=ssh,direction=ingress,port=22,protocol=tcp,v4-cidrs=[0.0.0.0/0]" \ + --rule "description=any,direction=egress,port=any,protocol=any,v4-cidrs=[0.0.0.0/0]" \ + --network-name webserver-network + ``` + + Результат: + + ```text + id: enpv1c0q7j01******** + folder_id: b1gt6g8ht345******** + created_at: "2024-03-23T18:54:05Z" + name: webserver-sg + network_id: enp9mji1m7b3******** + status: ACTIVE + rules: + - id: enpmbsk2hjfd******** + description: Flask + direction: INGRESS + ports: + from_port: "5000" + to_port: "5000" + protocol_name: TCP + protocol_number: "6" + cidr_blocks: + v4_cidr_blocks: + - 0.0.0.0/0 + - id: enpna5id9265******** + description: ssh + direction: INGRESS + ports: + from_port: "22" + to_port: "22" + protocol_name: TCP + protocol_number: "6" + cidr_blocks: + v4_cidr_blocks: + - 0.0.0.0/0 + - id: enpen3vf7rui******** + description: any + direction: EGRESS + protocol_name: ANY + protocol_number: "-1" + cidr_blocks: + v4_cidr_blocks: + - 0.0.0.0/0 + ``` + + Сохраните полученный идентификатор (`id`) группы безопасности: он потребуется при создании виртуальной машины. + + Подробнее о команде `yc vpc security-group create` читайте в [справочнике CLI](../../cli/cli-ref/vpc/cli-ref/security-group/create.md). + +- API {#api} + + Чтобы создать группу безопасности, воспользуйтесь методом REST API [create](../../vpc/api-ref/SecurityGroup/create.md) для ресурса [SecurityGroup](../../vpc/api-ref/SecurityGroup/index.md) или вызовом gRPC API [SecurityGroupService/Create](../../vpc/api-ref/grpc/SecurityGroup/create.md). + +{% endlist %} + +## Создайте и настройте виртуальную машину {#create-setup-vm} + +[Виртуальная машина](../../compute/concepts/vm.md) — это аналог сервера в облачной инфраструктуре. В {{ yandex-cloud }} вы можете создавать +виртуальные машины с самыми разными аппаратными характеристиками по [производительности](../../compute/concepts/performance-levels.md), объему оперативной памяти и [дискового пространства](../../compute/concepts/disk.md#maximum-disk-size), а также под управлением разных [операционных систем](../../compute/concepts/image.md#public). + +Создаваемое веб-приложение будет развернуто на виртуальной машине под управлением OC Linux [Ubuntu 22.04 LTS](/marketplace/products/yc/ubuntu-22-04-lts). + +1. Создайте виртуальную машину: + + Перед тем как приступать к созданию виртуальной машины, [подготовьте](../../compute/operations/vm-connect/ssh.md#creating-ssh-keys) пару ключей (открытый и закрытый) для доступа к ВМ по SSH. + + {% list tabs group=instructions %} + + - Консоль управления {#console} + + 1. В [консоли управления]({{ link-console-main }}) выберите [каталог](../../resource-manager/concepts/resources-hierarchy.md#folder), в котором будет создана ВМ. + 1. В списке сервисов выберите **{{ ui-key.yacloud.iam.folder.dashboard.label_compute }}**. + 1. На панели слева выберите ![image](../../_assets/console-icons/server.svg) **{{ ui-key.yacloud.compute.instances_jsoza }}**. + 1. Нажмите кнопку **{{ ui-key.yacloud.compute.instances.button_create }}**. + 1. В блоке **{{ ui-key.yacloud.compute.instances.create.section_image }}** выберите образ [Ubuntu 22.04 LTS](/marketplace/products/yc/ubuntu-22-04-lts). + 1. В блоке **{{ ui-key.yacloud.k8s.node-groups.create.section_allocation-policy }}** выберите [зону доступности](../../overview/concepts/geo-scope.md) `{{ region-id }}-b`. + 1. В блоке **{{ ui-key.yacloud.compute.instances.create.section_network }}**: + + * В поле **{{ ui-key.yacloud.component.compute.network-select.field_subnetwork }}** выберите созданную ранее подсеть `webserver-subnet-{{ region-id }}-b`. + * В поле **{{ ui-key.yacloud.component.compute.network-select.field_external }}** выберите `{{ ui-key.yacloud.component.compute.network-select.switch_auto }}`. + * В поле **{{ ui-key.yacloud.component.compute.network-select.field_security-groups }}** выберите созданную ранее группу безопасности `webserver-sg`. + + 1. В блоке **{{ ui-key.yacloud.compute.instances.create.section_access }}** выберите **{{ ui-key.yacloud.compute.instance.access-method.label_oslogin-control-ssh-option-title }}** и укажите данные для доступа к ВМ: + + * В поле **{{ ui-key.yacloud.compute.instances.create.field_user }}** укажите имя пользователя `yc-user`. + * {% include [access-ssh-key](../../_includes/compute/create/access-ssh-key.md) %} + + 1. В блоке **{{ ui-key.yacloud.compute.instances.create.section_base }}** задайте имя ВМ: `mywebserver`. + 1. Нажмите кнопку **{{ ui-key.yacloud.compute.instances.create.button_create }}**. + + - CLI {#cli} + + Выполните команду, указав сохраненный на предыдущем шаге идентификатор группы безопасности: + + ```bash + yc compute instance create \ + --name mywebserver \ + --zone {{ region-id }}-b \ + --network-interface subnet-name=webserver-subnet-{{ region-id }}-b,nat-ip-version=ipv4,security-group-ids=<идентификатор_группы_безопасности> \ + --create-boot-disk image-folder-id=standard-images,image-id=fd8ne6e3etbrr2ve9nlc \ + --ssh-key <файл_открытого_SSH-ключа> + ``` + + Где `--ssh-key` — путь к файлу с открытым SSH-ключом. Например, `~/.ssh/id_ed25519.pub`. + + Результат: + + ```yml + done (32s) + id: epdv79cu67np******** + folder_id: b1gt6g8ht345******** + created_at: "2024-03-23T19:17:09Z" + name: mywebserver + zone_id: {{ region-id }}-b + platform_id: standard-v2 + resources: + memory: "2147483648" + cores: "2" + core_fraction: "100" + status: RUNNING + metadata_options: + gce_http_endpoint: ENABLED + aws_v1_http_endpoint: ENABLED + gce_http_token: ENABLED + aws_v1_http_token: DISABLED + boot_disk: + mode: READ_WRITE + device_name: epdg0926k12t******** + auto_delete: true + disk_id: epdg0926k12t******** + network_interfaces: + - index: "0" + mac_address: d0:0d:1f:3a:59:e3 + subnet_id: e2l3qffk0h6t******** + primary_v4_address: + address: 192.168.1.14 + one_to_one_nat: + address: 62.84.***.*** + ip_version: IPV4 + security_group_ids: + - enpv1c0q7j01******** + serial_port_settings: + ssh_authorization: INSTANCE_METADATA + gpu_settings: {} + fqdn: epdv79cu67np********.auto.internal + scheduling_policy: {} + network_settings: + type: STANDARD + placement_policy: {} + ``` + + Подробнее о команде `yc compute instance create` читайте в [справочнике CLI](../../cli/cli-ref/compute/cli-ref/instance/create.md). + + - API {#api} + + Чтобы создать виртуальную машину, воспользуйтесь методом REST API [create](../../compute/api-ref/Instance/create.md) для ресурса [Instance](../../compute/api-ref/Instance/) или вызовом gRPC API [InstanceService/Create](../../compute/api-ref/grpc/Instance/create.md). + + {% endlist %} + + В вашем каталоге будет создана виртуальная машина `mywebserver`. Чтобы [подключиться](../../compute/operations/vm-connect/ssh.md#vm-connect) к ней по SSH, используйте логин `yc-user` и [публичный IP-адрес](../../vpc/concepts/address.md#public-addresses) этой ВМ. Если вы планируете пользоваться созданным веб-сервером длительное время, [сделайте](../../vpc/operations/set-static-ip.md) публичный IP-адрес этой ВМ статическим. + +1. Создайте и активируйте виртуальное окружение. + + Виртуальное окружение обеспечивает изолированное пространство для проектов Python на сервере. Все необходимые зависимости — исполняемые файлы, библиотеки и прочие файлы — копируются в выбранный каталог, и приложение использует их, а не установленные в системе. Это позволяет обеспечить стабильность среды разработки и чистоту основной системы. + + Для создания виртуального окружения используйте модуль библиотеки Python 3 `venv`: + + 1. [Подключитесь](../../compute/operations/vm-connect/ssh.md) к виртуальной машине `mywebserver`. + + 1. В директории текущего пользователя создайте поддиректорию проекта `flask_blog`, в которой будет находиться приложение, и перейдите в нее: + + ```bash + mkdir flask_blog && cd flask_blog + ``` + + 1. Установите модуль создания виртуальных сред `venv`: + + ```bash + sudo apt install python3.10-venv + ``` + + 1. Создайте виртуальное окружение `env`: + + ```bash + python3 -m venv env + ``` + + 1. Активируйте созданное виртуальное окружение: + + ```bash + source env/bin/activate + ``` + + После активации виртуального окружения в командной строке появится префикс с именем окружения: + + ```text + (env) yc-user@ubuntu:~/flask_blog$ + ``` + + {% note info %} + + Чтобы эффективно отслеживать процесс разработки проекта и управлять им, вы можете использовать [систему контроля версий](../../glossary/vcs.md). В этом случае добавьте директорию `env` в файл `.gitignore`, чтобы не отслеживать файлы, не связанные с проектом. + + {% endnote %} + + Чтобы деактивировать виртуальное окружение, выполните команду: + + ```bash + deactivate + ``` + +1. Установите Flask: + + ```bash + pip install flask + ``` + + Результат: + + ```text + Successfully installed Jinja2-3.1.3 MarkupSafe-2.1.5 Werkzeug-3.0.1 blinker-1.7.0 click-8.1.7 flask-3.0.2 itsdangerous-2.1.2 + ``` + +## Создайте и запустите приложение {#create-app} + +Создайте простое веб-приложение внутри файла Python и запустите его для начала работы сервера. + +1. В директории проекта `flask_blog` создайте и откройте файл `app.py`: + + ```bash + nano app.py + ``` + + Этот файл позволяет понять, как приложение будет обрабатывать HTTP-запросы. + +1. Добавьте в файл следующий код: + + ```python + from flask import Flask + + app = Flask(__name__) + + + @app.route('/') + def hello(): + return 'Hello, World!' + ``` + + В этом коде: + + * Импортируется [объект `Flask`](https://flask.palletsprojects.com/en/latest/api/#flask.Flask) из пакета `flask`. + * Создается экземпляр приложения Flask с именем `app`. Специальная переменная `__name__` содержит имя текущего модуля Python и указывает экземпляру его расположение. Это необходимо, так как Flask устанавливает ряд путей внутри приложения. + * С помощью [декоратора](https://en.wikipedia.org/wiki/Python_syntax_and_semantics#Decorators) `@app.route('/')` функция Python превращается в функцию визуализации Flask. Функция визуализации конвертирует возвращаемое значение в HTTP-ответ, который может быть обработан HTTP-клиентом, таким как веб-браузер. Значение `'/'` в маршруте `@app.route()​​` устанавливает, что эта функция будет отвечать на веб-запросы для URL `/`, который является основным URL-адресом веб-приложения. + * Создается функция `hello()`, которая возвращает строку `Hello, World!` в качестве ответа. + + Сохраните и закройте файл `app.py`. + +1. Задайте переменные окружения `Flask`: + + ```bash + export FLASK_APP=app && export FLASK_DEBUG=true + ``` + + Где: + + * `FLASK_APP=app` указывает на расположение приложения — файла `app.py`. + * `FLASK_DEBUG=true` указывает, что приложение необходимо запустить в режиме разработки. + +1. Запустите приложение: + + ```bash + flask run \ + --host=0.0.0.0 + ``` + + Где параметр `--host=0.0.0.0` запускает сервер приложения на всех IP-адресах виртуальной машины. Не указав этот параметр, вы не сможете обратиться к приложению по публичному IP-адресу ВМ. + + Результат: + + ```text + * Serving Flask app 'app' + * Debug mode: on + WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. + * Running on all addresses (0.0.0.0) + * Running on http://127.0.0.1:5000 + * Running on http://192.168.1.14:5000 + Press CTRL+C to quit + * Restarting with stat + * Debugger is active! + * Debugger PIN: 884-371-*** + ``` + + Для нас важна следующая информация: + + * Название работающего приложения — `app`. + * `Debug mode: on` означает, что отладчик Flask работает. Эта функция полезна при разработке, так как при возникновении проблем она выдает детализированные сообщения об ошибках, что упрощает работу по их устранению. + * Приложение работает на всех адресах. + + Вы можете изменить порт веб-сервера на любое другое значение, задав дополнительный параметр `--port=<номер_порта>`. Например, команда `flask run --host=0.0.0.0 --port=5001` запустит веб-сервер Flask на порте `5001`. + +1. Откройте браузер и введите в адресной строке `http://<публичный_IP-адрес_ВМ>:5000/`​. + + Браузер отобразит строку `Hello, World!`. Это подтверждает, что ваше приложение успешно работает и к нему можно обращаться из интернета. + +{% note warning %} + +Flask использует простой веб-сервер для обслуживания приложения в среде разработки. Он предназначен для тестирования и обнаружения ошибок и не должен использоваться при развертывании в производственной среде. Подробнее см. в [документации Flask](https://flask.palletsprojects.com/en/latest/deploying/). + +{% endnote %} + +Оставьте веб-сервер работать в текущем окне и откройте новое окно терминала. В новом окне терминала вы будете выполнять дальнейшую настройку приложения. Это позволит проверять работу внесенных в приложение изменений без необходимости постоянно останавливать и вновь запускать веб-сервер. + +При открытии нового окна терминала: + +1. [Подключитесь](../../compute/operations/vm-connect/ssh.md) к ВМ. +1. Перейдите в директорию проекта `flask_blog`, активируйте виртуальное окружение и задайте переменные окружения: + + ```bash + cd flask_blog && source env/bin/activate && export FLASK_APP=app && export FLASK_DEBUG=true + ``` + +## Создайте и настройте шаблоны HTML {#html-templates} + +В текущем виде приложение отображает в браузере только простое текстовое сообщение. Добавьте в приложение файлы-шаблоны HTML, которые позволят отображать нужные пользователю данные и элементы управления. + +Использовать в приложении шаблоны позволяет [вспомогательная функция `render_template()`](https://flask.palletsprojects.com/en/latest/api/#flask.render_template), в которой доступен [механизм шаблонов Jinja](https://jinja.palletsprojects.com/en/latest/templates/). Вы будете использовать шаблоны HTML для создания страниц приложения: главной страницы со списком текущих постов блога и страниц создания, просмотра и редактирования поста. + +### Создайте HTML-шаблон главной страницы {#create-html-template} + +1. Откройте файл `app.py`: + + ```bash + nano app.py + ``` + +1. Замените содержимое файла следующим кодом: + + ```python + from flask import Flask, render_template + + app = Flask(__name__) + + @app.route('/') + def index(): + return render_template('index.html') + ``` + + В этом коде: + + * Дополнительно импортируется вспомогательная функция `render_template()`, которая позволяет визуализировать шаблоны HTML. + * Функция `hello()` заменяется на функцию `index()`, которая возвращает результат вызова вспомогательной функции `render_template()` с аргументом `index.html​`​. Аргумент функции указывает на файл шаблона, который должен быть расположен в директории шаблонов и который будет использован для визуализации. + + {% note info %} + + Директория шаблонов и файл `index.html` еще не созданы. Вы получите сообщение об ошибке, если запустите приложение на этом этапе. + + {% endnote %} + + Сохраните и закройте файл `app.py`. + +1. В директории проекта `flask_blog` создайте поддиректорию `templates`: + + ```bash + mkdir templates + ``` + +1. Создайте и откройте файл-шаблон `index.html` в директории `templates`: + + ```bash + nano templates/index.html + ``` + +1. Добавьте в файл `index.html` следующий код: + + ```html + + + + + FlaskBlog + + +

Welcome to FlaskBlog

+ + + ``` + + В этом HTML коде описана простейшая страница с заголовком `FlaskBlog` и содержимым `Welcome to FlaskBlog` в заголовке первого уровня. + + Сохраните и закройте файл `index.html`. + +1. Обновите главную страницу приложения `http://<публичный_IP-адрес_ВМ>:5000/`. + + Результат: + + ```text + Welcome to FlaskBlog. + ``` + +1. Кроме директории `templates` в веб-приложениях Flask обычно также существует директория `static`, в которой сохраняются статичные файлы, такие как стили CSS, скрипты JavaScript или изображения, используемые приложением. + + В директории проекта `flask_blog` создайте поддиректорию `static`: + + ```bash + mkdir static + ``` + +1. Во вновь созданной директории `static` создайте поддиректорию `css`: + + ```bash + mkdir static/css + ``` + + {% note info %} + + Вложенные директории используются для упорядочивания статичных файлов в специальных папках. Например, файлы JavaScript обычно хранятся в директории `js`, изображения — в директории `images` (или `img`) и т.д. + + {% endnote %} + +1. Создайте и откройте файл `style.css` в директории `static/css`: + + ```bash + nano static/css/style.css + ``` + +1. Добавьте в файл `style.css` следующий код: + + ```css + h1 { + border: 2px #eee solid; + color: #fc3d17; + text-align: center; + padding: 10px; + } + ``` + + Этот CSS-код изменяет оформление текста внутри HTML-тегов `

`: + * свойство `border` добавляет границу; + * свойство `color` изменяет цвет текста; + * свойство `text-align` выравнивает текст; + * свойство `padding` добавляет отступ до текста от границы элемента. + + Сохраните и закройте файл `style.css`. + +1. Откройте шаблон `index.html`: + + ```bash + nano templates/index.html + ``` + +1. Добавьте ссылку на файл `style.css` внутри раздела ``: + + ```html + ... + + + + FlaskBlog + + ... + ``` + + В ссылке используется [вспомогательная функция `url_for()`](https://flask.palletsprojects.com/en/latest/api/#flask.url_for)​​​ для генерации адреса расположения файла. Первый аргумент указывает на то, что ссылка связана со статическими файлами, второй аргумент — путь к файлу в поддиректории статических файлов. + + Сохраните и закройте файл `index.html`. + +1. Обновите главную страницу приложения `http://<публичный_IP-адрес_ВМ>:5000/`. + + Вы увидите, что цвет текста `Welcome to FlaskBlog`​​​ теперь красный и расположен по центру внутри рамки. + +Используйте [язык CSS](https://ru.wikipedia.org/wiki/CSS), чтобы сформировать единый и уникальный стиль оформления вашего веб-приложения. Если вы не знакомы с языком CSS, воспользуйтесь [инструментарием Bootstrap](https://getbootstrap.com/), который предлагает простые и удобные в использовании элементы оформления приложения. В этом руководстве вы будете использовать Bootstrap. + +### Настройте другие шаблоны HTML {#configure-html-templates} + +В других HTML-шаблонах потребуется повторить основную часть кода HTML, который уже присутствует в шаблоне `index.html`. Чтобы избежать ненужного дублирования кода, используйте файл _базового шаблона_, который будет служить родителем для всех остальных HTML-шаблонов проекта. Подробнее см. в [документации Jinja](https://jinja.palletsprojects.com/en/latest/templates/#template-inheritance). + +1. Создайте и откройте базовый файл-шаблон `base.html` в директории `templates`: + + ```bash + nano templates/base.html + ``` + +1. Добавьте в файл следующий код: + + ```html + + + + + + + + + + + {% block title %} {% endblock %} + + + +
+ {% block content %} {% endblock %} +
+ + + + + + ``` + + В этот файл входит HTML-код, а также дополнительный код, необходимый для Bootstrap. Теги `` содержат информацию для браузера, тег `` — привязывает файлы CSS Bootstrap, а тег `