
- Add advanced search filters (year range, score, studio, source) - Create detailed statistics endpoint for anime collection - Implement enhanced pagination metadata for better navigation - Add sorting options for search results - Enhance anime model with additional fields (season info, ratings, etc.) - Add ability to search anime by character attributes - Create migration for new anime model fields - Update README with detailed documentation of new features
118 lines
2.8 KiB
Python
118 lines
2.8 KiB
Python
from typing import Optional, List, TYPE_CHECKING, ForwardRef
|
|
from datetime import date
|
|
from pydantic import BaseModel, Field
|
|
from app.schemas.genre import Genre
|
|
|
|
if TYPE_CHECKING:
|
|
from app.schemas.character import Character
|
|
else:
|
|
Character = ForwardRef("Character")
|
|
|
|
|
|
class AnimeBase(BaseModel):
|
|
title: str
|
|
alternative_titles: Optional[str] = None
|
|
synopsis: Optional[str] = None
|
|
episodes: Optional[int] = None
|
|
status: Optional[str] = None
|
|
aired_from: Optional[date] = None
|
|
aired_to: Optional[date] = None
|
|
duration: Optional[str] = None
|
|
rating: Optional[str] = None
|
|
score: Optional[float] = Field(None, ge=0, le=10)
|
|
ranked: Optional[int] = None
|
|
popularity: Optional[int] = None
|
|
studio: Optional[str] = None
|
|
source: Optional[str] = None
|
|
image_url: Optional[str] = None
|
|
|
|
# Season information
|
|
season: Optional[str] = None
|
|
season_year: Optional[int] = None
|
|
|
|
# Rating details
|
|
score_count: Optional[int] = None
|
|
favorites_count: Optional[int] = None
|
|
|
|
# Additional metadata
|
|
broadcast_day: Optional[str] = None
|
|
broadcast_time: Optional[str] = None
|
|
is_airing: Optional[bool] = None
|
|
licensors: Optional[str] = None
|
|
producers: Optional[str] = None
|
|
|
|
# Related anime info
|
|
related_anime: Optional[dict] = None
|
|
|
|
# Content tags
|
|
themes: Optional[str] = None
|
|
demographics: Optional[str] = None
|
|
|
|
|
|
class AnimeCreate(AnimeBase):
|
|
genre_ids: Optional[List[int]] = []
|
|
|
|
|
|
class AnimeUpdate(AnimeBase):
|
|
title: Optional[str] = None
|
|
genre_ids: Optional[List[int]] = None
|
|
|
|
|
|
class Anime(AnimeBase):
|
|
id: int
|
|
genres: Optional[List[Genre]] = []
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class AnimeWithCharacters(Anime):
|
|
characters: Optional[List[Character]] = []
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class AnimeSearchResults(BaseModel):
|
|
results: List[Anime]
|
|
total: int
|
|
page: int
|
|
size: int
|
|
pages: Optional[int] = None
|
|
has_next: Optional[bool] = None
|
|
has_prev: Optional[bool] = None
|
|
next_page: Optional[int] = None
|
|
prev_page: Optional[int] = None
|
|
|
|
|
|
class GenreCount(BaseModel):
|
|
id: int
|
|
name: str
|
|
count: int
|
|
|
|
|
|
class DistributionItem(BaseModel):
|
|
name: str
|
|
count: int
|
|
|
|
|
|
class YearDistribution(BaseModel):
|
|
year: int
|
|
count: int
|
|
|
|
|
|
class ScoreDistribution(BaseModel):
|
|
score_range: str
|
|
count: int
|
|
|
|
|
|
class AnimeStatistics(BaseModel):
|
|
total_anime: int
|
|
avg_score: Optional[float] = None
|
|
avg_episodes: Optional[float] = None
|
|
status_distribution: List[DistributionItem]
|
|
source_distribution: List[DistributionItem]
|
|
studio_distribution: List[DistributionItem]
|
|
year_distribution: List[YearDistribution]
|
|
score_distribution: List[ScoreDistribution]
|
|
top_genres: List[GenreCount] |