Создание сайта на питоне пошаговая инструкция с нуля пошагово

Как создать аналитический сайт на Python с нуля

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

Skillfactory.ru

Разобралась, как создать само приложение Dash. Однако мне не удалось найти способ, который описывал бы все 3 нужные функциональности. И в данной статье мы займемся его разработкой. 

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

Введение

Изначально сайт был разработан в Dash. Он представлял собой информационную панель, как показано ниже: 

Информационные панели создавались с помощью Dash и Plotly. 

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

Я начала изучать информацию в интернете. Мне нужно было найти подход для разработки такого сайта, который бы отображал разметку Markdown и использовал преимущества Dash для создания информационных панелей. Однако поиски не увенчались успехом. 

Зато я натолкнулась на описание практического опыта разработки Джеймса Хардинга. Он состоял в создании простого статического блога на основе Markdown с помощью Flask. Я воспользовалась им для настройки основного сайта и с помощью пары приемов согласовала его работу с информационной панелью. 

Структура каталога 

Основная структура выглядит следующим образом: 

.
|-- virtualenv/
|-- main/
| |-- content
| | |-- posts
| | | `-- about_website.md
| |-- dash
| |-- data
| |-- static
| |-- templates
| |-- __init__.py
|-- app.py
|-- Dockerfile
|-- .pylintrc
`-- requirements.txt

В __init__.py происходит настройка сервера Flask, а также регистрация Flatpages и компонентов Dash. 

Сайт разделен на статические файлы и файлы HTML. Выводимые на сайте изображения или файлы CSS и JavaScript располагаются в папке static, а файлы HTML  —  в папке templates

Регистрация приложения Flask 

Приложение вызывается из файла app.py. Сам он вызывает функцию create_app(), находящуюся в файле __init__.py.

def create_app():
app = Flask(__name__, static_url_path='/static')
app.config.from_object(__name__)
app.config['FLATPAGES_HTML_RENDERER'] = my_renderer
register_dashapps(app)
register_routes(app)
return app

Эта функция включает настройки сервера и указание места, в котором статические файлы наделяют сайт уникальными характеристиками. 

Примечание. Если не добавить static_url_path в качестве параметра, сервер Flask не сможет определить, где искать файлы CSS и JavaScript. Столкнувшись с ошибкой 404 при вызове данных файлов, знайте, что проблема может быть именно в этом. 

После регистрации сервера Flask добавляем компоненты Dash и страницы разметки Markdown Flatpages. 

Добавление информационной панели 

Файл __init__.py включает функцию register_dashapps, которая представлена ниже: 

def register_dashapps(app):
from .main.layout import html_layout
# Метатеги для отзывчивости viewport
meta_viewport = {"name": "viewport",
"content": "width=device-width, initial-scale=1, shrink-to-fit=no"}

dash_app = dash.Dash(
server=app,
routes_pathname_prefix="/projects/dashapp/",
external_stylesheets=[
"https://fonts.googleapis.com/css?family=Lato",
],
)

with app.app_context():
dash_app.index_string = html_layout
dash_app.layout = init_dashboard()

Главное отличие между обычным Dash и данной функцией заключается в дополнительном контексте Flask. Теперь информационная панель запускается через app_context() Flask. 

Добавление блогов 

Большинство блогов придерживаются общепринятого подхода и хранят контент в реляционной базе данных.  

Простые и “плоские” посты моего блога взяты из файлов в исходном коде. Flatpages отлично подходит для данного случая использования и быстро добавляет программу визуализации в конфигурацию приложения Flask, которая преобразует или переводит Markdown в HTML. 

FLATPAGES_EXTENSION = '.md'
FLATPAGES_ROOT = 'content'
POST_DIR = 'posts'

def my_renderer(text):
body = render_template_string(markdown2.markdown(
text, extras=['fenced-code-blocks']))
return pygmented_markdown(body)

def create_app():
app = Flask(__name__, static_url_path='/static')
app.config.from_object(__name__)
app.config['FLATPAGES_HTML_RENDERER'] = my_renderer
return app

Кроме того, нам нужно зарегистрировать маршруты сайта, указывающие на посты. 

def register_routes(app):
pages = FlatPages(app)
freezer = Freezer(app)

Добавление блокнотов Jupyter

Заключительный этап предусматривает добавление блокнотов Jupyter. 

Прежде чем добавить переадресацию в файл __init__.py, убедимся в наличии доступа к блокноту Jupyter с сайта. Я задействовала инструмент nbviewer, позволяющий бесплатно разместить этот блокнот. Затем данный URL можно использовать в переадресации (<URL>), как показано ниже: 

@app.route('/<title_for_redirect>')
def project_jupyter_notebook():
return redirect('https://mybinder.org/<your_binder_url>')

Теперь вы знаете, как объединить вместе Flask, Dash и Jupyter Notebook и создать прекрасный сайт.

Читайте также:

  • Бэкенд-разработчик: какие знания нужны для трудоустройства
  • Управляем интернетом с помощью Python
  • Овладей Python, создавая реальные приложения. Часть 6

Читайте нас в Telegram, VK и Яндекс.Дзен


Перевод статьи Sarah Floris: Create an Analytical Website From Scratch Using Python

Skillfactory.ru

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

Обзор проекта

Готовый сайт находится здесь. У сайта несколько секций:

  • Главная
  • Резюме
  • Портфолио
  • Блог
  • Контакты

