📝 Задания мини-проекта Agile Projects ч.2
⚡ Все задачи — кратко
- Задание 1: ProjectDetailSerializer (name, description, count_of_files), ProjectDetailAPIView (GET/PUT partial=True/DELETE), URL /api/v1/projects/<pk>/, коммит
- Задание 2: AllTasksSerializer (SlugRelatedField: project.name, assignee.email), CreateTaskSerializer с валидаторами (name ≥ 10, description ≥ 50, priority choices, project по имени, tags, deadline), TasksListAPIView (пагинация 5, фильтр по project_name/assignee_email), POST, URL /api/v1/tasks/, коммит
- Задание 3: TaskDetailSerializer (вложенный ProjectShortInfoSerializer, исключить updated_at/deleted_at), CreateUpdateTaskSerializer.update(), TaskDetailAPIView (GET/PUT partial/DELETE), URL /api/v1/tasks/<pk>/, коммит
- Задание 4: utils/upload_file_helpers.py (4 функции), AllProjectFilesSerializer, CreateProjectFileSerializer (валидация ASCII + расширения, create с chunked save), ProjectFileListGenericView (GET + POST), URL /api/v1/projects/files/, коммит
- Задание 5: ProjectFileDetailSerializer (вложенный ProjectShortInfoSerializer), ProjectFileDetailGenericView (GET/DELETE + физическое удаление файла), URL /api/v1/projects/files/<pk>/, коммит
- Задание 6: python manage.py startapp users, модель User (AbstractBaseUser, 13 полей, USERNAME_FIELD=email), AUTH_USER_MODEL в settings.py, пересоздать БД, миграции, createsuperuser
Контекст: Продолжаешь разработку REST API-платформы «Agile Projects» (начата в уроке 28). К этому моменту реализованы модели Tag, Project, ProjectFile, Task и базовый CRUD тегов. Теперь реализуем CRUD для проектов, API задач с пагинацией, загрузку файлов и кастомного пользователя.
Задание 1 — Получение, обновление и удаление проекта
- Создайте новый сериализатор
ProjectDetailSerializerдля получения конкретной информации по проекту:namedescriptioncreated_atcount_of_files
- Напишите новый класс-отображение
ProjectDetailAPIViewдля получения конкретного проекта, обновления и удаления проекта. - При обновлении полученного проекта добавьте возможность частичного обновления полей.
- Зарегистрируйте новый эндпоинт, проверьте как отрабатывают запросы GET, PUT, DELETE.
- Зафиксируйте все изменения, сделайте запрос на слияние.
Файлы для изменений:
apps/projects/serializers/project_serializers.py,
apps/projects/views/project_views.py,
apps/projects/urls.py
Задание 2 — Задачи для проекта, сотрудник с пагинацией, создание задачи
- В приложении
tasks, в модулеserializersсоздайте новый файлtasks_serializers.py. - Реализуйте сериализатор
AllTasksSerializerдля отображения краткой информации о задачах. Поля для отображения:namestatuspriorityproject(название проекта)assignee(email сотрудника)deadline
- Реализуйте сериализатор
CreateTaskSerializerдля создания новой задачи. Поля для создания новой задачи:namedescriptionpriorityproject(заполняется не по id, а по имени проекта)tagsdeadline
- Добавьте в сериализатор на создание новой задачи валидаторы полей:
name(минимальная длина)description(минимальная длина)priority(передаётся строго число, переданное число должно быть в доступных choices, от 1 до 5)project(передаётся имя проекта, поиск среди всех проектов. Если такого имени нет — выводить сообщение об ошибке, что проекта не существует)tags(список имён тегов, поиск среди всех тегов. Если тега по имени найдено не было — выводить сообщение об ошибке)deadline(не может быть в прошлом)
- Переопределите метод
createдля добавления информации тегов в промежуточную таблицу. - Напишите класс-отображение
AllTasksListAPIViewдля получения списка всех задач, привязанных к конкретному проекту, или сотруднику на выбор. Реализуйте пагинацию для отображения только первых пяти записей на одной странице. Добавьте методpostдля создания задачи. - Зарегистрируйте новый эндпоинт, проверьте как отрабатывают запросы GET, POST.
- Зафиксируйте все изменения, сделайте запрос на слияние.
Файлы для изменений:
apps/tasks/serializers/task_serializers.py,
apps/tasks/views/task_views.py,
apps/tasks/urls.py
Задание 3 — Получение, обновление и удаление задачи
- Напишите новый сериализатор
TaskDetailSerializer:- Сериализатор должен принимать все поля, кроме
updated_at,deleted_at - Более подробное отображение информации о проекте (вложенный сериализатор
ProjectShortInfoSerializer)
- Сериализатор должен принимать все поля, кроме
- В уже написанном сериализаторе
CreateTaskSerializerпоменяйте название наCreateUpdateTaskSerializer, добавьте методupdateна обновление существующей задачи. - Создайте классовое отображение
TaskDetailAPIViewдля получения полной информации о конкретной задаче по её ID, возможности полного, или частичного обновления задачи и удаления задачи. - Зарегистрируйте новый эндпоинт, проверьте как отрабатывают запросы GET, PUT, DELETE.
- Зафиксируйте все изменения, сделайте запрос на слияние.
Файлы для изменений:
apps/tasks/serializers/task_serializers.py,
apps/projects/serializers/project_serializers.py,
apps/tasks/views/task_views.py,
apps/tasks/urls.py
Задание 4 — Работа с файлами (загрузка)
- В приложении
projectsсоздайте новый модульutils. - Создайте в этом модуле файл
upload_file_helpers.py. - В этом файле необходимо создать функции:
- Функция на проверку валидных расширений файла
- Функция на проверку размерности файла (файл не должен быть больше 2 MB)
- Функция на создание пути для сохранения файла
- Функция на сохранение файла (файл должен записываться по частям для избежания потенциальных ошибок и потери данных)
- В модуле
serializersв приложенииprojectsсоздайте новый файлproject_file_serializers.py. - Создайте сериализатор
AllProjectFilesSerializerдля отображения краткой информации по всем файлам:idfile_nameproject
- Создайте сериализатор
CreateProjectFileSerializerдля создания нового файла:- Для создания необходимо только поле
file_name - Поле
file_nameнеобходимо валидировать:- Проверка на наличие символов из таблицы ASCII
- Проверка на доступные расширения файлов (pdf, csv, doc, xlsx)
- Для создания необходимо только поле
- Переопределите метод
create:- Перед сохранением файла необходимо создать путь для сохранения
- Необходимо получить из тела запроса сам файл и проверить его на размерность (не более 2 MB)
- Если файл проходит все проверки — сохранить его в проекте, сохранить объект файла
- Если файл слишком большой — поднять исключение валидации с сообщением об ошибке
- Напишите класс-отображение
ProjectFileListGenericViewдля получения списка всех файлов:- Реализовать метод на получение всех файлов для конкретного проекта по имени проекта. Если имя проекта не было передано — выводить список полностью всех файлов
- Добавьте в класс-отображение
ProjectFileListGenericViewметодpostдля создания нового файла и привязки его к конкретному проекту (проект получать через полеid, которое будет передаваться в теле запроса). - Зарегистрируйте новый эндпоинт, проверьте как отрабатывают запросы GET, POST.
- Зафиксируйте все изменения, сделайте запрос на слияние.
Файлы для создания:
apps/projects/utils/__init__.py,
apps/projects/utils/upload_file_helpers.py,
apps/projects/serializers/project_file_serializers.py,
apps/projects/views/project_file_views.py
Задание 5 — Получение файла, возможность его удаления
- Создайте сериализатор
ProjectFileDetailSerializerдля получения подробной информации о файле:namecreated_atproject(вложенный сериализатор для отображения названия проекта)
- Напишите классовое отображение
ProjectFileDetailGenericViewдля получения информации о конкретном файле и проекте, к которому он привязан, а также возможности удаления этого файла, как из базы данных, так и из проекта (физическое удаление). - Зарегистрируйте новый эндпоинт, проверьте как отрабатывают запросы GET, DELETE.
- Зафиксируйте все изменения, сделайте запрос на слияние.
Файлы для изменений:
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
Задание 6 — Создание кастомного пользователя
- Удалите существующую базу.
- Создайте новое приложение
users, зарегистрируйте его в проекте. - Создайте свою собственную модель
User, в которой будут поля:username— строковое поле, не более 50 символов, уникальное, обязательно к заполнениюfirst_name— строковое поле, не более 40 символов, обязательно к заполнениюlast_name— строковое поле, не более 40 символов, обязательно к заполнениюemail— поле email, уникальное, обязательное к заполнениюphone— строковое поле, не более 75 символов, не обязательно к заполнениюis_staff— административное логическое поле, по умолчанию Falseis_active— логическое поле, по умолчанию Truedate_joined— поле даты и времени, заполняется автоматически при созданииlast_login— поле даты и времени, заполняется при входе в системуupdated_at— поле даты и времени, заполняется автоматически при всех обновленияхdeleted_at— поле даты и времени, заполняется только если полеdeletedпереходит в состояние Truedeleted— логическое поле, по умолчанию Falseproject— связь с моделью Project. При удалении проекта все сотрудники также удаляются, связующее поле у проекта —users, при создании пользователя проекта у него может и не бытьposition— строковое поле выбора из готовых вариантов: Ceo, Cto, Designer, Programmer, Product_owner, Project_owner, Project_manager, Qa
- Укажите поле
email, как поле для входа в систему. - Добавьте дополнительные поля для регистрации:
username,last_name,first_name. - Перепишите настройки django на работу с пользователем в файле
settings.py. - Переопределите связь с новым пользователем в других моделях, где была связь с пользователем (модель Task).
- Проведите миграции и убедитесь, что всё работает.
Файлы для создания/изменений:
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 (поменять ForeignKey на settings.AUTH_USER_MODEL)