📝 Задания мини-проекта Agile Projects ч.3

7 задач: файлы (1–2) · кастомный User (3) · список пользователей (4) · регистрация (5) · assignee (6) · скачивание (7)

⚡ Все задачи — кратко

  1. Задание 1: get_serializer_class, get_queryset с фильтром по project_name, метод list с 204 при пустом. URL /api/v1/projects/files/. Коммит + PR.
  2. Задание 2: ProjectFileDetailSerializer (name, created_at, project вложенный), ProjectFileDetailGenericView (GET + физическое DELETE), URL /api/v1/projects/files/<pk>/. Коммит + PR.
  3. Задание 3: startapp users, модель User (14 полей: username, first/last_name, email, phone, is_staff, is_active, date_joined, last_login, updated_at, deleted_at, deleted, project FK, position), USERNAME_FIELD=email, AUTH_USER_MODEL, миграции, createsuperuser. Коммит + PR.
  4. Задание 4: UserListSerializer (6 полей), UserListGenericView с фильтром по project_name, URL /api/v1/users/. Коммит + PR.
  5. Задание 5: RegisterUserSerializer (re_password, regex-validate, validate_password, create с set_password), RegisterUserGenericView, URL /api/v1/users/register/. Коммит + PR.
  6. Задание 6: Добавить assignee = SlugRelatedField(slug_field='email') в CreateUpdateTaskSerializer. Коммит + PR.
  7. Задание 7: DownloadProjectFileView с FileResponse, URL /api/v1/projects/files/download/<pk>/. Коммит + PR.
Контекст: Продолжаешь разработку REST API-платформы «Agile Projects». К этому моменту реализованы модели, базовый CRUD проектов и задач, загрузка файлов (задачи 4–5 из урока 30). Теперь расширяем API файлов, добавляем полноценную систему пользователей и скачивание файлов.

Задание 1 — Получить список всех файлов проекта

  1. Обновите существующее отображение ProjectFileListGenericView, дописав к нему метод get_serializer_class.
  2. Добавьте в этот же класс метод get_queryset(), добавив возможность получения всех файлов проекта с поиском по конкретному проекту (как фильтр использовать имя проекта).
  3. Добавьте в этот же класс метод list() на получение списка всех файлов проекта.
  4. Протестируйте получение файлов проекта методом GET.
  5. Закомментируйте все изменения, сделайте запрос на слияние.
Файлы для изменений: apps/projects/views/project_file_views.py

Задание 2 — Получение файла, возможность его удаления

  1. Создайте сериализатор ProjectFileDetailSerializer для получения подробной информации о файле:
    • name
    • created_at
    • project (вложенный сериализатор для отображения названия проекта)
  2. Напишите классовое отображение ProjectFileDetailGenericView для получения информации о конкретном файле и проекте, к которому он привязан, а также возможности удаления этого файла, как из базы данных, так и из проекта (физическое удаление с диска).
  3. Зарегистрируйте новый эндпоинт, проверьте как отрабатывают запросы GET, DELETE.
  4. Зафиксируйте все изменения, сделайте запрос на слияние.
Файлы для изменений: apps/projects/serializers/project_file_serializers.py, apps/projects/views/project_file_views.py, apps/projects/utils/upload_file_helpers.py, apps/projects/urls.py

Задание 3 — Создание кастомного пользователя. Часть 1 и 2

  1. Удалите существующую базу данных.
  2. Создайте новое приложение users, зарегистрируйте его в проекте.
  3. Создайте свою собственную модель User, в которой будут поля:
    • username — строковое поле, не более 50 символов, уникальное, обязательно к заполнению
    • first_name — строковое поле, не более 40 символов, обязательно к заполнению
    • last_name — строковое поле, не более 40 символов, обязательно к заполнению
    • email — поле email, уникальное, обязательное к заполнению
    • phone — строковое поле, не более 75 символов, не обязательно к заполнению
    • is_staff — административное логическое поле, по умолчанию False
    • is_active — логическое поле, по умолчанию True
    • date_joined — поле даты и времени, заполняется автоматически при создании
    • last_login — поле даты и времени, заполняется при входе в систему
    • updated_at — поле даты и времени, заполняется автоматически при всех обновлениях
    • deleted_at — поле даты и времени, заполняется только если поле deleted переходит в состояние True
    • deleted — логическое поле, по умолчанию False (soft-delete флаг)
    • project — связь с моделью Project. При удалении проекта все сотрудники также удаляются (CASCADE), связующее поле у проекта — users, при создании пользователя проекта у него может и не быть
    • position — строковое поле выбора из готовых вариантов позиций:
      1. Ceo
      2. Cto
      3. Designer
      4. Programmer
      5. Product_owner
      6. Project_owner
      7. Project_manager
      8. Qa
  4. Укажите поле email как поле для входа в систему (USERNAME_FIELD).
  5. Добавьте дополнительные поля для регистрации (REQUIRED_FIELDS):
    • username
    • last_name
    • first_name
  6. Перепишите настройки Django на работу с кастомным пользователем в файле settings.py (AUTH_USER_MODEL).
  7. Переопределите связь с новым пользователем в других моделях, где была связь с пользователем (модель Task).
  8. Проведите миграции и убедитесь, что всё работает. Создайте суперпользователя.
