"""User schemas.""" from typing import Optional from pydantic import BaseModel, Field from utils.util_schemas import BaseResponse class UserBase(BaseModel): """User base schema.""" username: str = Field(..., min_length=3, max_length=50) email: str = Field(..., max_length=100) full_name: Optional[str] = Field(None, max_length=100) bio: Optional[str] = None avatar_url: Optional[str] = None class UserCreate(UserBase): """User creation schema.""" password: str = Field(..., min_length=6) class UserUpdate(BaseModel): """User update schema.""" username: Optional[str] = Field(None, min_length=3, max_length=50) email: Optional[str] = Field(None, max_length=100) full_name: Optional[str] = Field(None, max_length=100) bio: Optional[str] = None avatar_url: Optional[str] = None password: Optional[str] = Field(None, min_length=6) is_active: Optional[bool] = None class ChangePasswordRequest(BaseModel): """Change password request schema.""" current_password: str = Field(..., description="Current password") new_password: str = Field(..., min_length=6, description="New password") class ResetPasswordRequest(BaseModel): """Admin reset password request schema.""" new_password: str = Field(..., min_length=6, description="New password") class UserResponse(BaseResponse, UserBase): """User response schema.""" is_active: bool is_superuser: Optional[bool] = Field(default=False, description="是否为超级管理员") model_config = { 'from_attributes': True } @classmethod def model_validate(cls, obj, *, from_attributes=False): """从对象创建响应模型,正确处理is_superuser方法""" if hasattr(obj, '__dict__'): data = obj.__dict__.copy() # 调用is_superuser方法获取布尔值 if hasattr(obj, 'is_admin'): # 使用同步的 is_admin 属性代替异步的 is_superuser 方法 data['is_superuser'] = obj.is_admin elif hasattr(obj, 'is_superuser') and not callable(obj.is_superuser): # 如果is_superuser是属性而不是方法 data['is_superuser'] = obj.is_superuser return super().model_validate(data) return super().model_validate(obj, from_attributes=from_attributes) class LoginResponse(BaseModel): """登录响应模型,包含令牌和用户信息""" access_token: str token_type: str expires_in: int user: UserResponse