https://github.com/pahkey/fastapi-book/tree/v2.07
GitHub - pahkey/fastapi-book
Contribute to pahkey/fastapi-book development by creating an account on GitHub.
github.com
점프 투 fastapi의 2-07 장 까지 진행했다.

책에는 "content: 빈 값은 허용되지 않습니다."
라고 나오는데 파이썬 버젼의 차이인지 앞에 "Value error," 가 붙어서 나왔다.

# answer_crud.py
from datetime import datetime
from sqlalchemy.orm import Session
from domain.answer.answer_schema import AnswerCreate
from models import Answer, Question
def create_answer(db: Session, question: Question, answer_create: AnswerCreate):
db_answer = Answer(question=question,
content=answer_create.content,
create_date=datetime.now())
db.add(db_answer)
db.commit()
# answer_router.py
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from starlette import status
from database import get_db
from domain.answer import answer_schema, answer_crud
from domain.question import question_crud
router = APIRouter(
prefix="/api/answer",
)
@router.post("/create/{question_id}", status_code=status.HTTP_204_NO_CONTENT)
def answer_create(question_id: int,
_answer_create: answer_schema.AnswerCreate,
db: Session = Depends(get_db)):
# create answer
question = question_crud.get_question(db, question_id=question_id)
if not question:
raise HTTPException(status_code=404, detail="Question not found")
answer_crud.create_answer(db, question=question, answer_create=_answer_create)
# answer_schema.py
import datetime
from pydantic import BaseModel, field_validator
class AnswerCreate(BaseModel):
content: str
@field_validator('content')
def not_empty(cls, v):
if not v or not v.strip():
raise ValueError('빈 값은 허용되지 않습니다.')
return v
class Answer(BaseModel):
id: int
content: str
create_date: datetime.datetime
<script>
// Error.svelte
export let error // 전달받은 오류
</script>
{#if typeof error.detail === 'string'}
<ul>
<li>{error.detail}</li>
</ul>
{:else if typeof error.detail === 'object' && error.detail.length > 0}
<ul>
{#each error.detail as err, i}
<li>
<strong>{err.loc[1]}</strong> : {err.msg}
</li>
{/each}
</ul>
{/if}
<script>
// Detail.svelte
import fastapi from "../lib/api"
import Error from "../components/Error.svelte"
export let params = {}
let question_id = params.question_id
let question = {answers:[]}
let content = ""
let error = {detail:[]}
function get_question() {
fastapi("get", "/api/question/detail/" + question_id, {}, (json) => {
question = json
})
}
get_question()
function post_answer(event) {
event.preventDefault()
let url = "/api/answer/create/" + question_id
let params = {
content: content,
}
fastapi("post", url, params, (json) => {
content = ""
error = {detail:[]}
get_question()
}, (err_json) => {
error = err_json
})
}
</script>
<h1>{question.subject}</h1>
<div>
{question.content}
</div>
<ul>
{#each question.answers as answer}
<li>{answer.content}</li>
{/each}
</ul>
<Error error={error} />
<form method="post">
<textarea rows="15" bind:value={content}></textarea>
<input type="submit" value="답변등록" on:click="{post_answer}">
</form>
svelte로 question 및 answer 화면 구현 하는 게 주를 이뤘다.
fastapi도 가독성 좋고 편리하다고 느꼈는데
frontend framework인 svelte도 문법적으로 깔끔해보인다.
'MJSEC 활동 > 백엔드(2025-2학기)' 카테고리의 다른 글
| 백엔드 3주차 / ORM 이해, SQLAlchemy로 질문 목록 API 만들기 (0) | 2025.11.02 |
|---|---|
| 백엔드 2주차 / DB, Git (0) | 2025.10.26 |
| 백엔드 1주차 / Web 소개, Open API 사용 (0) | 2025.09.25 |
댓글