Files
d3m0k1d.ru/backend/app/api/v1/posts.py
2025-11-25 16:14:16 +03:00

92 lines
2.5 KiB
Python

from typing import Optional, Sequence
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy import select, delete
from sqlalchemy.ext.asyncio import AsyncSession
from app.schemas.posts import PostCreate, PostRead
from app.db_engine import get_async_session
from app.models.posts import Post
router = APIRouter(
prefix="/posts",
tags=["posts"],
responses={404: {"description": "Not found"}},
)
@router.get("/")
async def get_posts(
page: int = Query(1, ge=1),
page_size: int = Query(10, ge=1, le=100),
db: AsyncSession = Depends(get_async_session),
):
offset = (page - 1) * page_size
stmt = select(Post).order_by(Post.id).offset(offset).limit(page_size)
result = await db.execute(stmt)
posts: Sequence[Post] = result.scalars().all()
return posts
@router.get("/{id}", response_model=PostRead)
async def get_post(id: int, db: AsyncSession = Depends(get_async_session)):
post = await db.get(Post, id)
if post is None:
raise HTTPException(status_code=404, detail="Post not found")
else:
return post
@router.post("/", response_model=PostRead)
async def create_post(
title: str,
content: str,
images: Optional[str] = None,
db: AsyncSession = Depends(get_async_session),
) -> Post:
try:
post = PostCreate(title=title, content=content, images=images)
except ValueError as e:
raise HTTPException(status_code=422, detail=str(e))
new_post = Post(title=post.title, content=post.content, images=post.images)
db.add(new_post)
await db.commit()
await db.refresh(new_post)
return new_post
@router.put("/{id}")
async def update_post(
id: int,
db: AsyncSession = Depends(get_async_session),
title: Optional[str] = None,
content: Optional[str] = None,
images: Optional[str] = None,
):
s = select(Post).where(Post.id == id)
result = await db.execute(s)
post = result.scalars().first()
if post is None:
raise HTTPException(status_code=404, detail="Post not found")
if title is not None:
post.title = title # type: ignore
if content is not None:
post.content = content # type: ignore
if images is not None:
post.images = images # type: ignore
await db.commit()
return post
@router.delete("/{id}")
async def delete_post(id: int, db: AsyncSession = Depends(get_async_session)):
s = delete(Post).where(Post.id == id)
await db.execute(s)
await db.commit()
return {"message": "Post deleted"}