Рубрики
Без рубрики

Как использовать Python и Flask для создания веб — приложения-подробное руководство

Как использовать Python и Flask для создания веб — приложения-подробное руководство

Автор оригинала: Abhinav Suri.

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

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

Но, возможно, менее известным использованием Python является его использование в качестве веб-сервера. В тени более популярных фреймворков, таких как Node/Express и Ruby on Rails, Python часто упускается из виду как выбор веб-сервера для большинства разработчиков.

Наличие бэкенда, написанного на Python, действительно полезно по нескольким причинам, среди которых:

  • Легко перейти от изучения Python как обычного языка сценариев к использованию его для создания бэкенда.
  • Его лучше всего использовать, если вы планируете обслуживать части вашего приложения, которые уже написаны на Python (например, отправка формы, оценка входных данных с помощью модели Tensorflow и возврат выходных данных в использование)
  • Он имеет разнообразную экосистему пакетов и инструментов, которые помогут вам в разработке, не говоря уже о большом сообществе разработчиков (поскольку язык существует так долго)

Цель этой статьи-продемонстрировать, как Python можно использовать для создания веб-приложения с полным стеком. В этом уроке я буду использовать Flask, Python “microframework” для разработки веб-приложения.

Я бы не стал упоминать, что существуют и другие более популярные фреймворки Python, такие как Django, но Flask полезен начинающему разработчику, поскольку это голые кости и требует, чтобы разработчики создавали/использовали необходимые им компоненты в приложении на основе их требований (вместо того, чтобы вызывать какой-либо инструмент командной строки, который автоматически генерирует 20 файлов… смотрю на тебя, Рубин на рельсах). Конечно, я не буду рассказывать о том, как запустить веб-приложение полностью с нуля, скорее я дам вам введение в Flask, а затем перейду к тому, как вы можете использовать проект под названием flask-base, чтобы быстро набирать скорость в будущем.

Введение в колбу

Flask-это микрорамка (читай как: она не поставляется с большим количеством) для веб-разработки на Python. Прежде чем мы совершим глубокое погружение, давайте рассмотрим некоторые основные концепции разработки бэкенда.

Источник: flask.pocoo.org

Маршруты

Давайте представим, что вы в гостях apple.com и хотите перейти в раздел Mac по адресу apple.com/mac/ . Как серверы Apple узнают, чтобы предоставить вам конкретную страницу, на которой отображаются сведения об устройствах Mac. Это, скорее всего, потому, что у них есть веб-приложение, работающее на сервере, который знает, когда кто-то смотрит вверх apple.com и переходит в раздел /mac/ веб-сайта, обрабатывает этот запрос и отправляет некоторые страницы обратно. Логика, лежащая в основе выяснения того, что делать, когда кто-то идет в /mac/ , выполняется по маршруту .

Поэтому, когда я посещаю apple.com (подразумевается apple.com/ ), маршрутизатор / обрабатывает то, что показано. Если я пойду в apple.com/purchase , есть /покупка маршрут. Если я пойду в apple.com/purchase/1 где 1 есть какой-то идентификатор элемента, скорее всего, есть универсальный обработчик маршрута /покупка/ , который обрабатывает этот запрос. Маршруты также могут обрабатывать как запросы GET, так и запросы POST.

Базовое приложение

Итак, как мы создадим базовое приложение для колб с маршрутами? Что ж, давайте взглянем на документы. Создайте файл Python с именем hello.py который содержит следующее.

суть

Давайте разберем, что здесь происходит.

  1. Мы импортируем нашу зависимость от колбы
  2. Мы создаем экземпляр приложения Flask. Аргумент, переданный в экземпляр Flask ( __name__|/), преобразуется в строку, которая "называет" приложение Flask. При запуске из командной строки __name__ . Вы можете установить первый аргумент на все, что захотите. Мы настраиваем маршрут
  3. / в нашем приложении, который выполняет функцию hello() непосредственно под ним при посещении этого маршрута. Обратите внимание, что функция должна возвращать строку или отрисованный шаблон.