Переключение между секциями создает иллюзию многостраничности, но в «живой» версии сайт – одностраничный. Бэкенд включает в себя модуль Frozen Flask, который превращает приложение в генератор статических сайтов (SSG): все страницы, необходимые для адекватного представления сайта в статической версии, создаются автоматически.

Готовый сайт на GitHub Pages

Готовый сайт на GitHub Pages

Фронтенд сделан на Bootstrap с несколькими дополнительными JS скриптами – например, записи в блоге фильтруются (без перезагрузки страницы) по тегам с помощью скрипта isotope.js, при этом теги для фильтра скрипт получает из расширения Flask – FlatPages. Записи в блоге и карточки в портфолио можно перелистывать свайпом, без перезагрузки страницы. Bootstrap обеспечивает адаптивность: сайт одинаково хорошо смотрится на широкоформатном мониторе и на смартфоне.

Первый этап

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

Установка Flask

Сначала нужно создать папку для проекта и активировать виртуальное окружение:

        mkdir flask_project
cd flask_project
mkdir .venv
pipenv shell

    

Папка .venv – служебная: менеджер pipenv автоматически разместит все нужные зависимости там, и они не будут загромождать корневую директорию проекта. Виртуальное окружение активируется командой pipenv shell, для выхода нужно выполнить exit.

Установим Flask и все необходимые зависимости. Для этого сохраните этот список в файле requirements.txt:

        Click==7.0
Flask==1.1.1
Flask-FlatPages==0.7.1
Frozen-Flask==0.15
itsdangerous==1.1.0
Jinja2==2.10.3
Markdown==3.1.1
MarkupSafe==1.1.1
Pygments==2.4.2
PyYAML==5.1.2
Werkzeug==0.16.0

    

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

        pipenv install -r requirements.txt
    

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

Структура Flask проекта

Начнем с создания структуры проекта:

        ├── mysite.py
├── content
│   └── posts
│   	
├── static
└── templates

    

В папке content/posts будут размещаться Markdown файлы, в templates – шаблоны, в static – CSS стили, изображения и JS-скрипты. Весь код приложения мы напишем в файле mysite.py – сначала импортируем нужные модули, затем определим основные параметры, после пропишем маршруты к шаблонам и запустим сервер. Простейший вариант кода mysite.py выглядит так:

        import sys
from flask import Flask, render_template
from flask_flatpages import FlatPages, pygments_style_defs
from flask_frozen import Freezer
DEBUG = True
FLATPAGES_AUTO_RELOAD = DEBUG
FLATPAGES_EXTENSION = '.md'
FLATPAGES_ROOT = 'content'
POST_DIR = 'posts'
 
app = Flask(__name__)
flatpages = FlatPages(app)
freezer = Freezer(app)
app.config.from_object(__name__)
 
@app.route("/")
def index():
	posts = [p for p in flatpages if p.path.startswith(POST_DIR)]
	posts.sort(key=lambda item: item['date'], reverse=True)
	return render_template('index.html', posts=posts, bigheader=True)
 
@app.route('/posts/<name>/')
def post(name):
	path = '{}/{}'.format(POST_DIR, name)
	post = flatpages.get_or_404(path)
	return render_template('post.html', post=post)
 
if __name__ == "__main__":
	if len(sys.argv) > 1 and sys.argv[1] == "build":
    	freezer.freeze()
	else:
    	app.run(host='127.0.0.1', port=8000, debug=True)

    

В это трудно поверить, но основной код блога действительно занимает всего 28 строк. Это возможно благодаря модулям FlatPages и Flask Frozen: первый избавляет от необходимости хранить посты в базе данных, проводит рендеринг Markdown-файлов в html, обеспечивает вывод записей и обращение к их свойствам, что будет заметно при создании шаблонов. Flask Frozen в действии мы увидим чуть позже: этот модуль берет на себя создание статической копии сайта – экспортирует html-файлы и все нужные ассеты (скрипты, CSS, изображения) в папку build.

Добавим в папку posts два-три тестовых поста – в YAML части обязательно должны быть метаданные title, date, description, потому что Jinja будет вызывать их в шаблонах. Markdown посты можно писать в любом редакторе – хоть в Блокноте, хоть в Sublime Text; можно обзавестись и специальным редактором – MarkdownPad для Windows, Mou для macOS.

Теперь создадим два простейших шаблона. Это код для index.html:

        {% block content %}
<h2>Блог - тестовый запуск</h2>
            {% for post in posts %}
        	<small>{{ post.date }}</small>
        	<p>
          	<h3>
            	{{ post.title }}
          	</h3>
        	<p>
          	<i>{{ post.description }}</i>
        	</p>
         	<p>{{ post.html[:100]|safe }}</p>
            	<a href="{{ url_for('post', name=post.path.replace('posts/', '')) }}"><span>Читать</span></a>
        	</p>
        	{% endfor %}
{% endblock %}

    

А это шаблон для вывода записи на отдельной странице post.html:

        {{ post.date }}
{{ post.title }}
{{ post.dеscription }}
{{ post.html|safe }}

    

Оба шаблона мы доработаем на следующем этапе, а пока запустим приложение python mysite.py и посмотрим на результат.

Главная страница блога

Главная страница блога
Отдельная запись
Отдельная запись

Весь код и тестовый контент для этого этапа есть здесь.

Второй этап

На этом этапе мы сделаем первые шаблоны и подключим файл с настройками.

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

