[FastAPI] CloneCoding (CRUD, ToDO-list)

Stop._.bmin·2023년 3월 19일
0

Python FastAPI

목록 보기
5/10

목표

이번에 나온 미션은 FastAPI를 활용해서 to-do페이지를 만드는 것이었고, 학습의 용이성을 위해서 클론 코딩을 통해서 학습 방법을 제안해주셔서 제시해준 유튜브 링크를 통해 학습을 하는게 목표였다.

😵 매우 큰 실수를 하였다

보내주신 유튜브 계정에 많은 자료들이 있길래 구경을 하다가보니 헷갈려서 to-do가 아니라 CRUD를 만들어버렸다.

물론 이걸 나중에 알아채고 급하게 to-do도 해보았고.. 결국에 어쩌면 잘못 확인한 일이 되려 이익을 준 것 같기도 하다.

왜냐하면, CRUD페이지는 곧 Create, Read, Update and Delete기능을 구현하는 페이지로 어차피 to-do페이지를 만들기 위해 필요한 도구(웹 어플리케이션)들을 좀 더 도구에 집중해서 만든 느낌이었기 때문이다.

그래서 오늘 내가 정리할 내용은?

  1. CRUD, to-do 클론 코딩에 사용한 Jinja2 Template
  2. 사실 CRUD페이지를 하면서 정말 온갖 난리가 났기 때문에 to-do 클론코딩 할 때는 사실상 에러가 떠도 원인을 어느정도 알게 되어서 해결하기에 용이했다. 이 에러를 극복한 방향을 아래 글에 쓰려고 한다.

🧐 Jinja Template

templates folder의 이해가 필요했다.

HTML 파일의 저장소 -Template폴더

  • flask 프로젝트에서 사용될 HTML파일을 여기에 모아둔다.

  • 그래서 해당 폴더를 html 템플릿이라고 부른다.

    웹 페이지에서의 JS역할을 한다.

  • 원래는 프론트엔드에서 웹페이지를 구현하려면 최소 3가지를 알아야 한다.

    • HTML, CSS, JS(JS만 프로그래밍 언어)
  • 웹 페이지에서 JS의 역할

    • 사용자마다 다른 페이지가 보이게 한다.
      • 로그인한 사용자마다 다른 닉네임이 나오게 한다.
      • 로그인 한 사람/ 안한 사람이 다르게 한다.
    • 기능에 따라 다른 페이지가 보이게 한다.
    • 유동적인 페이지, 페이지의 동적화를 담당한다.

그래서 Jinja Template Language가 무엇인가?

  • Flask에서 Jinja Template Language라는 언어를 사용할 수 있다.
  • JS의 역할, 웹 페이지가 동적으로 반응해야 될 부분JS가 아닌 Python코드와 유사한 방식으로 작성하여 구현할 수 있다.

좀 더 자세한 내용은 이 링크를 참고하면 언제든 다시 확인할 수 있다.

그치만.. to-do에는 없었지만CURD 하면서 base.html를 만들게 됐는데 이거에 관해서 조금 정리해두겠다.

Base.html

  • 전체 웹 사이트의 테마가 될 것이다.
  • 이것은 templates 폴더 안에 생성한다.
  • html의 header, footer등 어느 페이지에서도 유지되는 공통 부분을 구현하게 된다.

Jinja - block기능

  • 테마가 될 base.html에 채워질 영역을 정의해준다.
  • 다른 페이지를 활용하여 채워지게 될 빈칸을 만든다고 생각한다.
  • 다음과 같이 표기한다.
    -빈 칸의 시작 : {% block title %}
    • 빈 칸의 끝 : {% endtitle %}
    • {% block title %} 기본값 {% endtitle %}

🥲 아마추어적인 실수

1. Runtime Error: Directory 'public' does not exist

한참을 고민을 했다.

분석한 바,

  • main.py 파일에서 staticFiles를 사용할 때, public 디렉토리가 없어서 발생하는 오류다.
  • 프로젝트 루트 디렉토리에 public 디렉토리를 만들어 주면 해결된다.
  • mkdir public 명령어로 디렉토리를 만들어 줄 수 있다.
mkdir public

🤔 엥 public 디렉터리가 뭐길래 필요함??

  • public 디렉토리는 프로젝트에서 사용하는 정적 파일들을 저장하는 디렉토리다.
  • CSS, JavaScript, 이미지 파일 등의 정적 파일들을 저장한다.
  • 따라서 public 디렉토리를 생성하고 정적 파일들을 추가해주어야 한다.

