Язык программирования Python

Курс IT-Академии Сухорукова

Декабрь 2019 - январь 2020

Этот курс закончился

Задание. Веб-приложение для голосований

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

Постановка задачи

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

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

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

Структура базы данных

Структура базы данных приложения описывается следующей схемой:

Структура базы данных

Голосование (Poll)

  • id — уникальный идентификатор голосования. Целое число, первичный ключ.
  • title — название голосования. Строка. Обязательное поле.
  • description — описание голосования. Строка Необязательное поле.

Вариант ответа (Variant)

  • id — уникальный идентификатор варианта. Целое число, первичный ключ.
  • poll_id — идентификатор соответствующего голосования, к которому относится этот вариант. Целое число. Не может содержать null.
  • text — текст варианта. Строка. Не может содержать null.

Отданный голос (Vote)

  • id — уникальный идентификатор голоса. Целое число, первичный ключ.
  • variant_id — идентификатор варианта, за который отдан голос. Целое число, не может содержать null.

Логика работы

Голосование

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

Просмотр результатов

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

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

Приложение должно содержать следующие страницы:

  • Главная страница — на ней выводится список доступных голосований. Для каждого голосования выводится его название, а так же ссылки для участия в этом голосовании, для просмотра результатов голосования, а так же для удаления этого голосования. Кроме того, на главной странице ниже списка голосований должна находиться ссылка для создания нового голосования.

  • Создание голосования — на этой странице находится форма создания нового голосования. Поскольку количество вариантов ответа заранее неизвестно, имеет смысл для ввода вариантов ответа использовать поле типа <textarea>, по принципу одна строка — один вариант. После создания голосования происходит перенаправление на страницу проведения этого голосования.

  • Проведение голосования — на этой странице выводится название голосования, описание голосования, а так же форма голосования — список вариантов в виде набора полей <input type="radio">, и кнопка «Оставить голос». После того, как форма обработана, происходит перенаправление на страницу просмотра результатов этого голосования.
  • Просмотр результатов голосования — на этой странице выводится название голосования, описание голосования, а так же список вариантов ответа. Для каждого варианта выводится количество голосов за этот вариант, а так же процентное соотношение голосов.

Кроме того, понадобится view-обработчик удаления указанного голосования. Эта функция не создаёт страницу, а лишь удаляет указанное голосование и перенаправляет пользователя на главную страницу.

Дополнительное задание

Эта часть задания необязательна.

Придумать, как сделать так, чтобы усложнить пользователям «накрутку» голосов, то есть многократный ответ в одном голосовании. Подсказка: хотя регистрации пользователей в приложении не предусмотрено, есть механизм пользовательских сессий Flask. Сессия уникальна для каждого пользователя, и в ней можно хранить любую информацию. Сразу замечу, что складывать в сессию идентификаторы голосований не вариант — размер словаря сессии сильно ограничен (это ограничение появляется из ограничения на размер сookie в браузерах, а всю сессию целиком Flask хранит в одном сookie). Найдите другой способ, который даже при большом количестве голосований на сайте не занимает в сессии много места. Ещё подсказка: в отличие от размера сессии, размер нашей базы данных не ограничен.