feat: add filtering books by author or title
This commit is contained in:
parent
d2e18dd528
commit
ed72288eb1
@ -1,32 +1,34 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from fastapi import APIRouter, Depends, Query, status
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import List, Optional, Union
|
||||
from uuid import UUID
|
||||
from typing import List, Optional
|
||||
|
||||
from core.database import get_db
|
||||
from helpers.book_helpers import get_all_books, get_book_by_id
|
||||
from helpers.book_helpers import get_all_books, get_books_by_author, get_books_by_title
|
||||
from schemas.book import BookSchema
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@router.get("/books", response_model=Union[List[BookSchema], BookSchema])
|
||||
@router.get("/books", response_model=List[BookSchema], status_code=status.HTTP_200_OK)
|
||||
async def get_books(
|
||||
book_id: Optional[UUID] = Query(None, description="ID of the book to retrieve"),
|
||||
skip: int = Query(0, description="Number of records to skip"),
|
||||
author: Optional[str] = Query(None, description="Filter books by author name"),
|
||||
title: Optional[str] = Query(None, description="Filter books by title or partial title match"),
|
||||
skip: int = Query(0, description="Number of records to skip for pagination"),
|
||||
limit: int = Query(100, description="Maximum number of records to return"),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
Get books with optional filtering by ID.
|
||||
Get all books with optional filtering by author or title.
|
||||
|
||||
If book_id is provided, returns a single book.
|
||||
Otherwise, returns a list of books with pagination.
|
||||
- If author is provided, returns all books by that author
|
||||
- If title is provided, returns all books with matching title (partial match)
|
||||
- If both are provided, returns books matching both criteria
|
||||
- If neither is provided, returns all books
|
||||
"""
|
||||
if book_id:
|
||||
book = get_book_by_id(db, book_id)
|
||||
if not book:
|
||||
raise HTTPException(status_code=404, detail="Book not found")
|
||||
return book
|
||||
|
||||
books = get_all_books(db, skip=skip, limit=limit)
|
||||
if author and not title:
|
||||
books = get_books_by_author(db, author=author, skip=skip, limit=limit)
|
||||
elif title and not author:
|
||||
books = get_books_by_title(db, title=title, skip=skip, limit=limit)
|
||||
else:
|
||||
books = get_all_books(db, author=author, title=title, skip=skip, limit=limit)
|
||||
|
||||
return books
|
@ -108,16 +108,26 @@ def get_books_by_title(db: Session, title: str, skip: int = 0, limit: int = 100)
|
||||
"""
|
||||
return db.query(Book).filter(Book.title.ilike(f"%{title}%")).offset(skip).limit(limit).all()
|
||||
|
||||
def get_all_books(db: Session, skip: int = 0, limit: int = 100) -> List[Book]:
|
||||
def get_all_books(db: Session, author: Optional[str] = None, title: Optional[str] = None, skip: int = 0, limit: int = 100) -> List[Book]:
|
||||
"""
|
||||
Retrieves all books with pagination.
|
||||
Retrieves all books with optional filtering by author or title and pagination.
|
||||
|
||||
Args:
|
||||
db (Session): The database session.
|
||||
author (Optional[str], optional): The author name to filter by. Defaults to None.
|
||||
title (Optional[str], optional): The title or partial title to search for. Defaults to None.
|
||||
skip (int, optional): Number of records to skip for pagination. Defaults to 0.
|
||||
limit (int, optional): Maximum number of records to return. Defaults to 100.
|
||||
|
||||
Returns:
|
||||
List[Book]: A list of book objects.
|
||||
List[Book]: A list of book objects matching the filters.
|
||||
"""
|
||||
return db.query(Book).offset(skip).limit(limit).all()
|
||||
query = db.query(Book)
|
||||
|
||||
if author:
|
||||
query = query.filter(Book.author == author)
|
||||
|
||||
if title:
|
||||
query = query.filter(Book.title.ilike(f"%{title}%"))
|
||||
|
||||
return query.offset(skip).limit(limit).all()
|
Loading…
x
Reference in New Issue
Block a user