🔥 Самостоятельная работа 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)
Рекомендуемый порядок:
- невыполненные задачи;
- высокий приоритет перед обычным и низким;
- ближайший срок выполнения;
- задачи без срока — в конце.
Допускается более простой порядок, если он явно описан в 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.
Интерфейс должен содержать:
- общую навигационную панель;
- имя вошедшего пользователя;
- кнопки входа, регистрации и выхода;
- заметную кнопку создания задачи;
- карточки или таблицу задач;
- цветные обозначения приоритета;
- отдельное оформление выполненных и просроченных задач;
- подтверждение перед удалением;
- понятные сообщения об ошибках формы;
- корректное отображение на экране телефона.
Не используйте цвет как единственный признак: рядом с цветом должен быть текст или значок.
Этапы выполнения#
- Создайте проект, приложения и виртуальное окружение.
- Опишите модель
Task, зарегистрируйте её в административном интерфейсе и выполните миграции. - Создайте суперпользователя и несколько тестовых задач.
- Реализуйте регистрацию, вход и POST-выход.
- Реализуйте список только собственных задач.
- Добавьте создание и редактирование через
TaskForm. - Добавьте безопасное удаление и переключение состояния.
- Подключите
django-bootstrap4и добавьте адаптивное оформление. - Проверьте работу с двумя разными пользователями.
- Добавьте автоматические тесты и 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.
Передайте две ссылки:
- На публичный репозиторий проекта в GitHub.
- На развёрнутое приложение, которое открывается по IP-адресу учебного сервера и выделенному порту.
Публикация приложения во внешней сети через домен и HTTPS не обязательна. Преподаватель может настроить её через свой шлюз по запросу.
В репозитории обязательно должны находиться:
README.mdс понятной инструкцией по развёртыванию проекта на сервере;compose.yamlдля быстрого запуска проекта командойdocker compose up -d --build;- все исходные файлы, зависимости и миграции, необходимые для запуска.
Файл .env, секретные ключи, пароли, база с реальными данными и виртуальное окружение в GitHub не загружайте. Перечень необходимых переменных окружения опишите в README.md.