From 83dbb1824eb826794662a46e124c66f9b47aba8f Mon Sep 17 00:00:00 2001 From: wowlikon Date: Tue, 24 Jun 2025 21:47:07 +0300 Subject: [PATCH] Created models for genres --- README.md | 6 +----- library_service/models/db/__init__.py | 11 +++++++++-- library_service/models/db/book.py | 7 ++++++- library_service/models/db/genre.py | 14 ++++++++++++++ library_service/models/db/links.py | 15 +++++++++++++++ library_service/models/dto/__init__.py | 8 ++++++-- library_service/models/dto/genre.py | 25 +++++++++++++++++++++++++ 7 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 library_service/models/db/genre.py create mode 100644 library_service/models/dto/genre.py diff --git a/README.md b/README.md index fd52f90..232065c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ # LibraryAPI -## WARNING: Documentation may be partially out of date at this time. - This project is a test web application built using FastAPI, a modern web framework for creating APIs in Python. It showcases the use of Pydantic for data validation, SQLModel for database interactions, Alembic for migration management, PostgreSQL as the database system, and Docker Compose for easy deployment. ### **Key Components:** @@ -96,6 +94,4 @@ For run tests: ### **TODO List** -- Implement tests -- Geners table -- Check and update documentation +- Geners table and endpoints diff --git a/library_service/models/db/__init__.py b/library_service/models/db/__init__.py index e47964f..dd6849e 100644 --- a/library_service/models/db/__init__.py +++ b/library_service/models/db/__init__.py @@ -1,7 +1,14 @@ from .author import Author from .book import Book -from .links import AuthorBookLink, AuthorWithBooks, BookWithAuthors +from .links import ( + AuthorBookLink, GenreBookLink, + AuthorWithBooks, BookWithAuthors, + GenreWithBooks, BookWithAuthorsAndGenres +) __all__ = [ - 'Author', 'Book', 'AuthorBookLink', 'AuthorWithBooks', 'BookWithAuthors' + 'Author', 'Book', + 'AuthorBookLink', 'AuthorWithBooks', + 'BookWithAuthors', 'GenreBookLink', + 'GenreWithBooks', 'BookWithAuthorsAndGenres' ] diff --git a/library_service/models/db/book.py b/library_service/models/db/book.py index 54f85e2..ead3968 100644 --- a/library_service/models/db/book.py +++ b/library_service/models/db/book.py @@ -1,10 +1,11 @@ from typing import List, Optional, TYPE_CHECKING from sqlmodel import SQLModel, Field, Relationship from ..dto.book import BookBase -from .links import AuthorBookLink +from .links import AuthorBookLink, GenreBookLink if TYPE_CHECKING: from .author import Author + from .genre import Genre class Book(BookBase, table=True): id: Optional[int] = Field(default=None, primary_key=True, index=True) @@ -12,3 +13,7 @@ class Book(BookBase, table=True): back_populates="books", link_model=AuthorBookLink ) + genres: List["Genre"] = Relationship( + back_populates="books", + link_model=GenreBookLink + ) diff --git a/library_service/models/db/genre.py b/library_service/models/db/genre.py new file mode 100644 index 0000000..f114532 --- /dev/null +++ b/library_service/models/db/genre.py @@ -0,0 +1,14 @@ +from typing import List, Optional, TYPE_CHECKING +from sqlmodel import SQLModel, Field, Relationship +from ..dto.genre import GenreBase +from .links import GenreBookLink + +if TYPE_CHECKING: + from .book import Book + +class Genre(GenreBase, table=True): + id: Optional[int] = Field(default=None, primary_key=True, index=True) + books: List["Book"] = Relationship( + back_populates="authors", + link_model=GenreBookLink + ) diff --git a/library_service/models/db/links.py b/library_service/models/db/links.py index cb68a02..2ac7037 100644 --- a/library_service/models/db/links.py +++ b/library_service/models/db/links.py @@ -3,13 +3,28 @@ from typing import List from library_service.models.dto.author import AuthorRead from library_service.models.dto.book import BookRead +from library_service.models.dto.genre import GenreRead class AuthorBookLink(SQLModel, table=True): author_id: int | None = Field(default=None, foreign_key="author.id", primary_key=True) book_id: int | None = Field(default=None, foreign_key="book.id", primary_key=True) +class GenreBookLink(SQLModel, table=True): + genre_id: int | None = Field(default=None, foreign_key="genre.id", primary_key=True) + book_id: int | None = Field(default=None, foreign_key="book.id", primary_key=True) + class AuthorWithBooks(AuthorRead): books: List[BookRead] = Field(default_factory=list) class BookWithAuthors(BookRead): authors: List[AuthorRead] = Field(default_factory=list) + +class BookWithGenres(BookRead): + genres: List[GenreRead] = Field(default_factory=list) + +class GenreWithBooks(GenreRead): + books: List[BookRead] = Field(default_factory=list) + +class BookWithAuthorsAndGenres(BookRead): + authors: List[AuthorRead] = Field(default_factory=list) + genres: List[GenreRead] = Field(default_factory=list) diff --git a/library_service/models/dto/__init__.py b/library_service/models/dto/__init__.py index 4f16be6..ef60ea5 100644 --- a/library_service/models/dto/__init__.py +++ b/library_service/models/dto/__init__.py @@ -6,10 +6,14 @@ from .book import ( BookBase, BookCreate, BookUpdate, BookRead, BookList ) -# from .common import PaginatedResponse + +from .genre import ( + GenreBase, GenreCreate, GenreUpdate, + GenreRead, GenreList +) __all__ = [ 'AuthorBase', 'AuthorCreate', 'AuthorUpdate', 'AuthorRead', 'AuthorList', 'BookBase', 'BookCreate', 'BookUpdate', 'BookRead', 'BookList', - # 'PaginatedResponse' + 'GenreBase', 'GenreCreate', 'GenreUpdate', 'GenreRead', 'GenreList', ] diff --git a/library_service/models/dto/genre.py b/library_service/models/dto/genre.py new file mode 100644 index 0000000..e589cce --- /dev/null +++ b/library_service/models/dto/genre.py @@ -0,0 +1,25 @@ +from sqlmodel import SQLModel +from pydantic import ConfigDict +from typing import Optional, List + +class GenreBase(SQLModel): + name: str + + model_config = ConfigDict( #pyright: ignore + json_schema_extra={ + "example": {"name": "genre_name"} + } + ) + +class GenreCreate(GenreBase): + pass + +class GenreUpdate(SQLModel): + name: Optional[str] = None + +class GenreRead(GenreBase): + id: int + +class GenreList(SQLModel): + genres: List[GenreRead] + total: int