Файлы для создания/изменений: python manage.py startapp users, apps/users/models.py, apps/users/choices/positions.py, settings.py (AUTH_USER_MODEL), apps/tasks/models/task_model.py

Задание 4 — Получение списка пользователей, фильтрация пользователей

  1. Создайте сериализатор UserListSerializer для отображения только лишь некоторых полей для пользователя:
    • first_name
    • last_name
    • position
    • email
    • phone
    • last_login
  2. Создайте классовое отображение UserListGenericView для получения списка пользователей.
    • Переопределите метод get_queryset для получения списка пользователей по конкретному проекту, если фильтр был передан, иначе должен отдаваться список всех пользователей.
  3. Зарегистрируйте новый эндпоинт, протестируйте его, чтобы убедиться, что он работает.
  4. Закомментируйте все изменения, создайте запрос на слияние.
Файлы для создания: apps/users/serializers.py, apps/users/views.py, apps/users/urls.py, apps/router.py (добавить path('users/', ...))

Задание 5 — Регистрация нового пользователя

  1. Создайте новый сериализатор RegisterUserSerializer для регистрации нового пользователя. Сериализатор будет обрабатывать поля:
    • username
    • first_name
    • last_name
    • email
    • position
    • password
    • re_password

    Поле re_password — искусственно созданное поле для проверки совпадения паролей:

    • Максимальная длина — 128 символов
    • Только для записи (write_only=True)

    В параметре extra_kwargs указать, что поле password строго только для записи.

  2. Создайте в этом сериализаторе метод validate. Этот метод должен проверять:
    • username — любые буквы из латиницы, символ нижнего подчёркивания, цифры от 0 до 9
    • first_name — строго буквы из латиницы, любым регистром
    • last_name — строго буквы из латиницы, любым регистром
    • password — пароль и его повторный ввод должны совпадать; также вызов базовых проверок пароля от системы Django (validate_password)
  3. Переопределите метод create для хеширования пароля и его установки для пользователя перед созданием.
  4. Напишите классовое отображение RegisterUserGenericView, которое будет принимать данные из запроса и создавать пользователя.
  5. Зарегистрируйте новый эндпоинт, протестируйте его, чтобы убедиться, что он работает.
  6. Закомментируйте все изменения, создайте запрос на слияние.
Файлы для изменений: apps/users/serializers.py, apps/users/views.py, apps/users/urls.py

Задание 6 — Обновление сериализатора для создания задач

  1. В сериализатор CreateUpdateTaskSerializer добавьте новое поле assignee для возможности указывать назначенного разработчика на определённую задачу при создании/обновлении задачи.
    • Поле заполняется по email пользователя
    • Поле не обязательно к заполнению, его можно пропускать
  2. Запустите сервер и протестируйте добавленные изменения, чтобы убедиться, что создание и обновление задач работает.
  3. Закомментируйте все изменения, создайте запрос на слияние.
Файлы для изменений: apps/tasks/serializers/task_serializers.py

Задание 7 — Скачивание конкретного файла по переданному ID

  1. Напишите отображение для возможности скачивания файла по переданному ID файла. Если файла с таким ID не существует — выдавать сообщение, что файл не найден.
  2. Зарегистрируйте новое отображение, запустите сервер и протестируйте новый функционал по скачиванию файлов.
  3. Закомментируйте все изменения, создайте запрос на слияние.
Файлы для изменений: apps/projects/views/project_file_views.py, apps/projects/urls.py
Посмотреть решения →