В командной строке давайте создадим так называемую виртуальную среду (это поможет нам изолировать нашу среду разработки и установки пакетов от остальной части нашей системы).

  1. Если вы еще этого не сделали, установите pip через easy_install pip (возможно, вам придется запустить sudo перед этим, если вы находитесь на Mac.
  2. Запустите pip install virtualenv для установки virtualenv с помощью pip
  3. В каталоге вашего приложения создайте виртуальную среду, запустив virtualenv venv (это создаст виртуальную среду в папке с именем venv текущего каталога).
  4. Запустите source venv/bin/activate , чтобы активировать виртуальную среду. Это особенно необходимо для установки в него пакетов. Вы можете деактивировать виртуальную среду, запустив деактивировать из командной строки. Довольно просто.

Теперь, когда наша виртуальная среда установлена и активирована, давайте установим Flask. Это действительно просто, просто запустите pip install Flask . Затем мы можем запустить пример из предыдущего, написав следующее в нашей командной строке.

суть

Вы должны увидеть что-то вроде * http://localhost:5000/ в вашем терминале. И если вы перейдете по этой ссылке в своем браузере, вы увидите страницу с просто Hello World .

Пример приложения: Обзор Penn Club

Примечание: Код для этого проекта можно найти в этом репозитории на GitHub .

Теперь давайте придумаем какой-нибудь проект для создания, чтобы продемонстрировать все возможности колбы. Один из недавних проектов, который я придумал, – это приложение для оценки клубов под названием “Обзор Penn Club”.

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

Ярмарка клуба UPenn

Итак, чтобы бороться с этой проблемой, мы можем создать приложение, в котором

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

Разбиение компонентов приложения

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

Введите Основание колбы

Flask-base-это проект, который мы с друзьями разработали в рамках студенческой некоммерческой организации под названием Hack4Impact . Мы работаем с некоммерческими организациями в течение семестра, чтобы разработать технические проекты, которые помогут им выполнить свою миссию.

Работая над таким количеством проектов, мы обнаружили, что часто повторяем один и тот же код во всех наших приложениях. Поэтому мы решили создать единую базу кода, содержащую наиболее распространенные части, которые понадобятся любому созданному нами приложению. Эта кодовая база будет включать в себя:

  • Схема аутентификации пользователя
  • Управление учетными записями
  • Чертежи (для обработки маршрутов)
  • Резервное копирование базы данных
  • Электронная почта (с очередью redis)

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

Настройка разработчика приложений

Сначала давайте клонируем колбу-базу. Следуйте инструкциям на README.md страница. В двух словах выполните следующее.

суть

ОК. Я подробно расскажу о том, что мы здесь сделали.

  • Клонируйте репозиторий с GitHub (т. Е. загрузите его), а затем перейдите в его каталог.
  • Создайте новую виртуальную среду и активируйте ее.
  • Прочитайте зависимости пакетов в requirements.txt файл и установите их все через pip .
  • Создайте экземпляр базы данных (создайте ее заново), а также вставьте правило администратора (через setup_dev).

Кроме того, давайте создадим запущенную миграцию базы данных. Это позволит отслеживать изменения в наших моделях баз данных без необходимости воссоздавать нашу базу данных (т. Е. Удалять всю информацию, а затем перестраивать базу данных с нуля). Миграции позволяют нам сохранять информацию. Мы можем сделать это с помощью команды ниже.

суть

Чтобы запустить приложение, запустите honcho start-f Local (вам нужно будет установить Honcho, если вы еще этого не сделали). Если у вас есть какие-либо проблемы, скорее всего, они уже были рассмотрены в README базы колб. Теперь вы можете посетить localhost:5000 и вытащить работающее приложение на базе колбы.

Чтобы войти в приложение в качестве администратора, перейдите по ссылке входа в систему и введите имя пользователя flask-base-admin@example.com с паролем пароль . Затем вы можете пригласить новых пользователей в приложение с экрана администратора. Обратите внимание, что перед этим вам нужно будет создать файл config.env , содержащий следующие две переменные:

MAIL_PASSWORD=someSendGridPassword
MAIL_USERNAME=someSendGridUsername

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

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

Базы данных!

Вся наша логика базы данных обернута ORM SQLAlchemy, поэтому нам не нужно делать очень подробные инструкции базы данных для выполнения запросов или добавления/удаления записей. Все базы данных models (думайте о них как о классах) содержатся в папке app/models . Давайте подумаем о некоторых моделях, которые необходимы для самого приложения.

Поэтому нам нужна модель Club , содержащая имя клуба (тип данных: Строка), описание клуба (Тип данных: Текст) и переменную is_confirmed (Тип данных: логический), чтобы отслеживать, был ли предложенный клуб одобрен администратором для отображения. Кроме того, мы хотим каким-то образом ссылаться на категории клуба и другим способом ссылаться на ответы на вопросы, которые принадлежат клубу.

Давайте подумаем о том, как Клубы и Категории клубов должны соотноситься друг с другом. Мы можем думать об этом следующим образом. Клуб имеет много категорий (например, клуб может быть Социальным воздействием и Техническим клубом), и категория клуба может принадлежать многим клубам (например, в кампусе может быть много Технических клубов). Единственный атрибут этой Клубной категории имеет category_name (Тип данных: Строка).

Мы можем создать эту связь (связь “многие ко многим”) с помощью таблицы ассоциаций.

Клуб и Категории клубов (Многие ко многим)

Теперь, как мы закодируем эту логику в основу колбы? Сначала создайте файл с именем club.py в приложение/модели . Сначала давайте создадим Клуб и Категорию клуба модели.

суть

Итак, теперь у нас есть две модели, но они не связаны друг с другом. Каждый из них имеет индивидуальные атрибуты, но ни один из них не может быть явно связан друг с другом. Мы устанавливаем связь через ассоциацию, как я упоминал ранее. После импорта db добавьте следующие строки.

суть

Это создает новую ассоциативную таблицу (посредник между моделью Клуба и категорией клуба). В этой таблице есть два столбца club_id и club_category_id , которые ссылаются на соответствующие идентификаторы соответствующих моделей (обратите внимание, что атрибут id является первичным ключом в каждой модели, т. Е. уникальным для каждой записи). Но в таблице ассоциаций мы называем эти первичные ключи внешними ключами (потому что они ссылаются на другие таблицы). Кроме того, нам нужно добавить строку в модель Club внизу.

categories = db.relationship(
        'ClubCategory', secondary=club_category_assoc, backref='clubs')

И это фактически создает двунаправленную связь между Club и Категорией клуба моделями и устанавливает связь между Club и ClubCategory с помощью таблицы ассоциаций club_category_assoc . backref указывает категории Club model, как обращаться к моделям Club . Итак, с данным клубом club вы можете запустить club.categories , чтобы получить массив объектов категории. С заданной категорией Club под названием category вы можете получить все клубы в этой категории , выполнив category.clubs .

Вы можете увидеть это в действии, выполнив следующие действия:

В приложение/модели/__init__.py добавить строку

суть

А затем запустите python manage.py оболочка . Выполните следующие команды для взаимодействия с моделями баз данных (обратите внимание, что >>> указывает на вводимые данные).

суть

Вопросы и ответы (Много к одному)

Отлично! Теперь у нас есть рабочий клуб и модель категории клуба. Теперь давайте перейдем к моделям Вопрос и Ответ|/. Для вопроса нам нужно отслеживать содержание вопроса, который будет представлять собой строку, содержащую текст самого вопроса. Мы также включим атрибут max_rating , который будет содержать максимальную оценку, которую человек может дать за вопрос. Например, если содержание вопроса "Оцените сообщество клуба 10 как лучшее", мы могли бы установить max_rating равным 10. Кроме того, мы будем отслеживать логическое значение free_response , чтобы определить, позволим ли мы людям включать необязательный дополнительный ответ в длинную форму. Наконец, нам нужно будет иметь отношение к модели Answer . Это будет отношение "один ко многим", потому что вопрос может иметь несколько ответов, но ответ может иметь только один вопрос.

Модель Answer будет иметь следующие атрибуты:

  • атрибут answer , соответствующий ответу на свободный текст ответа (если вопрос допускает ответ на свободный текст)
  • a рейтинг в диапазоне от 1 до любого максимального рейтинга для вопроса
  • a user_id , относящийся к пользователю, который написал вопрос (опять же, у пользователя может быть много ответов, но ответ может иметь только один пользователь)
  • a question_id ссылка на вопрос , к которому относится ответ
  • a club_id ссылка на клуб ответ принадлежит

Давайте создадим файл question.py

суть

Большая часть материала здесь довольно проста, за исключением последней строки. Последняя строка соединяет модели Вопрос и Ответ|/. В нем говорится, чтобы установить связь с моделью Answer , которая может ссылаться на модель Question с помощью ключевого слова question . Получив ответ a , вы можете получить вопрос через a.question , а получив вопрос q , вы можете получить связанный с ним ответ через q.answers . Теперь давайте настроим модель Answer . Создайте новый файл с именем answer.py в папку models и вставьте следующее.

суть

Таким образом, этот файл намного длиннее, но помните, что есть много вещей, с которыми связан ответ. Давайте начнем с самого начала, обратите внимание, что question_id ссылается на модель Question через внешний ключ questions.id (столбец id таблицы questions (который содержит записи экземпляров модели Question ).

Обратите внимание, что у нас также есть столбец user_id , который ссылается на пользователя. Давайте перейдем к user.py в папке app/models и добавьте следующую строку после объявления role_id .

суть

Этот оператор использует синтаксис, очень похожий на синтаксис модели Question .

Также обратите внимание, что существует атрибут club_id , который ссылается на клуб, с которым связан ответ. Отредактируйте club.py файл, чтобы включить следующую строку в качестве последнего атрибута модели Club .

суть

Наконец, добавьте эти две строки в __init__.py в приложение/модели

суть

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

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

Еще раз, мы можем запустить python manage.py оболочка

суть

Вот, теперь мы закончили с моделями

Просмотры

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

Чертежи

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

С каждым чертежом связана папка в разделе app . Например, есть папка account/ и папка в разделе templates , содержащая фактические шаблоны html, которые будут отображаться пользователю.

Давайте добавим несколько чертежей. Перед return app строкой app/__init__.py добавить следующее.

суть

Эти вызовы создают чертежи, смонтированные в префиксах url /club , /question и /category соответственно. Давайте создадим папки клуб , вопрос и категория для каждого из чертежей. В каждой из папок создайте файлы __init__.py , forms.py , и views.py .

Клубные формы и виды

Я расскажу, как настроить представления/шаблоны для club blueprint. Другие представления довольно легко понять из кода.

Поэтому в рамках представления клуба мы хотим показать несколько разных вещей

  1. Если вы являетесь администратором, вы должны иметь возможность создать клуб и дать ему имя, описание и категории.
  2. Если вы являетесь администратором, вы должны иметь возможность просматривать все клубы, включая те, которые не подтверждены.
  3. Если вы являетесь администратором или пользователем, вы должны иметь возможность просматривать информацию об отдельном клубе.
  4. Если вы являетесь администратором, вы должны иметь возможность редактировать информацию о клубе и удалять клуб.

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

В forms.py для клуба добавить следующие строки:

суть

Колба-база использует wtforms для создания форм. wtforms позволяет нам создавать формы объектно-ориентированным способом, где каждая форма является классом.

Таким образом, мы создаем две формы, одна из которых называется NewClubForm , которая расширяет базовый класс wtforms | Form и имеет 3 поля - name (Тип данных: Текст), desc (Тип данных: Текст), содержащий описание клуба, и categories (выпадающий список множественного выбора). С помощью поля categories мы запрашиваем модель Club Category с помощью лямбда-функции (которая в основном является анонимной функцией) для имен категорий и заполняем параметры поля выбора категории результатами этого запроса.

Наконец, у нас есть поле submit , поэтому кнопка “Отправить” может быть отображена.

Затем у нас есть Edit Club Из , который расширяет набор полей New Club Form , добавив новое поле с именем is_confirmed . Напомним, что is_confirmed в нашей модели Club определяет, может ли данный экземпляр клуба быть показан или не показан общественности. Мы добавим функцию для клуба, который будет предложен пользователями, и по умолчанию предлагаемые клубы скрыты до утверждения администратором. Мы также перезаписываем поле submit , чтобы отобразить текст “Edit Club”.

В views.py в разделе клуб/ мы создаем несколько маршрутов.

  • /new-club (GET, POST) ЛОГИН ЗАЩИЩЕН: Программа отображает и принимает данные из формы для создания нового клуба.
  • /клубы (GET) ADMIN PROTECTED: Отображает все клубы
  • //(:info) (GET) LOGIN PROTECTED: Будет отображать информацию для данного экземпляра клуба с id и может получить доступ к маршрутизатору в/club/1 или/club/1/info.
  • //change-club-details (GET, POST) ADMIN PROTECTED: Визуализация и прием данных из формы для редактирования информации о клубе.
  • //delete (GET) ADMIN PROTECTED: Визуализация страницы для удаления клуба
  • //_delete (GET) ADMIN PROTECTED: Удалить клуб с идентификатором клуба.

Для первого маршрута /new-club мы также хотим разрешить обычным пользователям создавать новый клуб , поэтому мы только входим в него. Давайте посмотрим, как мы можем проложить маршрут для этого.

суть

Взлом кода. В строке 1 мы указываем, где будет доступен маршрут. Например, он будет на схеме club в подмаршруте /new-club. Полный URL-адрес, по которому он может быть доступен, – это basedomain.com/club/new-club .

Затем мы помещаем на маршрут декоратор маршрута @login_required , этот декоратор выдаст ошибку 403, если пользователь не вошел в систему, но также позволит пользователю просматривать маршрут, если он вошел в систему.

Далее мы определяем метод обработки запросов к маршруту (обратите внимание, что это имя должно быть уникальным). На этот метод может ссылаться club.new_club в шаблонах Jinja.

Затем мы создаем экземпляр нашей Новой клубной формы , которую мы создали ранее. В следующей строке мы проверяем, была ли отправлена форма (обратите внимание, что этот маршрут также будет принимать запросы на отправку) с помощью метода form.validate_on_submit () . Если это так, то мы создаем новый экземпляр Club с именем , описанием и категориями , соответствующими полям формы. Примечание для is_confirmed мы устанавливаем его равным тому, является ли текущий пользователь администратором или нет (потому что, если обычный пользователь отправляет эту форму, мы хотим, чтобы новый клуб не появлялся для всех, поэтому мы устанавливаем is_confirmed в False). Затем мы добавляем новый экземпляр клуба в сеанс базы данных и фиксируем сеанс.

Наконец, если пользователь, отправляющий форму, не является администратором, мы создаем ссылку для отправки администратору формы по электронной почте. Эта ссылка должна перейти непосредственно к маршруту admin change_club_details , который позволит администратору переключаться is_confirmed . Затем мы просматриваем базу данных для всех пользователей с ролью администратора и добавляем задачу электронной почты в нашу очередь redis. В рамках метода get_queue() мы ставим в очередь задание send_email , в частности, устанавливая получателю адрес электронной почты администратора, тема которого равна

суть

добавьте экземпляр club (для использования в качестве переменной шаблона) и ссылку (также для использования в качестве переменной шаблона).

Мы также передаем шаблон , который мы создаем в app/templates/club/email/suggested_club.html и .текст . Содержимое html-файла выглядит следующим образом:

суть

и для файла .txt

суть

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

суть

И шаблон клуба, который мы визуализируем, находится по адресу app/templates/club/clubs.html со следующим содержанием.

суть

Большая часть этого довольно проста, если вы знаете Дзиндзя (или любой другой язык шаблонов). В принципе, цикл for {% for c в клубах %} ... {% endfor %} пройдет через все клубы, и для каждого клуба он отобразит название клуба {{ c.name }} и категории клубов.

суть

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

суть

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

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

суть

Мы также можем настроить несколько других маршрутов, потому что наш manage_club.html страница на самом деле отображает несколько маршрутов.

Давайте настроим маршрут /change-club-details , который просто отображает и принимает информацию из формы Edit Club .

суть

Обратите внимание, что при сохранении поля club.is_confirmed нам необходимо преобразовать строковые значения True и False в их логические аналоги, как указано в forms.py спецификация для EditClubForm . Мы делаем это с помощью пользовательской функции bool , которая определяется следующим образом:

суть

Python по умолчанию bool вернет True , если определена какая-либо строка , включая False' , поэтому нам нужно определить нашу собственную функцию.

Мы также определяем delete для отображения страницы удаления и функции _delete , которая фактически удаляет экземпляр клуба.

суть

Обратите внимание, что для маршрута _delete у нас есть перенаправление на маршрут clubs , в котором перечислены все экземпляры клуба.

Теперь перейдем к manage_club.html шаблон в app/templates/club/manage_club.html . Содержание этого заключается в следующем:

суть

Давайте разберем этот файл. В первой строке мы просто расширяем наш базовый макет, а затем импортируем из макросов. Макросы-это в основном методы в Дзиндзя.

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

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

суть

Наконец, мы фактически пишем логику для отображения страницы в тегах {% block content %} ... {% endblock%} . Мы переключаемся между подстраницами для визуализации, проверяя request.endpoint , чтобы увидеть, является ли это конечной точкой удаления или есть ли форма (в этом случае визуализируйте форму). В противном случае мы просто вызываем макрос club_info . И мы закончили с клубными маршрутами и видами. Большинство других маршрутов для категорий и вопросов следуют аналогичной логике.

Основные виды и формы

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

  • /(GET): отображение всех клубов, связанных вопросов и средних оценок для каждого клуба по каждому вопросу в таблице.
  • /submit-review/(GET, POST): Динамическое создание формы для отправки клубного обзора на основе вопросов в Question db. Также примите данные для формы и сохраните как ответы для клуба, соответствующего club_id.

Первый маршрут очень прост и соответствует маршруту /клубы , который мы реализовали ранее. Разница лишь в том, что вопросы также должны быть переданы.

Самая интересная часть здесь заключается в том, как рассчитать средний рейтинг и передать его в маршрут. Я создаю список под названием all_c и для каждого из клубов я создаю club_obj , содержащий основную информацию для клуба.Для каждого из ответов для клуба я добавляю новое свойство club_obj , соответствующее содержанию вопроса, если оно еще не существует. Я добавляю каждый из рейтингов в список, а затем повторяю каждое из свойств club_obj . Если свойство имеет значение типа list, то я заменяю этот список средним значением оценок в этом списке. Затем я добавляю club_obj к all_c и передаю это в шаблон.

Динамическая генерация форм

Для маршрута submit-review мне нужно создать форму динамически на основе вопросов, которые у меня есть в моей модели Question . Код выглядит следующим образом:

суть

Сначала мы создаем фиктивный класс формы, который наследуется от базового класса Form . Затем для каждого из вопросов мы создаем новые поля формы setattr(F, ...) на фиктивной форме F . Метод setattr принимает в качестве второго аргумента имя поля формы. Мы устанавливаем это на идентификатор вопроса с добавлением _q , соответствующий рейтингу, и _resp , соответствующий свободному ответу, если указано. Для поля формы оценки мы создаем поле Select с выбором от 1 до max_rating .

Для обработки отправки формы мы используем тот же оператор if form.validate_on_submit () , но вместо поиска конкретных именованных полей формы мы вместо этого перебираем все поля формы и создаем новый ответ с помощью метода newAnswer . Этот метод удалит любой предыдущий ответ перед добавлением нового для пользователя, если он ответил за этот клуб.

Запуск

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

Если вы никогда не подписывались на Heroku

  1. Перейти к Heroku.com и зарегистрируйте учетную запись
  2. Установите КЛИЕНТ

Если вы изначально не настроили репо git, запустите git init и войдите в свою учетную запись Heroku.

Затем git добавляет Все соответствующие файлы (т. Е. Все, что угодно, кроме config.env и env/ ) и запускает pip freeze > requirements.txt чтобы убедиться, что все установленные вами зависимости включены.

Запустите heroku create , чтобы создать новый экземпляр Heroku, и запустите git push heroku master , чтобы добавить ваши файлы в репозиторий Heroku.

После этого вам нужно будет установить некоторые переменные среды с помощью следующей команды

суть

Как только это будет сделано, выполните следующие действия, которые создадут базу данных на Heroku

суть

а затем следующая команда создаст учетную запись администратора.

суть

Вам также потребуется создать экземпляр Redistogo для обработки очереди задач

суть

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

суть

Затем вы можете запустить heroku open , чтобы открыть запущенное приложение Heroku в отдельном окне.

Расширение приложения и заключение

Довольно легко скопировать текущую структуру приложения и расширить ее, чтобы добавить в приложение дополнительную информацию/маршруты. Просто просмотрите любой из предыдущих маршрутов, которые были реализованы. Если по какой-то причине вы хотите включить загрузку файлов какого-либо типа, вам нужно будет интегрировать приложение с Amazon S3, если вы планируете запускать приложение на Heroku (поскольку у него эфемерная файловая система).

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