🔥 Самостоятельная работа 1 — Система управления задачами#

В проекте Learning Log вы уже создавали модели, формы, представления, маршруты, шаблоны и систему пользователей. Теперь нужно самостоятельно перенести эти приёмы в новую предметную область.

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

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

Пользователь должен уметь:

  • создавать задачи;
  • просматривать список своих задач;
  • редактировать задачи;
  • удалять задачи после подтверждения;
  • назначать срок выполнения;
  • выбирать приоритет;
  • отмечать задачу выполненной и возвращать её в работу.

Имена проекта и приложения#

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

Объект Имя
Каталог и Django-проект task_manager
Приложение задач tasks
Приложение пользователей users
Основная модель Task

Виртуальное окружение не добавляйте в архив или репозиторий проекта.

Модель Task#

Модель должна содержать как минимум следующие поля:

Поле Рекомендуемый тип Назначение
owner ForeignKey к пользователю Владелец задачи
title CharField(max_length=200) Краткое название
description TextField(blank=True) Подробное описание
date_added DateTimeField(auto_now_add=True) Дата создания
due_date DateTimeField(null=True, blank=True) Срок выполнения
priority CharField с choices Низкий, обычный или высокий приоритет
completed BooleanField(default=False) Выполнена ли задача

Метод __str__() должен возвращать понятное название задачи. Значение приоритета по умолчанию — обычный.

После создания или изменения модели выполните миграции и убедитесь, что команда python manage.py check не сообщает об ошибках.

Формы#

Создайте TaskForm на базе ModelForm.

В форме пользователь может изменять:

  • название;
  • описание;
  • срок выполнения;
  • приоритет;
  • состояние выполнения.

Поля owner и date_added не должны передаваться пользователем. Владельца назначайте в представлении через request.user перед первым сохранением объекта.

Для срока выполнения используйте удобный HTML-виджет даты и времени. Проверьте, что некорректное значение не приводит к ошибке 500, а отображает ошибку формы.

Обязательные страницы#

Страница Пример URL Доступ
Главная / Всем
Список задач /tasks/ После входа
Создание задачи /tasks/new/ После входа
Редактирование /tasks/<id>/edit/ Только владельцу
Удаление /tasks/<id>/delete/ Только владельцу
Изменение состояния /tasks/<id>/toggle/ Только владельцу
Вход /users/login/ Всем
Регистрация /users/register/ Всем
Выход /users/logout/ Только методом POST

Вы можете добавить отдельную страницу задачи, фильтры и другие URL, но обязательные маршруты должны работать.

Логика списка задач#

На странице списка показывайте только объекты текущего пользователя:

Task.objects.filter(owner=request.user)

Рекомендуемый порядок:

  1. невыполненные задачи;
  2. высокий приоритет перед обычным и низким;
  3. ближайший срок выполнения;
  4. задачи без срока — в конце.

Допускается более простой порядок, если он явно описан в README и одинаково работает после перезагрузки страницы.

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

Безопасность и разграничение доступа#

Все страницы с пользовательскими данными защитите декоратором login_required или эквивалентным механизмом классовых представлений.

Любой объект получайте вместе с проверкой владельца:

task = get_object_or_404(Task, id=task_id, owner=request.user)

Обязательные правила:

  • пользователь не видит чужие задачи в списке;
  • подбор чужого ID для просмотра, изменения, удаления или смены состояния возвращает 404;
  • создание задачи всегда связывает её с текущим пользователем;
  • удаление, смена состояния и выход выполняются POST-запросом с CSRF-токеном;
  • анонимный пользователь перенаправляется на страницу входа;
  • несуществующий ID возвращает 404, а не 500.

Оформление через django-bootstrap4#

Используйте тот же пакет django-bootstrap4, который применялся в Learning Log. Для всех страниц проекта должен использоваться Bootstrap 4.

Установите пакет в активированном виртуальном окружении:

pip install django-bootstrap4

Добавьте приложение в INSTALLED_APPS:

'bootstrap4',

В базовом шаблоне загрузите теги и ресурсы Bootstrap 4:

{% load bootstrap4 %}
{% bootstrap_css %}
{% bootstrap_javascript jquery='full' %}

Для оформления форм используйте теги bootstrap_form и bootstrap_button либо классы Bootstrap 4, изученные в Learning Log.

Интерфейс должен содержать:

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

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

Этапы выполнения#

  1. Создайте проект, приложения и виртуальное окружение.
  2. Опишите модель Task, зарегистрируйте её в административном интерфейсе и выполните миграции.
  3. Создайте суперпользователя и несколько тестовых задач.
  4. Реализуйте регистрацию, вход и POST-выход.
  5. Реализуйте список только собственных задач.
  6. Добавьте создание и редактирование через TaskForm.
  7. Добавьте безопасное удаление и переключение состояния.
  8. Подключите django-bootstrap4 и добавьте адаптивное оформление.
  9. Проверьте работу с двумя разными пользователями.
  10. Добавьте автоматические тесты и README.

После каждого этапа запускайте:

python manage.py check
python manage.py test

Сценарии приёмки#

№ Действие Ожидаемый результат
1 Открыть /tasks/ без входа Перенаправление на вход
2 Зарегистрироваться Пользователь создан и выполнен вход
3 Создать задачу Задача появилась только у создателя
4 Изменить срок и приоритет Новые данные сохраняются
5 Отметить задачу выполненной Состояние и оформление изменились
6 Вернуть задачу в работу Состояние снова стало активным
7 Войти вторым пользователем Задачи первого пользователя не видны
8 Подставить ID чужой задачи Ответ 404, данные не изменены
9 Подставить несуществующий ID Ответ 404, сервер продолжает работать
10 Удалить задачу После подтверждения задача исчезла
11 Отправить удаление методом GET Удаление не выполняется
12 Выйти из системы POST-выход завершает сеанс

Обязательные автоматические тесты#

Добавьте тесты, которые подтверждают:

  • необходимость авторизации;
  • фильтрацию списка по владельцу;
  • автоматическое назначение владельца при создании;
  • запрет изменения чужой задачи;
  • запрет удаления чужой задачи;
  • ответ 404 для отсутствующего ID;
  • переключение состояния задачи;
  • невозможность удаления через GET.

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

После выполнения обязательной части можно добавить:

  • фильтры «все», «активные», «выполненные», «просроченные»;
  • поиск по названию и описанию;
  • пагинацию;
  • категории или теги;
  • напоминание о приближающемся сроке;
  • дату фактического завершения;
  • API на Django REST Framework.

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

Что сдавать#

Для запуска на учебном сервере используйте раздел «Деплой на сервер»: создайте отдельный проект и замените learning_log.wsgi:application на task_manager.wsgi:application в Dockerfile и compose.yaml.

Передайте две ссылки:

  1. На публичный репозиторий проекта в GitHub.
  2. На развёрнутое приложение, которое открывается по IP-адресу учебного сервера и выделенному порту.

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

В репозитории обязательно должны находиться:

  • README.md с понятной инструкцией по развёртыванию проекта на сервере;
  • compose.yaml для быстрого запуска проекта командой docker compose up -d --build;
  • все исходные файлы, зависимости и миграции, необходимые для запуска.

Файл .env, секретные ключи, пароли, база с реальными данными и виртуальное окружение в GitHub не загружайте. Перечень необходимых переменных окружения опишите в README.md.