from dmr.controller import Controller
from dmr.components import Body, File, UploadedFile
from django.contrib.auth.models import AbstractBaseUser
from .schemas import UserProfileResponseSchema, UserProfileUpdateRequestSchema
from .services import UserService
class MeController(Controller):
"""Контроллер управления личным профилем пользователя (/api/v1/users/me)."""
async def get(self, user: CurrentUser) -> UserProfileResponseSchema:
"""Получение профиля текущего пользователя."""
return UserProfileResponseSchema(
id=user.id,
email=user.email,
first_name=user.first_name,
last_name=user.last_name,
role=user.role,
avatar=user.avatar.url if user.avatar else None,
is_active=user.is_active,
date_joined=user.date_joined
)
async def patch(
self,
user: CurrentUser,
body: Body[UserProfileUpdateRequestSchema]
) -> UserProfileResponseSchema:
"""Частичное обновление текстовых данных профиля."""
# Защита extra="forbid" отработала на уровне Body компонента
clean_data = body.value.model_dump(exclude_unset=True)
updated_user = await UserService.update_profile(user, clean_data)
return UserProfileResponseSchema(
id=updated_user.id,
email=updated_user.email,
first_name=updated_user.first_name,
last_name=updated_user.last_name,
role=updated_user.role,
avatar=updated_user.avatar.url if updated_user.avatar else None,
is_active=updated_user.is_active,
date_joined=updated_user.date_joined
)
class AvatarUploadController(Controller):
"""Изолированный контроллер для загрузки бинарных медиа-данных."""
async def post(
self,
user: CurrentUser,
# Компонент File берет файл из multipart/form-data
avatar: File[UploadedFile, "avatar"]
) -> dict:
"""Загрузка аватара напрямую в объектное хранилище."""
avatar_url = await UserService.upload_avatar(user, avatar.value)
return {"avatar": avatar_url}