Flask использует шаблонизатор Jinja2. Синтаксис Jinja2 идентичен шаблонизатору Django и напоминает Python. Если вам еще не приходилось работать с Django, на этом этапе достаточно знать, что логика в Jinja2 заключается в такие фигурные скобки {% %}, а переменные – в такие {{ }}.

Шаблон Jinja2 представляет собой обычный html-файл, в котором блоки с логикой и переменными размещаются в уже упомянутых скобках. К шаблону можно подключать любые JS-скрипты, иконки, шрифты. Большое количество переменных можно передать в шаблон в виде словаря:

        @app.route("/")
def index():
	variables = {"title":"Это мой сайт",
             	"description":"Разработчик, дизайнер, автор ИТ-курсов"
             	"keywords":"Разработка на Python, курсы по Django"
 	            }	
return render_template('index.html', **variables)

    

В шаблоне index.html, в свою очередь, эти переменные можно вставить в нужные теги:

        <title>{{ title }}</title>
  <meta content="{{ description }}" name="description">
  <meta content="{{ keywords }}" name="keywords">

    

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

Jinja2 поддерживает наследование и включение шаблонов – это позволяет разбить шаблон объемной страницы на несколько секций, которые проще редактировать по отдельности. Наш сайт состоит из одной страницы с несколькими разделами, которые целесообразно вынести в отдельные шаблоны:

  • base.html
  • index.html
  • header.html
  • resume.html
  • counters.html
  • skills.html
  • interests.html
  • portfolio.html
  • card.html
  • blog.html
  • post.html
  • contacts.html

Jinja2 не диктует каких-то жестких правил: при желании можно обойтись всего двумя шаблонами – index.html и post.html. И, конечно, можно не выносить переменные в отдельный файл, а вписать весь текст резюме и портфолио прямо в index.html. Но поддерживать сайт проще, если хранить всю потенциально изменяемую информацию в Markdown-файлах и текстовом файле конфигурации – в этом случае для изменения данных нужно будет внести поправки только один раз: переменные в шаблонах обеспечат обновление текста во всех разделах сайта. Кроме того, ненужные разделы сайта очень просто удалить, если они находятся в отдельных шаблонах.

Первый шаблон, который мы создадим – base.html. Он будет получать переменные из бэкенда. Для передачи данных в шаблон создайте файл settings.txt и сохраните в нем словарь:

        {"site_url":"http://localhost:8000",
"site_title": "John Doe: Python разработчик и автор контента",
"description": "Джон Доу - портфолио, резюме и блог Python разработчика",
"keywords": "Веб-разработка на Python, бэкенд на Django и Flask"}

    

Теперь добавьте импорт json и загрузку данных из файла в mysite.py:

        @app.route("/")
def index():
	posts = [p for p in flatpages if p.path.startswith(POST_DIR)]
	posts.sort(key=lambda item: item['date'], reverse=True)
	with open('settings.txt', encoding='utf8') as config:
    	data = config.read()
    	settings = json.loads(data)
	return render_template('index.html', posts=posts, bigheader=True, **settings)

    

Сохраните этот код в templates/base.html:

        <!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="utf-8">
  <meta content="width=device-width, initial-scale=1.0" name="viewport">
  <title>{{ site_title }}</title>
  <meta content="{{ description }}" name="description">
  <meta content="{{ keywords }}" name="keywords">
  <link href="{{ url_for('static', filename='img/favicon.png') }}" rel="icon">
  <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i|Raleway:300,300i,400,400i,500,500i,600,600i,700,700i|Poppins:300,300i,400,400i,500,500i,600,600i,700,700i" rel="stylesheet">
  <link href="{{ url_for('static', filename='assets/bootstrap/css/bootstrap.min.css') }}" rel="stylesheet">
  <link href="{{ url_for('static', filename='assets/bootstrap-icons/bootstrap-icons.css') }}" rel="stylesheet">
  <link href="{{ url_for('static', filename='assets/boxicons/css/boxicons.min.css') }}" rel="stylesheet">
  <link href="{{ url_for('static', filename='assets/glightbox/css/glightbox.min.css') }}" rel="stylesheet">
  <link href="{{ url_for('static', filename='assets/remixicon/remixicon.css') }}" rel="stylesheet">
  <link href="{{ url_for('static', filename='assets/swiper/swiper-bundle.min.css') }}" rel="stylesheet">
  <script src="https://kit.fontawesome.com/69e2443572.js" crossorigin="anonymous"></script>
  <link href="{{ url_for('static', filename='css/style.css') }}" rel="stylesheet">
</head>
<body>
  <main id="main">
{% block content %} <!-- вложенные шаблоны -->
{% endblock %}
  </main>
  <!-- Скрипты -->
  <script src="{{ url_for('static', filename='assets/purecounter/purecounter.js') }}"></script>
  <script src="{{ url_for('static', filename='assets/bootstrap/js/bootstrap.bundle.min.js') }}"></script>
  <script src="{{ url_for('static', filename='assets/glightbox/js/glightbox.min.js') }}"></script>
  <script src="{{ url_for('static', filename='assets/isotope-layout/isotope.pkgd.min.js') }}"></script>
  <script src="{{ url_for('static', filename='assets/swiper/swiper-bundle.min.js') }}"></script>
  <script src="{{ url_for('static', filename='assets/waypoints/noframework.waypoints.js') }}"></script>
  <script src="{{ url_for('static', filename='js/main.js') }}"></script>
</body>
</html>

    

А этот – в templates/index.html:

        {% extends "base.html" %}
{% block content %}
<h1>Здесь будет сайт</h1>
{% endblock %}

    

