Загрузка данных


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}