2. in __init__ raise RuntimeError(f"Directory '{directory}' does not exist")

문제를 분석한 바,

  • StaticFiles가 참조하는 디렉터리가 존재하지 않아서 발생한 문제다.
  • 따라서, StaticFiles가 참조하는 디렉터리가 올바르게 설정되어 있는지 확인하고, 디렉터리가 존재하지 않는 경우에는 디렉터리를 생성하거나 StaticFiles가 참조하는 디렉터리를 다시 설정해야 했다.

좀 더 쉽게 설명하자면,
원인: 에러 메시지에서 RuntimeError이 발생한 이유는, StaticFiles가 참조하는 디렉터리가 존재하지 않기 때문이다.

  • StaticFilesHTML, CSS, JavaScript와 같은 정적 파일을 제공하는 데 사용되는 FastAPI의 기능 중 하나다. 이 기능을 사용하려면, StaticFiles가 참조하는 디렉터리를 지정해야 한다.

해결: StaticFiles가 참조하는 디렉터리를 지정하는 방법은 app.mount() 메소드를 사용하여 지정한다.

내 코드에서는

app.mount("/static", StaticFiles(directory="static"), name="static")

구문을 사용하여, /static 경로로 들어오는 요청이 있을 때, static 디렉터리에 있는 파일을 찾아서 반환하도록 설정하였다.

그런데, 에러 메시지에서 "Directory 'static' does not exist" 라는 메시지가 나타난 이유는, StaticFiles이 참조하는 static 디렉터리가 존재하지 않기 때문이다. 이를 해결하기 위해서는, static 디렉터리를 생성하거나, StaticFiles가 참조하는 디렉터리를 다른 경로로 변경해야 한다.

이때 아래 코드를 사용하여 public 디렉터리에 있는 파일이 /static 경로를 통해 요청되도록 설정할 수 있다.

app.mount("/static", StaticFiles(directory="public"), name="static")

To-do 클론코딩 결과

결과 페이지는 위와 같다.

내가 할 일을 입력하면 save되고, 했다면 update, delete를 누르면 된다.
결국 CRUD에서 구현한 기능들을 필요에 알맞게 집어넣은 꼴이 되었다.

그리고 동작을 확실히 확인하고자 할 때, FastAPI에서 제공해주는 Swagger UI를 통해서 다시 확인할 수 있었다.

2번째 있는 놈을 지우겠다.

2를 넣으면 지워지지롱

1번은 다 했어!


complete 값이 1이 되네


페이지에서도 표시가 된다!!

✏️ 앞으로는 어떻게 해야할까..

이번에 클론 코딩을 통해서 전체적인 틀을 익혔던 것 같다. 물론 완벽히는 아니지만! 간단한 기능을 수행하는데 있어서 몇 가지 기능을 뜯어서 공부하다보면 언젠가 내가 원하는 부분에 알맞는 기능을 구현할 수 있지 않을까 생각을 하게 되었다.

  1. SQLAlchemy에 대해서 더 자세히 알아오자!
    ORM(Object Relational Mapping)을 사용할 수 있게 도와주는 데이터베이스 관련 툴킷이라고 하는데, 이 부분은 내용이 좀 방대한 것 같아서 이번 게시물에는 정리하지 못했다.
  2. 좀 더 자세히 뜯어서 공부해볼 필요가 있다.
    클론코딩을 통해서도 물론 간단한 학습을 할 수 있지만 이건 시작이고, 앞으로는 직접 해보고 부딪히는 것이 가장 큰 도움이 되리라 생각한다.
  3. 해결되지 않은 궁금증
    사실 public, static 관련해서 겪은 문제(위에서 정리한 문제 중 2번째)는 뭔가 웹 페이지에 대한 구조나 동작에 관한 이해가 부족했기 때문에 발생했다고 생각한다. 이번에도 발생해서 겨우 급한 불은 껐으나, 앞으로도 많이 부딪힐 것 같다. 그때마다 열심히 채워넣어야 할 것 같다.

아쉬운 점..

  • 시간 투자가 부족해서 이번에는 이 코드가 어떤 기능을 하는지 하나하나 뜯어보기는 어려웠다.
    ➡️ 이번에 이해하지 못한 부분은 다음에 꼭 채워서 오자.

가상환경에 올리기도 성공

근데 이상태에서

uvicorn main:app --reload

해서 돌아간거면 성공한거면 가상환경 상에서 한게 맞는지 모르겠다.

profile
원하는 만큼만

0개의 댓글