Сохраните в папке static все эти ассеты. Теперь можно запускать сервер python mysite.py– скелет сайта готов:

Значения тегов title, description и keywords взяты из файла settings.txt

Значения тегов title, description и keywords взяты из файла settings.txt

Перейдем к созданию первого шаблона, расширяющего index.html – header.html. Добавьте переменные в файл settings.txt:

        "site_url":"http://localhost:8000",
"tag1":"Разработчик и автор",
"tag2":"курсов по Django",
"sect1":"Главная",
"sect2":"Резюме",
"sect3":"Портфолио",
"sect4":"Блог",
"sect5":"Контакты",
"telegram":"https://t.me/johndoe",
"facebook":"ttps://facebook.com/john.doe",
"vk":"https://vk.com/john_doe",
"email":"mailto:john_doe@gmail.com"

    

И отредактируйте файл index.html – теперь он будет включать в себя header.html с помощью include:

        {% extends "base.html" %}
{% block content %}
{% block header %}
{% include "header.html" %}
{% endblock %}
{% endblock %}

    

Перезагрузите страницу:

Хэдер включен в index.html

Хэдер включен в index.html

Весь код и контент для этого этапа – здесь. Во второй части туториала мы завершим работу над приложением и загрузим статическую копию сайта на GitHub Pages.

***

Материалы по теме

  • 🐍🚀 Django с нуля. Часть 1: пишем многопользовательский блог для клуба любителей задач Python
  • 🐍🚀 Django с нуля. Часть 2: регистрация, авторизация, ограничение доступа
  • 🐍🚀 Django с нуля. Часть 3: создание профилей, сжатие изображений, CRUD и пагинация

На чтение 10 мин Просмотров 20.9к. Опубликовано 18.11.2021

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

Для начала устанавливаем колбу:

Содержание

  1. Шаг 1: минимальное веб-приложение
  2. Шаг 2: Добавление HTML
  3. Шаг 3: Добавление CSS
  4. Шаг 4: добавление изображения
  5. Шаг № 5: Добавление JavaScript

Шаг 1: минимальное веб-приложение

Минимальное приложение можно найти по адресу https://flask.palletsprojects.com/en/2.0.x/quickstart/#a-minimal-application. Это веб-страница, на которой отображается «Hello World». Первым делом мы создали экземпляр Flask () с аргументом «__name__». Декоратор маршрута используется для того, чтобы сообщить Flask URL-адрес, который активирует написанную нами функцию.

from flask import Flask

app = Flask(__name__)

@app.route(‘/’)

def index():
return «Hello World»

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

Затем в терминале PyCharm введите следующее (где имя моего файла Python — main.py; в вашем случае замените main.py именем вашего файла Python):

set FLASK_APP=main.py
$env:FLASK_APP = «main.py»
flask run

Как только вы запустите «flask run», терминал выдаст URL-адрес с портом. Этот URL: ПОРТ — это место, где загружается веб-страница. Вы всегда можете нажать Control + c, чтобы выйти. В моем случае написано: «Запуск на http://127.0.0.1:5000/ (нажмите CTRL + C, чтобы выйти)». Итак, откройте свой веб-браузер, скопируйте и вставьте указанный URL. В моем случае я скопировал и вставил «http://127.0.0.1:5000/». Также обратите внимание, что предыдущие строки должны запускаться каждый раз, когда вы перезапускаете PyCharm, чтобы он работал:

Как только вы запустите «flask run», терминал выдаст URL-адрес с портом

Шаг 2: Добавление HTML

Первое, что вам нужно сделать, это открыть папку, в которой находится скрипт Python, и создать папку под названием «шаблоны». Когда я впервые запустил это, я попытался указать имя «шаблон» в качестве имени папки, и вся программа вылетела и не работала. Поэтому обязательно назовите папку « Шаблоны ». В этой папке «шаблонов» создайте файл index.html с вашим HTML-кодом. Затем используйте render_template () и передайте index.html в качестве аргумента. Теперь, если вы запустите «flask run» в терминале, ваш HTML-код должен отобразиться:

Мой html-код (index.html) на данный момент выглядит следующим образом:

<!DOCTYPE html>
<html lang=«en»>
<head>
<meta charset=«UTF-8»>
<title>Kalyani‘s Resume</title>
</head>
<body>
<h1>
Kalyani’
s Resume
This page will contain my resume
</h1>
</body>
</html>

И мой код файла Python (main.py) выглядит следующим образом:

from flask import Flask, render_template

app = Flask(__name__)

@app.route(‘/’)

def index():
return render_template(«index.html»)

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

Последний будет отображать простую HTML-страницу.

Шаг 3: Добавление CSS

Теперь я хочу добавить CSS в свой HTML. Для этого создайте папку с именем «static» и создайте файл с именем «main.css». Здесь имя фактического файла CSS может быть любым. Я решил назвать свой «main.css». Однако имя папки должно быть «статическим»! Фактически, в «статической» папке можно разместить все, что является статическим, например CSS, JavaScript и изображения. Итак, если вы собираетесь размещать изображения, JavaScript и CSS, вы можете создать подпапки.

Теперь я хочу добавить CSS в свой HTML

Сначала напишем нужный мне CSS (main.css):

body {
margin:0;
color: #333
font-family: verdana;
font-size: 20px;
background-color: rgb(201, 76, 76);
}
.styled {
background-color: #92a8d1;
font-family: verdana;
font-size: 20px;
}

