Add advanced filtering, sorting, and pagination to Todo list endpoint
This commit is contained in:
parent
25fd3c49f2
commit
38273684c4
13
README.md
13
README.md
@ -5,6 +5,7 @@ A deadass simple Todo API built with FastAPI and SQLite. This project provides a
|
||||
## Features
|
||||
|
||||
- RESTful API endpoints for Todo resource (Create, Read, Update, Delete)
|
||||
- Advanced filtering, sorting, and pagination capabilities
|
||||
- SQLite database with SQLAlchemy ORM
|
||||
- Database migrations with Alembic
|
||||
- Health check endpoint
|
||||
@ -66,7 +67,17 @@ The API will be available at http://localhost:8000
|
||||
- `GET /health` - Check API and database health
|
||||
|
||||
### Todo Management
|
||||
- `GET /api/v1/todos` - Get all todos (with optional pagination and filtering)
|
||||
- `GET /api/v1/todos` - Get all todos (with advanced filtering, sorting, and pagination)
|
||||
- Filtering options:
|
||||
- `completed`: Filter by completion status (true/false)
|
||||
- `created_after`: Filter todos created on or after date (YYYY-MM-DD)
|
||||
- `created_before`: Filter todos created on or before date (YYYY-MM-DD)
|
||||
- Sorting options:
|
||||
- `sort_by`: Field to sort by (id, title, created_at, updated_at)
|
||||
- `sort_order`: Sort direction (asc, desc)
|
||||
- Pagination:
|
||||
- `skip`: Number of items to skip
|
||||
- `limit`: Maximum number of items to return
|
||||
- `GET /api/v1/todos/{todo_id}` - Get a specific todo by ID
|
||||
- `POST /api/v1/todos` - Create a new todo
|
||||
- `PUT /api/v1/todos/{todo_id}` - Update an existing todo
|
||||
|
@ -1,6 +1,8 @@
|
||||
from typing import List, Optional
|
||||
from datetime import datetime, date
|
||||
from fastapi import APIRouter, Depends, HTTPException, status, Response, Query
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy import desc, asc
|
||||
|
||||
from app.db.database import get_db
|
||||
from app.models.todo import Todo as TodoModel
|
||||
@ -31,23 +33,58 @@ def read_todos(
|
||||
skip: int = 0,
|
||||
limit: int = 100,
|
||||
completed: Optional[bool] = Query(None, description="Filter by completion status"),
|
||||
created_after: Optional[date] = Query(None, description="Filter todos created after this date (YYYY-MM-DD)"),
|
||||
created_before: Optional[date] = Query(None, description="Filter todos created before this date (YYYY-MM-DD)"),
|
||||
sort_by: str = Query("id", description="Field to sort by (id, title, created_at, updated_at)"),
|
||||
sort_order: str = Query("asc", description="Sort order (asc or desc)"),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
Get all todo items with optional filtering.
|
||||
Get all todo items with optional filtering, sorting, and pagination.
|
||||
|
||||
- **skip**: Number of items to skip (pagination)
|
||||
- **limit**: Maximum number of items to return
|
||||
- **completed**: Optional filter by completion status
|
||||
- **limit**: Maximum number of items to return (pagination)
|
||||
- **completed**: Optional filter by completion status (true/false)
|
||||
- **created_after**: Filter todos created on or after this date (format: YYYY-MM-DD)
|
||||
- **created_before**: Filter todos created on or before this date (format: YYYY-MM-DD)
|
||||
- **sort_by**: Field to sort by (options: id, title, created_at, updated_at)
|
||||
- **sort_order**: Sort order (options: asc, desc)
|
||||
|
||||
Returns a list of todo items.
|
||||
"""
|
||||
query = db.query(TodoModel)
|
||||
|
||||
# Apply filter if completed parameter is provided
|
||||
# Apply filters
|
||||
if completed is not None:
|
||||
query = query.filter(TodoModel.completed == completed)
|
||||
|
||||
if created_after:
|
||||
# Convert date to datetime with time at start of day (00:00:00)
|
||||
start_datetime = datetime.combine(created_after, datetime.min.time())
|
||||
query = query.filter(TodoModel.created_at >= start_datetime)
|
||||
|
||||
if created_before:
|
||||
# Convert date to datetime with time at end of day (23:59:59)
|
||||
end_datetime = datetime.combine(created_before, datetime.max.time())
|
||||
query = query.filter(TodoModel.created_at <= end_datetime)
|
||||
|
||||
# Apply sorting
|
||||
if sort_by not in ["id", "title", "created_at", "updated_at"]:
|
||||
sort_by = "id" # Default to id if invalid field provided
|
||||
|
||||
if sort_order.lower() not in ["asc", "desc"]:
|
||||
sort_order = "asc" # Default to ascending if invalid order provided
|
||||
|
||||
# Get the attribute to sort by
|
||||
sort_attr = getattr(TodoModel, sort_by)
|
||||
|
||||
# Apply sorting direction
|
||||
if sort_order.lower() == "desc":
|
||||
query = query.order_by(desc(sort_attr))
|
||||
else:
|
||||
query = query.order_by(asc(sort_attr))
|
||||
|
||||
# Apply pagination
|
||||
todos = query.offset(skip).limit(limit).all()
|
||||
return todos
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user