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:
parent
10ef945a25
commit
5f63459832
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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())
|
@ -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
|
||||||
|
29
migrations/versions/add_priority_field.py
Normal file
29
migrations/versions/add_priority_field.py
Normal 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')
|
Loading…
x
Reference in New Issue
Block a user