Здесь, в index.html, нам нужно написать & lt; link rel = «stylesheet» type = «text / css» href = «{{url_for (‘static’, filename = ‘main.css’)}}» > в заголовке HTML-файла. Здесь имя файла — это имя файла CSS (у меня main.css). Если, например, «main.css» находится с подпапкой «css», вы должны написать следующее:

 <link rel=«stylesheet» type=«text/css» href=«{{ url_for(‘static’, filename=’css/main.css’)}}»>.

После этого вы можете использовать созданный вами CSS. Например, я создал один под названием «стилизованный» и использовал его в классе h1.

Мой файл index.html будет следующим:

<!DOCTYPE html>
<html lang=«en»>
<head>
<meta charset=«UTF-8»>
<title>Kalyani‘s Resume</title>
<link rel=»stylesheet» type=»text/css» href=»{{ url_for(‘
static‘, filename=’main.css‘)}}»>
</head>
<body>

<h1 class=»styled»>
Kalyani’s Resume
This page will contain my resume
</h1>
</body>
</html>

Главный файл Python — main.py — остается прежним.

from flask import Flask, render_template

app = Flask(__name__)

@app.route(‘/’)

def index():
return render_template(«index.html»)

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

Шаг 4: добавление изображения

Теперь давайте добавим изображение на созданную HTML-страницу! Для этого мы используем созданную нами «статическую» папку. Внутри «статической» папки я создал другую папку под названием «изображения». В папке изображений я поместил изображение. Теперь давайте добавим изображение в HTML-код следующим образом: <img src = ”/ static / images / kalyani.jpg” height = ”200 ″ />. В этом случае я установил высоту изображения на 200, но вы можете изменить ее на все, что захотите, и добавить CSS, если хотите.

Теперь давайте добавим изображение на созданную HTML-страницу

HTML-код будет выглядеть следующим образом:

<!DOCTYPE html>
<html lang=«en»>
<head>
<meta charset=«UTF-8»>
<title>Kalyani‘s Resume</title>
<link rel=»stylesheet» type=»text/css» href=»{{ url_for(‘
static‘, filename=’main.css‘)}}»>
</head>
<body>
<img src=»/static/images/kalyani.jpg» height=»200″ />
<h1 class=»styled»>
Kalyani’
s Resume
</h1>
This page will contain my resume
</body>
</html>

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

<img src=«{{ url_for(‘static’, filename=’images/kalyani.jpg’)}}» height=«200» />.

В этом случае HTML-код будет выглядеть так:

<!DOCTYPE html>
<html lang=«en»>
<head>
<meta charset=«UTF-8»>
<title>Kalyani‘s Resume</title>
<link rel=»stylesheet» type=»text/css» href=»{{ url_for(‘
static‘, filename=’main.css‘)}}»>
</head>
<body>
<img src=»{{ url_for(‘
static‘, filename=’images/kalyani.jpg‘)}}» height=»200″ />
<h1 class=»styled»>
Kalyani’
s Resume
</h1>
This page will contain my resume
</body>
</html>

Шаг № 5: Добавление JavaScript

Есть два способа добавить JavaScript. В этой первой демонстрации я создам кнопку. Когда кнопка нажата, она активирует функцию myFunction (), которая будет JavaScript (находится в теге <script>). Для этого настройте кнопку. Затем установите тег скрипта в заголовке HTML-кода и определите в нем функцию. В моем случае я определил функцию, которая будет добавлять «все резюме» к элементу ap при нажатии кнопки.

Вы можете добавить его в файл index.html следующим образом:

<!DOCTYPE html>
<html lang=«en»>
<head>
<meta charset=«UTF-8»>
<title>Kalyani‘s Resume</title>
<link rel=»stylesheet» type=»text/css» href=»{{ url_for(‘
static‘, filename=’main.css‘)}}»>

function myFunction() {
document.getElementById(«para»).innerHTML = «WHOLE RESUME»;
}
</script>
</head>
<body>
<img src=»/static/images/kalyani.jpg» height=»200″ />
<h1 class=»styled»>
Kalyani’s Resume
</h1>
This page will contain my resume
<br>
<br>
<id=«para»> </p>
<<button id=«button» type=«button» onclick=«myFunction()»> Click to see Resume </button>
</body>
</html>

Однако в большинстве случаев файлы JavaScript, как правило, сами по себе являются документами, а не однострочниками. В таких случаях у нас будет файл.js, который нужно связать. В моем случае я бы написал: <script src = ”/ static / javascript / javascript.js”> </script>. Итак, как и в случае с файлом изображения, мы связываем файл js следующим образом:

<!DOCTYPE html>
<html lang=«en»>
<head>
<meta charset=«UTF-8»>
<title>Kalyani‘s Resume</title>
<link rel=»stylesheet» type=»text/css» href=»{{ url_for(‘
static‘, filename=’main.css‘)}}»>
<script src=»/static/javascript/javascript.js»>
</script>
</head>
<body>
<img src=»/static/images/kalyani.jpg» height=»200″ />
<h1 class=»styled»>
Kalyani’
s Resume
</h1>
This page will contain my resume
<br>
<br>
<id=«para»> </p>
<button id=«button» type=«button» onclick=«myFunction()»> Click to see Resume </button>
</body>
</html>

В качестве альтернативы вы также можете использовать это: <script src = ”{{url_for (‘static’, filename = ‘javascript / javascript.js’)}}”> </script>. Последний сгенерирует этот HTML-код:

