AID backend project 추가 정리

Stop._.bmin·2023년 7월 2일
0

Python FastAPI

목록 보기
8/10
post-custom-banner

이번 프로젝트를 진행하면서 배웠던 점을 총합해서 정리한 게시물입니다.

이때까지 정리한 글

  1. 개발환경 설정 + 패키지 정리
  2. fork한 repo를 origin에 push
  3. Lock 파일 & pre-commit
  4. FastAPI
  5. Pytest & Github action & Docker
  6. CloneCoding (CRUD, ToDO-list)
  7. DockerCompose & MongoDB
  8. Precommit Test
  9. CRUD vs AID_Web project
  10. SQLAlchemy

1. 개발환경 설정 + 패키지 정리

Pyenv: 다양한 버전의 파이썬을 관리하는데 사용되었다.
Pipenv: 가상환경을 사용하기 위해 사용되었다. 이때 pipfile이 생성되는데, 이것이 pipenv의 핵심 부분이 된다.

FastAPIUvicorn을 통해서 서비스 배포가 되는데, FastAPIFlask같은 파이썬 웹 프레임워크였다.

PymongoMongoDB를 파이썬에서 연결하기 위해서 필요한 라이브러리였다.

가상환경을 설정하는 이유

  1. 당장 눈앞에 보이는 프로젝트를 진행할 땐 문제가 없지만 여러 프로젝트를 동시에 진행하고 있거나 혹은 한 프로젝트 내에서 패키지 버전이 안 맞으면 문제가 발생한다.
  2. 예를 들어, 프로젝트 A는 django 버전 1.11을, 프로젝트 B는 django 버전 2.0을 사용한다고 해보자
  3. A를 진행하다가 B를 진행하면 버전 호환이 안 맞아 오류가 발생하므로 django 를 2.0으로 재설치후 진행하다가 다시 A를 하려면 2.0을 지우고 1.11을 재설치해야한다.

2. fork한 repo를 orgin에 push하기

upstream이란,

upstream은 곧 다른 사람의 GitHub의 저장소를 Fork한 경우 내 GitHuborigin이 되고, 처음 fork를 시도한 저장소를 upstream이라고 부른다.

원격으로 upstream 주소 등록

 git remote add upstream [REPO주소]

내 로컬 저장소로 upstream 저장소에 있는 걸 Pull(Fetch+Merge)하기

git pull upstream [브랜치명]

origin에 Push

git push origin [브랜치명]

3. CSS

1) Web Font를 적용

base.html에 web-font를 적용시켰다.

폰트 출처

2) 버튼 CSS

버튼은 아래와 같이 작성되었다.

