개발 도서/FastAPI
4 템플릿팅
hp0724
2023. 10. 10. 14:00
API 보낸 다양한 형식의 데이터를 화면에 표시하는 프로세스다.
Jinja 템플릿 사용
4.1 Jinja
중괄호는 사용해서 템플릿 파일의 일반적인 HTML ,텍스트 등을 표현식 및 구분과 구분한다.
- {%….%} : 구조를 제어하기 위한 명령을 지정할때 사용
- {{todo.item}} : 식의 값을 전달할때 사용
필터
문자열 수정작업은 Jinja의 필터 기능을 사용해야 한다.
템플릿 상속
중복 배제 원칙에 근거한것 큰 규모의 웹 애플리케션을 개발할때 많은 도움이 된다 .
템플릿 상속은 기본 템플릿을 정의한 다음 이 템플릿을 자식 템플릿이 상속하거나 교체해서 사용할수 있게 한다.
4.2 FastAPI 에서 Jinja를 사용하는 방법
pip install jinja2 python-multipart
- 애플리케이션 홈 페이지용 home.html
- todo 페이지용 todo.html
from fastapi import APIRouter, Path,HTTPException ,status,Request,Depends
from fastapi.templating import Jinja2Templates
from model import Todo, TodoItem,TodoItems
todo_router = APIRouter()
todo_list = []
templates = Jinja2Templates(directory="templates/")
@todo_router.post("/todo")
async def add_todo(request:Request,todo:Todo = Depends(Todo.as_form)):
todo.id = len(todo_list)+1
todo_list.append(todo)
return templates.TemplateResponse("todo.html",{
"request":request,
"todos":todo_list
})
@todo_router.get("/todo",response_model=TodoItems)
async def retrieve_todos(request:Request) :
return templates.TemplateResponse("todo.html",{
"request":request,
"todos":todo_list
})
@todo_router.get("/todo/{todo_id}")
async def get_single_todo(request:Request ,todo_id: int = Path(..., title="The ID of the todo to retrieve")) -> dict:
for todo in todo_list:
if todo.id == todo_id:
return templates.TemplateResponse("todo.html",{
"request":request,
"todo":todo
})
raise HTTPException (
status_code=status.HTTP_404_NOT_FOUND,
detail="Todo with supplied ID doesn't exits",
)
@todo_router.put("/todo/{todo_id}")
async def update_todo(todo_data:TodoItem, todo_id: int = Path(..., title="the id of the todo to be updated")) -> dict:
for todo in todo_list:
if todo.id == todo_id:
# Update the todo using todo_data
# You need to implement the logic to update the todo here
todo.item=todo_data.item
return {
"message": "Todo updated successfully"
}
raise HTTPException (
status_code=status.HTTP_404_NOT_FOUND,
detail="Todo with supplied ID doesn't exits",
)
@todo_router.delete("/todo/{todo_id}")
async def delete_single_todo(todo_id: int) -> dict:
for index in range(len(todo_list)):
todo = todo_list[index]
if todo.id == todo_id:
todo_list.pop(index)
return {
"message": "Todo deleted successfully"
}
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Todo with supplied ID doesn't exits",
)
@todo_router.delete("/todo")
async def delete_all_todo() -> dict:
todo_list.clear()
return {
"message": "Todos deleted successfully"
}
block 사용하기 위해
{% block todo_container %} {% endblock %}
{% extends "home.html" %}
todo html 의 경우 home.html을 상속
id 값을 선택적으로 받기 위해서 Optinal[int]를 사용한다.
@classmethod
def as_form(
cls,
item: str = Form(...),
id:Optional[int]=Form(None)
):
return cls(id=id,item=item)