<!DOCTYPE html>
<html lang=«en»>
<head>
<meta charset=«UTF-8»>
<title>Kalyani‘s Resume</title>
<link rel=»stylesheet» type=»text/css» href=»{{ url_for(‘
static‘, filename=’main.css‘)}}»>

<script src=»{{ url_for(‘static‘, filename=’javascript/javascript.js‘)}}»>
</script>
</head>
<body>
<img src=»{{ url_for(‘
static‘, filename=’images/kalyani.jpg‘)}}» height=»200″ />

<h1 class=»styled»>
Kalyani’s Resume
</h1>
This page will contain my resume
<br>
<br>
<id=«para»> </p>
<button id=«button» type=«button» onclick=«myFunction()»> Click to see Resume </button>
</body>
</html>

Заключение

Flask — это микро-фреймворк, который удобен в использовании и отлично подходит для начинающих. В частности, сама документация великолепна, и ее можно найти по адресу https://flask.palletsprojects.com/en/2.0.x/quickstart/#static-files. В этом руководстве мы узнали, как создать простой веб-сайт, добавить CSS, добавить изображения и добавить JavaScript на веб-сайт с помощью модуля Python Flask. Мы надеемся, что эта статья оказалась для вас полезной, и, пожалуйста, ознакомьтесь с Linux Hint для получения более информативных статей.

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

Сегодня я расскажу про то, как написать Hello world, как CGI-скрипт.

Настройка локального сервера

В Python уже есть встроенный CGI сервер, поэтому его настройка элементарна.

Для запуска из консоли (для любителей linux-систем). Запускать нужно из той папки, где мы хотим работать:

python3 -m http.server --cgi

Для сидящих на Windows чуть проще будет запуск Python файла (заметьте, что он должен находиться в той же папке, в которой мы планируем работать!):

from http.server import HTTPServer, CGIHTTPRequestHandler
server_address = ("", 8000)
httpd = HTTPServer(server_address, CGIHTTPRequestHandler)
httpd.serve_forever()

Теперь откройте браузер и в адресной строке наберите localhost:8000

Если у вас примерно такая же картина, значит, у вас все заработало!

Локальный CGI-сервер

Теперь в той папке, где мы запустили сервер, создаём папку cgi-bin (у меня она уже создана).

В этой папке создаём скрипт hello.py со следующим содержимым:

#!/usr/bin/env python3

print("Content-type: text/html")
print()
print("<h1>Hello world!</h1>")

Первая строка говорит о том, что это Python скрипт (CGI-скрипты можно не только на Python писать).

Вторая строка печатает заголовок. Он обозначает, что это будет html файл (бывает ещё css, javascript, pdf и куча других, и браузер различает их по заголовкам).

Третья строка (просто символ новой строки) отделяет заголовки от тела ответа.

Четвёртая печатает Hello world.

Теперь переходим на localhost:8000/cgi-bin/hello.py

И радуемся!

Hello world CGI

Если у вас не работает, проверьте, установлены ли права на выполнение.

Также в консоли запущенного сервера появляются сообщения об ошибках. Например, убрал скобочку и обновил страницу:

CGI ошибки

В следующей части мы рассмотрим обработку данных форм и cookies.

Для вставки кода на Python в комментарий заключайте его в теги <pre><code class=»python3″>Ваш код</code></pre>

Рассказываем про один из самых популярных и лаконичных микрофреймворков для Python — Flask. Как написать простое приложение, подключить к нему Bootstrap и базу данных, и есть ли вообще у Flask минусы.

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

Первая публичная версия Flask вышла 16 апреля 2010 года. Автор проекта — Армин Ронахер, который возглавлял команду энтузиастов в Python-разработке Poocco. Flask основан на быстром и расширяемом механизме шаблонов Jinja и наборе инструментов Werkzeug. Кроме того, Flask использует одну из самых передовых служебных библиотек WSGI (Web Server Gateway Interface — стандарт взаимодействия между Python-программой, выполняющейся на стороне сервера, и самим веб-сервером).

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

Изучите Python на Хекслете
Пройдите нашу профессию «Python-разработчик», чтобы поменять свою жизнь и стать бэкенд-программистом.

Плюсы и минусы Flask

Практически все плюсы и минусы Flask появились именно из-за того, что он является микрофреймворком.

Среди достоинств:

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

При этом у Flask есть и свои недостатки:

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

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

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

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

pip install Flask

Для примера мы напишем на Flask тестовое веб-приложение с минимальным функционалом. Как работают приложения такого типа:

  • Пользователь вводит в браузере url, например — hexlet.io. В нашем тестовом приложении пользователь не будет вводить url, потому что мы будем работать с локальным сервером по адресу http://127.0.0.1:5000.
  • Браузер получает у DNS IP-адрес нужного нам сервера. DNS — это Domain Name System, распределенная системе серверов. Она работает как общая «контактная книга» в интернете.
  • Браузер отправляет запрос по этому адресу и получает ответ. Как правило — в виде HTML-страницы.
  • Браузер отображает содержимое страницы.

Итак, создадим файл hello.py и запишем в него следующий код:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def index() -> str:
    return '<p>Hello Flask!</p>'

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

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

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

Декоратор route() сообщает Flask, при обращении к какому URL-адресу запустится декорируемая разработчиком функция — в нашем примере это index. Последней строчкой мы открываем локальный веб-сервер с параметром debug=True — это позволит следить за всеми ошибками в логе программы.