* {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }

    body {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
        background: whitesmoke;
    }

    button {
        margin: 20px;
    }

    .w-btn {
        position: relative;
        border: none;
        display: inline-block;
        padding: 15px 30px;
        border-radius: 15px;
        box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
        text-decoration: none;
        font-weight: 600;
        transition: 0.25s;
    }

    .w-btn-outline {
        position: relative;
        padding: 15px 30px;
        border-radius: 15px;
        box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
        text-decoration: none;
        font-weight: 600;
        transition: 0.25s;
    }

    .w-btn:hover {
        letter-spacing: 2px;
        transform: scale(1.2);
        cursor: pointer;
    }

    .w-btn-outline:hover {
        letter-spacing: 2px;
        transform: scale(1.2);
        cursor: pointer;
    }

    .w-btn:active {
        transform: scale(1.5);
    }

    .w-btn-outline:active {
        transform: scale(1.5);
    }

    .w-btn-gra1 {
        background: linear-gradient(-45deg, #33ccff 0%, #ff99cc 100%); 
        color: white;
    }

    .w-btn-gra-anim {
        background-size: 400% 400%;
        animation: gradient1 5s ease infinite;
    }

    @keyframes gradient1 {
        0% {
            background-position: 0% 50%;
        }
        50% {
            background-position: 100% 50%;
        }
        100% {
            background-position: 0% 50%;
        }
    }

linear-gradient를 적용시키면 자연스럽고 예쁜 그라데이션을 구현할 수 있다.
이를 활용해서 nav.html의 상단 바도 편하게 적용시킬 수 있었다.

background: linear-gradient(to right, #ffa7a3, #5673bd); padding: 0.43em 1em; font-size: 19px; border-radius: 3px; color: #ffffff;

3) Sender.html

<style>
    body {
      font-family: Arial, sans-serif;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
    }

    form {
      width: 800px;
      padding: 40px;
      border: 1px solid #ccc;
      border-radius: 4px;
      background-color: #f2f2f2;
      display: flex;
      flex-direction: column;
    }

    label {
      margin-top: 10px;
      display: block;
    }

    textarea {
      width: 100%;
      resize: vertical;
      height: 200px;
    }

    .w-btn-rainbow {
      background: linear-gradient(-45deg, #33ccff 0%, #ff99cc 100%);
      color: white;
    }
    .w-btn {
      position: relative;
      border: none;
      display: inline-block;
      padding: 15px 30px;
      border-radius: 15px;
      box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
      text-decoration: none;
      font-weight: 600;
      transition: 0.25s;
      z-index: 1;
    }

    .w-btn-outline {
      position: relative;
      padding: 15px 30px;
      border-radius: 15px;
      box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
      text-decoration: none;
      font-weight: 600;
      transition: 0.25s;
    }

    .w-btn:hover {
      letter-spacing: 2px;
      transform: scale(1.2);
      cursor: pointer;
    }

    .w-btn-outline:hover {
      letter-spacing: 2px;
      transform: scale(1.2);
      cursor: pointer;
    }

    .w-btn:active {
      transform: scale(1.5);
    }

    .w-btn-outline:active {
      transform: scale(1.5);
    }
    .w-btn-gra-anim {
      background-size: 400% 400%;
      animation: gradient1 5s ease infinite;
    }

    @keyframes gradient1 {
      0% {
          background-position: 0% 50%;
      }
      50% {
          background-position: 100% 50%;
      }
      100% {
          background-position: 0% 50%;
      }
    }
</style>

버튼 코드는 위와 마찬가지로 똑같다. 다만 몇가지 배치를 조정하면서 관리자들이 지원자들에게 보낼 수 있는 페이지의 css 꾸몄다.

4) submission_detail.html

    <div class="submission-detail__field">
        <div class="submission-detail__label" style="border-radius: 5px; padding: 0.6em 1em; background: linear-gradient(to right, #ffa7a3, #5673bd); color: white;">이름:{{ submit_info.username }}</div>
    </div>

    <div style="border: 5px solid #F1F1F3; padding: 0.3em 1em; border-radius: 2px;">
        <div class="submission-detail__field" style="margin-right: 50px;">
            <div class="submission-detail__label">이메일: {{ submit_info.email }}</div>
        </div>
        <div class="submission-detail__field" style="margin-right: 50px;">
            <div class="submission-detail__label">학번: {{ submit_info.student_id }}</div>
        </div>
        <div class="submission-detail__field" style="margin-right: 70px;">
            <div class="submission-detail__label">Python Skill: {{ submit_info.python_skill }}</div>
        </div>
    </div>

    <div class="submission-detail__field">
        <div class="submission-detail__label">동아리 지원 계기 (공백 포함 500자 이내):</div>
        <div class="submission-detail__value" style="border: 5px solid #F1F1F3; padding: 0.3em 1em; border-radius: 2px; white-space:pre;">{{ submit_info.motivation }}</div>
    </div>
    <div class="submission-detail__field">
        <div class="submission-detail__label">AI 관련 수강 과목 (학교 수업이 아니어도 기재해주세요):</div>
        <div class="submission-detail__value" style="border: 5px solid #F1F1F3; padding: 0.3em 1em; border-radius: 2px; white-space:pre;">{{ submit_info.ai_subject }}</div>
    </div>
    <div class="submission-detail__field">
        <div class="submission-detail__label">본인이 하고 싶은 스터디:</div>
        <div class="submission-detail__value" style="border: 5px solid #F1F1F3; padding: 0.3em 1em; border-radius: 2px; white-space:pre;">{{ submit_info.study_want }}</div>
    </div>
    <div class="submission-detail__field">
        <div class="submission-detail__label">본인이 해보고 싶은 프로젝트:</div>
        <div class="submission-detail__value" style="border: 5px solid #F1F1F3; padding: 0.3em 1em; border-radius: 2px; white-space:pre;">{{ submit_info.project_want }}</div>
    </div>
    <div class="submission-detail__field">
        <div class="submission-detail__label">본인의 진로:</div>
        <div class="submission-detail__value" style="border: 5px solid #F1F1F3; padding: 0.3em 1em; border-radius: 2px; white-space:pre;">{{ submit_info.course }}</div>
    </div>
    <div class="submission-detail__field">
        <div class="submission-detail__label" style="white-space:pre;">프로젝트 경험: {{ submit_info.project_exp }}</div>
    </div>
    <div  style="border-radius: 5px;padding: 0.6em 1em;background: #F1F1F3;">
        <div class="submission-detail__field">
            <div class="submission-detail__label" style="white-space:pre;">Github: {{ submit_info.github }}</div>
        </div>
        <div class="submission-detail__field">
            <div class="submission-detail__label" style="white-space:pre;">Tech Blog: {{ submit_info.blog }}</div>
        </div>
    </div>

이건, 제출한 정보를 보여주는 html이다. 편의상 style코드는 올리지 않았다.
각 항목마다 style을 개별적으로 달아주었다.

5) 애먹은 pagination nav


    nav {
        margin-top: 70px;
        padding: 10px;
        border-radius: 5px;
    }

    .pagination .page-item .page-link {
        background: linear-gradient(-45deg, #FFA3B1, #FFD8CB);
        border-color: transparent;
        color: white;
    }

    .pagination .page-item.active .page-link {
        color: white;
        background: white;
        color: #FFD8CB;
        border-color: #FFD8CB;
    }

    .pagination .page-item .page-link:hover {
        background: linear-gradient(-45deg, #FFA3B1, #FFD8CB);
        filter: brightness(90%);
        color: white;
    }

저번에 앞에서 설정한 bootstrap때문에, 색상 default가 파란색이 되어서 그런지, 자꾸 nav바 글씨가 파란색으로 설정되었다.

사진이 흐릿하지만, 저기 숫자가 파란색인건 볼 수 있을 것이다.

그래서 이걸 어떻게하지, 근본적으로 문제를 해결해야하나 계속 고민하다가 해결이 어려워서 그냥 추가적으로 속성해서 글씨를 white를 넣어버렸다.
원래 boostrap쓰면, 기본적으로 파란색으로 정말 예쁘게 hover속성까지 다 완벽하게 만들어주는데, 우리 웹 페이지는 핑크색으로 도배하고 싶어서 직접 속성을 다 부여하였다.

4. Login 이슈


원래는 위와 같이 하드코딩을 했었다.
이건 좋지 않다고 해서, 회장님께서 db에 데이터를 숨겨놓고, 깃허브 코드상에서는 위와 같이 확인되는 경우를 막도록 수정하셨었다.

정리하는 시점에서 현재 코드 pull받아서 정리하려고 확인해봤는데, 이건 다시 하드코딩 되어있는 것 같아서 추가적으로 정리하는건 다음에 기회가 된다면 해보도록 하겠다. (아마 조만간 할 듯 하다..)

5. 정규식을 활용하여 이메일 폼 확인하기


    def is_valid(self):
        if self.username == "":
            return False

        email_pattern = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
        if not re.match(email_pattern, self.email):  # 정규식을 사용하여 이메일 폼 확인
            return False

        if len(self.student_id) != 9:
            return False

        return True

6. 합불 여부를 결정하는 방법


기본 값을 false로 결정해둔 후에, 아래 코드를 통해서 new_value를 설정해주는 것이다. 내가 잘 해결하지 못해서 회장님께서 도와주셨다.

profile
원하는 만큼만
post-custom-banner

0개의 댓글