🏠 Закрепляющая практика

Информация: Это закрепляющее задание составлено по материалу урока 35. Оно не является LMS-домашним заданием — это дополнительная практика для самостоятельного закрепления навыков после урока.

⚡ Задания кратко

  1. Добавить эндпоинт GET /api/v1/users/<pk>/ — детальная информация о пользователе
  2. Добавить soft-delete для пользователей: вместо физического удаления устанавливать deleted=True, deleted_at=now()
  3. Добавить фильтрацию задач по assignee через query param ?assignee=email
  4. Написать эндпоинт PATCH /api/v1/users/<pk>/ для частичного обновления пользователя

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

# Клонировать или открыть существующий проект
cd agile_project

# Активировать виртуальное окружение
# Windows:
.venv\Scripts\activate
# Linux/macOS:
source .venv/bin/activate

# Убедиться, что зависимости установлены
pip install django djangorestframework

# Запустить сервер
python manage.py runserver

Задание 1 — Детальная информация о пользователе

Добавьте эндпоинт для получения полной информации о конкретном пользователе.

  1. Создайте сериализатор UserDetailSerializer с полями:
    • username, first_name, last_name, email, phone
    • position, is_active, deleted
    • registered (date_joined), last_login
    • project (вложенный сериализатор с именем проекта)
  2. Создайте UserDetailGenericView(RetrieveAPIView) с методом get_object.
  3. Добавьте URL: path('<int:pk>/', UserDetailGenericView.as_view())
  4. Проверьте в Postman: GET /api/v1/users/1/

Задание 2 — Soft-delete для пользователей

Вместо физического удаления пользователей устанавливать флаг deleted=True.

  1. Создайте UserDeleteGenericView(DestroyAPIView).
  2. Переопределите метод destroy: вместо instance.delete() выполнять:
    from django.utils import timezone
    instance.deleted = True
    instance.deleted_at = timezone.now()
    instance.is_active = False
    instance.save()
  3. Добавьте URL: path('<int:pk>/delete/', UserDeleteGenericView.as_view())
  4. Убедитесь, что мягко удалённые пользователи не возвращаются в UserListGenericView:
    def get_queryset(self):
        return User.objects.filter(deleted=False, ...)

Задание 3 — Фильтрация задач по assignee

В существующем AllTasksListAPIView добавьте возможность фильтрации по email назначенного разработчика.

  1. В get_queryset добавьте обработку параметра ?assignee_email=...:
    assignee_email = self.request.query_params.get('assignee_email')
    if assignee_email:
        queryset = queryset.filter(assignee__email=assignee_email)
  2. Протестируйте: GET /api/v1/tasks/?assignee_email=dev@example.com

Задание 4 — Частичное обновление пользователя

  1. Создайте сериализатор UpdateUserSerializer с полями: phone, position, first_name, last_name.
  2. Создайте UserUpdateGenericView(UpdateAPIView) с partial=True.
  3. Добавьте URL: path('<int:pk>/', UserUpdateGenericView.as_view())
  4. Протестируйте в Postman: PATCH /api/v1/users/1/ с телом {"phone": "+7999000111"}

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

VS Code — запуск через F5

Создайте/обновите .vscode/launch.json:

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

Нажмите F5 — откроется сервер с точками останова.

Postman — коллекция запросов

# Получить список пользователей
GET http://localhost:8000/api/v1/users/

# Получить пользователей проекта
GET http://localhost:8000/api/v1/users/?project_name=Alpha

# Зарегистрировать нового пользователя
POST http://localhost:8000/api/v1/users/register/
Content-Type: application/json

{
  "username": "john_doe",
  "first_name": "John",
  "last_name": "Doe",
  "email": "john@example.com",
  "position": "PROGRAMMER",
  "password": "SecurePass123!",
  "re_password": "SecurePass123!"
}

# Скачать файл
GET http://localhost:8000/api/v1/projects/files/download/1/

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