Читайте также:
Программирование на Python: особенности обучения, перспективы, ситуация на рынке труда

Запускаем веб-приложение через терминал:

python hello.py

Если мы все сделали правильно, то в терминале появятся эти сообщения:

Сообщение в терминале об удачном запуске приложения

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

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

from flask import Flask
app = Flask(__name__)

@app.route('/')
def index():
    greet_with_link = """<h1>Привет, Мир!</h1>
    <p><a href="user/Аникин/Георгий">Нажми на меня</a></p>"""
    return greet_with_link

@app.route('/user/<surname>/<name>')
def get_user(name, surname):
    personal_instruc = f"""<h1>Привет, {surname} {name}!</h1>
    <p>Измени имя пользователя в адресной строке и перезагрузи страницу</p>"""
    return personal_instruc

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

В нашем примере значения просто появятся в браузере как часть строки. На стартовой странице нашего сайта будет запускаться функция index(). В ней пользователю, помимо приветствия, будет предлагаться нажать на ссылку, при клике на которую он перейдет на user/Аникин/Георгий. Этот URL-маршрут будет обрабатываться уже функцией get_user.

Функция get_user декорируется @app.route('/<surname>/<name>’), а в адресной строке у нас /user/Аникин/Георгий. То есть наша функция получает аргументы из URL-адреса, эти значения лежат между косых скобок. По умолчанию тип таких значений string принимает любой текст без косой черты. Но переменные маршрутов могут быть и иных типов: int, float, path и других. Типы указываются в формате <тип:имя переменной>.

Структура приложения на Flask

Создадим подкаталог flask_app с такой структурой файлов и папок:

Структура файлов в проекте

Чтобы написать приложение сложнее одной строки, в директории проекта должны находиться папки static и templates. Директория static содержит ресурсы, которые используются шаблонами. В том числе включая файлы CSS, JavaScript и картинки. Папка templates содержит только шаблоны с расширением *.html.

Заполним наши файлы кодом. Сначала — наш основной файл проекта app.py:

from flask import Flask, render_template

app = Flask(__name__)

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


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

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

После этого — index.html:

<!DOCTYPE html>
<html>
    <head>
        <title>Main page</title>
    </head>
    <body>
        <h1>Главная страница</h1>
    </body>
</html>

И файл about.html:

<!DOCTYPE html>
<html>
    <head>
        <title>About</title>
    </head>
    <body>
        <h1>О приложении</h1>
    </body>
</html>

Для отображения HTML-шаблонов мы используем функцию render_template(). В нашем коде она принимает только имя шаблона и возвращает строку с результатом рендеринга шаблона.

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

Напишем базовый шаблон base.html и пару его наследников. При этом блоки {% block smth %} … {% endblock %} — это части базового шаблона, которые можно заменить в наследнике. Переменные передаются по именам в конструкции {{ variable }}.

<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}Приложение Flask{% endblock %}</title>
</head>
<body>
    <h1>{{h1}}</h1>
</body>
</html>

После появления файла с базовым HTML-шаблоном можем поправить наши остальные HTML-файлы:

about.html:
{% extends 'base.html' %}
{% block title %}About{% endblock %}

index.html:
{% extends 'base.html' %}
{% block title %}Main page{% endblock %}

Кроме того, нужно поправить и основной файл Flask-проекта app.py:

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def index():
    return render_template("index.html", h1 = "Главная страница")

@app.route("/about")
def get_page_about():
    return render_template("about.html", h1 = "О приложении")

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

Подключаем Bootstrap

Bootstrap — это открытый и бесплатный набор инструментов для создания сайтов и веб-приложений.

В нашем проекте в папке templates у нас есть подкаталог bootstrap, а в нем файл base.html — это немного модифицированная заготовка сайта-документации Bootstrap-Flask:

<!doctype html>
<html lang="en">
    <head>
        {% block head %}
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

        {% block styles %}
            <!-- Bootstrap CSS -->
            {{ bootstrap.load_css() }}
        {% endblock %}

        <title>{% block title %}Приложение Flask{% endblock %}</title>
        {% endblock %}
    </head>
    <body>
        <!-- Your page content -->
        {% block content %}
            <div class="jumbotron text-center">
            <h1>{{h1}}</h1>
            </div>
        {% endblock %}

        {% block scripts %}
            <!-- Optional JavaScript -->
            {{ bootstrap.load_js() }}
        {% endblock %}
    </body>
</html>

В файлах index.html и about.html заменим строку наследования на:

{% extends 'bootstrap/base.html' %}

Второй путь подключения Bootstrap к проекту на Flask — через CDN. Подробнее об этом можно почитать в документации фреймворка.

Читайте также:
Как создатель Python Гвидо ван Россум устроился в Microsoft и теперь работает над развитием CPython

После подключения Bootstrap нужно будет немного поправить основной файл нашего проекта app.py:

from flask_bootstrap import Bootstrap4
from flask import Flask, render_template

app = Flask(__name__)
bootstrap = Bootstrap4(app)

@app.route("/")
def index():
    return render_template("index.html", h1 = "Главная страница")

@app.route("/about")
def get_page_about():
    return render_template("about.html", h1 = "О приложении")

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

Последним элементом нашего веб-приложения будет форма отправки. Для этого нужно немного модифицировать index.html:

{% extends 'bootstrap/base.html' %}
{% block title %}Main page{% endblock %}
{% block content %}
   {{super()}}
   <div class="container text-center">
       <form class="d-inline-block" style="max-width: 33%;">
           <div class="form-group">
               <label for="eventDate">Дата</label>
               <input type="date" name="eventDate" class="form-control" placeholder="Дата события">
           </div>
           <div class="form-group">
               <label for="eventName">Событие</label>
               <input type="text" name="eventName" class="form-control" placeholder="Название события">
           </div>
           <div class="form-group">
               <label for="eventDuration">Продолжительность</label>
               <input type="number" name="eventDuration" class="form-control" placeholder="Продолжительность" min="1" max="24">
           </div>
           <button type="submit" class="btn btn-primary">Записать</button>
       </form>
   </div>
{% endblock %}

Вообще, Bootstrap может добавить огромное количество элементов в приложение буквально в несколько кликов. Мы ограничились четырьмя — три поля и одна кнопка. Ключевой элемент здесь — это {{ super() }}.

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

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

Есть большое количество способов работы с SQL-запросами во Flask. Мы можем использовать, например, sqlite3 и чистый SQL, а можем — библиотеку sqlite3 для Python. Кроме того, можно обернуть чистые SQL-запросы в код, либо использовать Psycopg2 для работы с PostgresSQL в Python (мы рекомендуем делать именно так и вот почему). Для примера в этом тексте мы используем библиотеку Flask SQLAlchemy (расширение для Flask), которая предлагает технологию ORM для взаимодействия с БД.

Подключаем базу данных к нашему проекту через файл app.py:

from datetime import datetime


from flask import Flask, redirect, render_template, request
from flask_bootstrap import Bootstrap4
from flask_sqlalchemy import SQLAlchemy


app = Flask(__name__)
bootstrap = Bootstrap4(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///events.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)


class Event(db.Model):
   id = db.Column(db.Integer, primary_key=True)
   date = db.Column(db.Date, nullable=False)
   name = db.Column(db.String(255), nullable=False)
   duration = db.Column(db.Integer, nullable=False)

   def __str__(self):
       return (
           f"Название: {self.name}n"
           f"Дата: {self.date}n"
           f"Продолжительность {self.duration}ч"
       )


@app.route('/', methods=['POST'])
def add_event():
   date = datetime.strptime(request.form['eventDate'], '%Y-%m-%d').date()
   name = request.form['eventName']
   duration = int(request.form['eventDuration'])
   print(date, name, duration, sep='n')
   event = Event(date=date, name=name, duration=duration)
   db.session.add(event)
   db.session.commit()
   return redirect('/')


@app.route("/")
def index():
   return render_template("index.html", h1 = "Главная страница")


@app.route("/about")
def get_page_about():
   return render_template("about.html", h1 = "О приложении")


if __name__ == "__main__":
   with app.app_context():
       db.create_all()
   app.run(debug=True)

В нашей БД появился класс Event c атрибутами, который наследуется от db.Model. Это позволяет с помощью SQLAlchemy создать таблицу event, а поля нашего класса сделать колонками этой таблицы. Кроме того, мы определили магический метод __str__ для строкового отображения экземпляров класса — это пригодится для отображения в HTML.

Для создания таблицы в блок if __name__ == ‘__main__’ мы добавили команду db.create_all(), а для обработки отправленной формы — метод add_event. Он работает с методом POST, который указывает Flask, что данные будут отправлены на сервер.

В методе POST мы считываем данные отправленной формы и создаем для каждой строки временную переменную. После этого мы создаем объект event класса Event, передаем наши временные переменные как именованные аргументы, добавляем event в БД и фиксируем изменения.

Нам осталось лишь немного поправить форму: в файле index.html в открывающем теге <form> добавим атрибуты action="{{ url_for('add_event') }}" method="POST". Теперь форма отправки по нажатию на кнопку «Записать» будет отправлять данные в базу данных.

Добавим страницу отображения наших записей в новый файл Events.html:

{% extends 'bootstrap/base.html' %}
{% block title %}Events{% endblock %}
{% block content %}
   {{super()}}
   <div class="container text-center">
       <a href="{{ url_for('index') }}"><h2>Добавить событие</h2></a>
   </div>
   <div class="mt-4">
       <ul class="list-group">
           {% for event in events %}
               <li class="list-group-item">
                   <p>{{ event }}</p>
               </li>
           {% endfor %}
       </ul>
   </div>
{% endblock %}

В файл app.py добавим view:

@app.route("/events")
def view_events():
   events = Event.query.order_by(Event.date).all()
   return render_template("events.html", h1 = "События", events=events)

А в основном контейнере index.html добавим ссылку на эту страницу:

<a href="{{ url_for('view_events') }}"><h2>Посмотреть события</h2></a>

Наш тестовый проект на Flask готов! Его можно запустить на локальном сервере через команду python app.py (в некоторых случаях надо будет написать название директории перед названием файла app.py).

Что еще почитать про Flask

  • Большой курс по Flask на Хекслете
  • Документация Flask
  • Цикл статей на Real Python
  • Проектирование RESTful API с помощью Python и Flask

Изучите Python на Хекслете
Пройдите нашу профессию «Python-разработчик», чтобы поменять свою жизнь и стать бэкенд-программистом.

Стать бэкенд-разработчиком

Понравилась статья? Поделить с друзьями:
  • Сервис мануал телевизора erisson
  • Препарат феварин инструкция по применению цена отзывы аналоги
  • Камаз 43501 руководство по ремонту
  • Приказ об утверждении руководства по качеству
  • Асдр комплексон 6 инструкция по эксплуатации