Bật from_attributes=True trong model_config của schema.
Pydantic v2 mặc định chỉ đọc dict; với ORM object nó phải được cho phép đọc thuộc tính thay vì khoá dict (v1 gọi là orm_mode).
from pydantic import BaseModel, ConfigDict
class UserOut(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: int
email: str
@app.get("/users/{user_id}", response_model=UserOut)
async def get_user(user_id: int, db: DbSession):
return await db.get(User, user_id) # ORM object, FastAPI validates itCác tuỳ chọn model_config hay dùng kèm:
- populate_by_name=True — cho phép nạp bằng tên field lẫn alias (hữu ích khi API dùng camelCase mà code dùng snake_case, kết hợp alias_generator).
- extra='forbid' — chặn field lạ ở schema đầu vào, tránh client gửi thừa mà bị bỏ qua âm thầm.
- str_strip_whitespace=True — cắt khoảng trắng thừa ở mọi field chuỗi.
Lưu ý về mặt an toàn: schema output nên khai báo danh sách field trắng như trên, đừng trả nguyên model ORM ra ngoài — nếu bảng thêm cột password_hash thì schema tường minh vẫn không lộ.