2025-06-12 15:59:22 +00:00

86 lines
3.3 KiB
Python

from datetime import datetime
from typing import TYPE_CHECKING, Optional
from pydantic import BaseModel, Field, validator
# Use forward references for type annotations
from app.schemas.genre import Genre
# Import types for type checking only
if TYPE_CHECKING:
from app.schemas.author import Author
from app.schemas.publisher import Publisher
# Shared properties
class MangaBase(BaseModel):
title: str = Field(..., min_length=1, max_length=255, description="Title of the manga")
original_title: str | None = Field(
None, max_length=255, description="Original title in Japanese or other language"
)
isbn: str | None = Field(None, max_length=20, description="ISBN of the manga volume")
description: str | None = Field(None, description="Description of the manga")
volume_number: int | None = Field(None, ge=1, description="Volume number in the series")
total_volumes: int | None = Field(
None, ge=1, description="Total number of volumes in the series"
)
publication_date: datetime | None = Field(None, description="Publication date of the manga")
page_count: int | None = Field(None, ge=1, description="Number of pages")
price: float | None = Field(None, ge=0, description="Price of the manga")
quantity: int = Field(0, ge=0, description="Quantity in inventory")
in_stock: bool = Field(True, description="Whether the manga is in stock")
rating: float | None = Field(None, ge=0, le=10, description="Rating of the manga (0-10)")
language: str | None = Field(None, max_length=50, description="Language of the manga")
cover_image_url: str | None = Field(None, max_length=255, description="URL to the cover image")
@validator("total_volumes")
def validate_total_volumes(self, v, values):
if v is not None and "volume_number" in values and values["volume_number"] is not None:
if v < values["volume_number"]:
raise ValueError("Total volumes must be greater than or equal to volume number")
return v
# Properties to receive on manga creation
class MangaCreate(MangaBase):
author_id: int | None = Field(None, description="ID of the author")
publisher_id: int | None = Field(None, description="ID of the publisher")
genre_ids: list[int] | None = Field(None, description="IDs of the genres")
# Properties to receive on manga update
class MangaUpdate(MangaBase):
title: str | None = Field(None, min_length=1, max_length=255, description="Title of the manga")
author_id: int | None = Field(None, description="ID of the author")
publisher_id: int | None = Field(None, description="ID of the publisher")
genre_ids: list[int] | None = Field(None, description="IDs of the genres")
# Properties shared by models stored in DB
class MangaInDBBase(MangaBase):
id: int
author_id: int | None
publisher_id: int | None
created_at: datetime
updated_at: datetime
class Config:
orm_mode = True
# Properties to return to client
class Manga(MangaInDBBase):
pass
# Properties properties stored in DB
class MangaInDB(MangaInDBBase):
pass
# Additional properties for response with relationships
class MangaWithRelations(Manga):
author: Optional["Author"] = None
publisher: Optional["Publisher"] = None
genres: list[Genre] = []