from __future__ import annotations from urllib.parse import quote from pydantic import BaseModel, ConfigDict, field_validator def encode_path(path: str) -> str: if not path: return "" return "/".join(quote(part, safe="") for part in path.split("/")) class PhotoItem(BaseModel): model_config = ConfigDict(from_attributes=True) id: int path: str filename: str category_id: int @field_validator("path", mode="before") @classmethod def encode_urls(cls, v): return encode_path(v) @field_validator("path", mode="after") @classmethod def add_media(cls, v: str) -> str: if not v: return v clean_v = v.lstrip('/') if clean_v.startswith('media/'): return f"{clean_v}" return f"media/{clean_v}" class Category(BaseModel): model_config = ConfigDict(from_attributes=True) id: int title: str photos: list[PhotoItem] = [] class PhotosOut(BaseModel): photos: list[PhotoItem] class CategoryItem(BaseModel): id: int title: str photos_count: int class CategoriesOut(BaseModel): categories: list[CategoryItem] class PhotosPaginatedOut(BaseModel): photos: list[PhotoItem] page_inc: str page_dec: str