🏠 Закрепляющее задание

Примечание: Это закрепляющее задание по материалу урока 28. LMS-домашнего задания по данному практикуму не предусмотрено — этот урок целиком является практикумом на занятии. Задание ниже позволит углубить понимание темы самостоятельно.

⚡ Кратко: что сделать

  1. Расширить проект: добавить API для задач (TaskListAPIView, TaskDetailAPIView)
  2. Добавить фильтрацию задач по статусу и приоритету через query_params
  3. Написать сериализатор для вложенного вывода тегов в задаче
  4. Проверить через Postman: GET/POST/PUT/DELETE для /api/v1/tasks/tasks/

Задание: расширить Agile Projects — API для задач

После прохождения практикума у вас есть полный CRUD для тегов и проектов, а также загрузка файлов. Пора добавить самое важное — API для задач.

Часть 1 — Сериализаторы задач

  1. В модуле apps/tasks/serializers/ создайте файл task_serializers.py.
  2. Создайте сериализатор TaskListSerializer для отображения списка задач:
    • Поля: id, name, status, priority, deadline, project
  3. Создайте сериализатор TaskDetailSerializer для детального отображения:
    • Поля: все поля модели Task
    • Поле tags должно показывать теги как вложенные объекты (использовать TagSerializer(many=True, read_only=True))
  4. Создайте сериализатор CreateTaskSerializer для создания задачи:
    • Поля: name, description, status, priority, project, tags, deadline, assignee
    • Валидация: deadline не может быть в прошлом

Часть 2 — Views для задач

  1. Создайте файл apps/tasks/views/task_views.py.
  2. Реализуйте TaskListAPIView:
    • GET: список задач с фильтрацией по status и priority через query_params
    • POST: создание новой задачи
  3. Реализуйте TaskDetailAPIView:
    • GET: получение задачи по pk с вложенными тегами
    • PUT: частичное обновление (partial=True)
    • DELETE: «мягкое удаление» — установить deleted_at = timezone.now() вместо реального удаления из БД

Часть 3 — URL-маршруты

  1. Зарегистрируйте новые views в apps/tasks/urls.py:
    • /api/v1/tasks/tasks/TaskListAPIView
    • /api/v1/tasks/tasks/<int:pk>/TaskDetailAPIView

Часть 4 — Мягкое удаление

Реализуйте логику «мягкого удаления» (soft delete): задача не удаляется из БД, а помечается как удалённая через поле deleted_at.

  1. В TaskListAPIView.get_objects() добавьте фильтр: показывать только задачи, где deleted_at IS NULL
  2. В методе delete класса TaskDetailAPIView установите task.deleted_at = timezone.now() и сохраните объект вместо вызова task.delete()

Подготовка окружения

# 1. Клонировать/создать проект
python -m venv venv
venv\Scripts\activate          # Windows PowerShell
# source venv/bin/activate     # macOS/Linux

# 2. Установить зависимости
pip install django djangorestframework

# 3. Создать проект Django
django-admin startproject agile_projects .

# 4. Добавить DRF в INSTALLED_APPS
# settings.py → INSTALLED_APPS → 'rest_framework'

# 5. Создать структуру
mkdir apps
echo "" > apps/__init__.py
cd apps
python ../manage.py startapp tasks
python ../manage.py startapp projects
cd ..

# 6. Зарегистрировать в settings.py
# 'apps.tasks.apps.TasksConfig',
# 'apps.projects.apps.ProjectsConfig',

# 7. Настроить URL в agile_projects/urls.py
# path('api/v1/', include('apps.routers')),

Проверка в VS Code и Postman

VS Code: запуск сервера

# Терминал VS Code (Ctrl+`)
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver

Сервер доступен на http://127.0.0.1:8000/. DRF Browsable API: http://127.0.0.1:8000/api/v1/

VS Code: launch.json для отладки

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Django",
      "type": "debugpy",
      "request": "launch",
      "program": "${workspaceFolder}/manage.py",
      "args": ["runserver"],
      "django": true
    }
  ]
}

Postman: примеры запросов

Запрос URL Тело / Параметры
GET список задач /api/v1/tasks/tasks/
GET с фильтром /api/v1/tasks/tasks/?status=NEW query param: status=NEW
POST создать задачу /api/v1/tasks/tasks/ JSON: name, description, project
DELETE «мягкое» /api/v1/tasks/tasks/1/ Устанавливает deleted_at
POST загрузить файл /api/v1/projects/files/ form-data: file_name, project_id, file

Связь с теорией