63 lines
No EOL
1.8 KiB
Python
63 lines
No EOL
1.8 KiB
Python
from fastapi import APIRouter, Depends, HTTPException
|
|
from sqlalchemy.orm import Session, joinedload
|
|
from uuid import UUID
|
|
from database import get_db
|
|
import models
|
|
from schemas import ItemCreate, ItemOut
|
|
|
|
router = APIRouter(prefix="/items", tags=["items"])
|
|
|
|
@router.get("/", response_model=list[ItemOut])
|
|
def list_items(db: Session = Depends(get_db)):
|
|
items = (
|
|
db.query(models.Item)
|
|
.options(joinedload(models.Item.tags).joinedload(models.ItemTag.tag))
|
|
.all()
|
|
)
|
|
# pydantic can handle relationships if orm_mode
|
|
return [
|
|
models.Item(
|
|
id=it.id,
|
|
user_id=it.user_id,
|
|
name=it.name,
|
|
tags=it.tags,
|
|
) for it in items
|
|
]
|
|
|
|
@router.post("/", response_model=ItemOut)
|
|
def create_item(payload: ItemCreate, db: Session = Depends(get_db)):
|
|
user = db.query(models.User).first()
|
|
if not user:
|
|
from uuid import uuid4
|
|
user = models.User(id=uuid4(), name="Demo")
|
|
db.add(user)
|
|
db.flush()
|
|
|
|
item = models.Item(user_id=user.id, name=payload.name)
|
|
|
|
if payload.tag_ids:
|
|
links = []
|
|
tags = db.query(models.Tag).filter(models.Tag.id.in_(payload.tag_ids), models.Tag.user_id == user.id).all()
|
|
for t in tags:
|
|
links.append(models.ItemTag(item=item, tag=t))
|
|
item.tags = links
|
|
|
|
db.add(item)
|
|
db.commit()
|
|
db.refresh(item)
|
|
|
|
# eager load for response
|
|
item = (
|
|
db.query(models.Item)
|
|
.options(joinedload(models.Item.tags).joinedload(models.ItemTag.tag))
|
|
.get(item.id)
|
|
)
|
|
return item
|
|
|
|
@router.delete("/{item_id}", status_code=204)
|
|
def delete_item(item_id: UUID, db: Session = Depends(get_db)):
|
|
item = db.get(models.Item, item_id)
|
|
if not item:
|
|
raise HTTPException(status_code=404, detail="Item not found")
|
|
db.delete(item)
|
|
db.commit() |