Add priority feature for todos

- Add priority field to Todo model
- Update Pydantic schemas with priority field
- Create Alembic migration for priority column
- Add filter by priority to GET /todos endpoint
- Update README with new feature details

generated with BackendIM... (backend.im)
This commit is contained in:
Automated Action 2025-05-13 06:28:44 +00:00
parent 10ef945a25
commit 5f63459832
5 changed files with 52 additions and 7 deletions

View File

@ -7,6 +7,8 @@ A simple Todo API application built with FastAPI and SQLite.
- RESTful API for managing todo items - RESTful API for managing todo items
- SQLite database with SQLAlchemy ORM - SQLite database with SQLAlchemy ORM
- Alembic migrations for database versioning - Alembic migrations for database versioning
- Priority levels for todo items (Low, Medium, High)
- Filter todos by priority
- Health check endpoint - Health check endpoint
- Swagger UI documentation - Swagger UI documentation
@ -65,9 +67,10 @@ API Documentation is available at:
### Todo Operations ### Todo Operations
- `GET /todos` - List all todos - `GET /todos` - List all todos
- `POST /todos` - Create a new todo - Optional query parameter: `priority` (1=Low, 2=Medium, 3=High) to filter by priority
- `POST /todos` - Create a new todo (with optional priority field: 1=Low, 2=Medium, 3=High)
- `GET /todos/{todo_id}` - Get a specific todo - `GET /todos/{todo_id}` - Get a specific todo
- `PUT /todos/{todo_id}` - Update a todo - `PUT /todos/{todo_id}` - Update a todo (including priority)
- `DELETE /todos/{todo_id}` - Delete a todo - `DELETE /todos/{todo_id}` - Delete a todo
## Database ## Database

View File

@ -1,6 +1,6 @@
from fastapi import APIRouter, Depends, HTTPException, status from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from typing import List from typing import List, Optional
from app.db.database import get_db from app.db.database import get_db
from app.models.todo import Todo as TodoModel from app.models.todo import Todo as TodoModel
@ -20,8 +20,18 @@ def create_todo(todo: TodoCreate, db: Session = Depends(get_db)):
return db_todo return db_todo
@router.get("/", response_model=List[Todo]) @router.get("/", response_model=List[Todo])
def read_todos(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)): def read_todos(
todos = db.query(TodoModel).offset(skip).limit(limit).all() skip: int = 0,
limit: int = 100,
priority: Optional[int] = Query(None, ge=1, le=3, description="Filter by priority (1=Low, 2=Medium, 3=High)"),
db: Session = Depends(get_db)
):
query = db.query(TodoModel)
if priority is not None:
query = query.filter(TodoModel.priority == priority)
todos = query.offset(skip).limit(limit).all()
return todos return todos
@router.get("/{todo_id}", response_model=Todo) @router.get("/{todo_id}", response_model=Todo)

View File

@ -9,5 +9,6 @@ class Todo(Base):
title = Column(String, index=True) title = Column(String, index=True)
description = Column(String) description = Column(String)
completed = Column(Boolean, default=False) completed = Column(Boolean, default=False)
priority = Column(Integer, default=1, index=True) # 1: Low, 2: Medium, 3: High
created_at = Column(DateTime, default=func.now()) created_at = Column(DateTime, default=func.now())
updated_at = Column(DateTime, default=func.now(), onupdate=func.now()) updated_at = Column(DateTime, default=func.now(), onupdate=func.now())

View File

@ -1,4 +1,4 @@
from pydantic import BaseModel from pydantic import BaseModel, Field
from datetime import datetime from datetime import datetime
from typing import Optional from typing import Optional
@ -6,6 +6,7 @@ class TodoBase(BaseModel):
title: str title: str
description: Optional[str] = None description: Optional[str] = None
completed: Optional[bool] = False completed: Optional[bool] = False
priority: Optional[int] = Field(default=1, ge=1, le=3, description="Priority level: 1=Low, 2=Medium, 3=High")
class TodoCreate(TodoBase): class TodoCreate(TodoBase):
pass pass
@ -14,6 +15,7 @@ class TodoUpdate(BaseModel):
title: Optional[str] = None title: Optional[str] = None
description: Optional[str] = None description: Optional[str] = None
completed: Optional[bool] = None completed: Optional[bool] = None
priority: Optional[int] = Field(default=None, ge=1, le=3, description="Priority level: 1=Low, 2=Medium, 3=High")
class Todo(TodoBase): class Todo(TodoBase):
id: int id: int

View File

@ -0,0 +1,29 @@
"""add_priority_field
Revision ID: 002
Revises: 001
Create Date: 2025-05-13
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '002'
down_revision = '001'
branch_labels = None
depends_on = None
def upgrade() -> None:
op.add_column('todos', sa.Column('priority', sa.Integer(), nullable=True, server_default='1'))
op.create_index(op.f('ix_todos_priority'), 'todos', ['priority'], unique=False)
# Set default value for existing rows
op.execute("UPDATE todos SET priority = 1 WHERE priority IS NULL")
def downgrade() -> None:
op.drop_index(op.f('ix_todos_priority'), table_name='todos')
op.drop_column('todos', 'priority')