본문 바로가기
코딩

[패스트캠퍼스]웹개발 강의 4주차 후기

by 담슬생 2023. 1. 29.

4주 차 수업 내용

서버 실행하고 응답 만들고 파일 관리까지

모바일 청첩장 만들기 실습

 

#국비지원교육 #내일 배움 카드

 

1. Flask(플라스크)

파이썬 프로그램으로 백엔드 프로그램을 만들기 위해서는 필요한 배경 지식이 많은데, 요즘에는 이미 개발자들이 만들어서 제공하는 코드들(=라이브러리)이 있다.

Flask라는 라이브러리도 그중 하나로, 이번 수업에서 사용하게 될 예정

플라스크를 사용하는 이유는 웹서버를 만드는 여러 라이브러리들 중에서도 필요한 최소한의 기능들만이 들어있어서 가볍고 빠르며 마이크로 서비스를 만들 때 유용하기 때문이다. (한마디로 진입장벽이 가장 낮다)

 

플라스크는 비주얼스튜디오 프로그램에서 새 터미널을 열고  pip install flask를 입력해 설치할 수 있다.

플라스크의 기본 기능을 사용할 수 있는 튜토리얼을 다음 홈페이지에서 제공하고 있다. 

https://flask-docs-kr.readthedocs.io/ko/latest/quickstart.html

 

빠르게 시작하기 — Flask 0.11-dev documentation

웹 어플리케이션에 있어서 클라이언트에서 서버로 보내는 데이타를 처리하는 것은 중요한 일이다. Flask에서 이 정보는 글로벌한 request 객체에 의해 제공된다. 여러분이 파이썬 경험이 있다면,

flask-docs-kr.readthedocs.io

이 페이지에 접속 후 윗부분에 있는 다음 코드를 입력하면 코드가 종료되지 않고 경고창이 뜬다

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World!'

if __name__ == '__main__':
    app.run()

프로그램이 종료되지 않고 계속 실행 상태인 이유는,

웹사이트에 접속한 순간부터 계속 그 형태를 유지하고 반응을 한다는 점에서

진행이 종료되지 않고 항상 실행 중인 프로그램과 같다고 볼 수 있기 때문이다.

 

위 코드에 있는 주소를 구글창에 그대로 검색해서 이동하면 Hello World!라고 출력된 창이 뜬다.

 

코드를 분석해 보자면,

@app.route('/')라는 코드는 해당 루트, 즉 웹사이트 주소를 지정한다. def를 통해 hellow_world()라는 함수를 지정해 줬고, 이 함수는 Hello World!라는 텍스트 값을 반환한다. 이 코드는 해당 루트에 접속하면 항상 실행 중인 상태이다.

 

만약 @app.route('/fc')라는 코드를 추가한다면, http://127.0.0.1:5000/fc라는 주소를 지정하는 것과 같다.

이 페이지에서는 다른 기능을 보여주고 싶다면 다른 함수를 지정해서 사용하면 된다.

 

추가로, 이 코드는 항상 실행 중인 상태를 유지하고 있기 때문에 코드를 수정하고 다시 작동하는 걸 확인하고 싶다면 꼭 컨트롤+C를 사용해 코드 실행을 멈추고 다시 실행해야 정상적으로 확인할 수 있다.

 

그리고 위 코드에서 또 짚고 넘어갈 부분은 바로 마지막 두 줄인데,

이 코드는 사용자가 해당 코드를 직접 실행하는 것인지 혹은 패키지로 받은 파일이 자동으로 실행되는지를 묻는 조건문이다. 즉 직접 실행했을 때만 코드가 실행되도록 하는 것이다.

우리가 파이썬 파일을 실행할 때, 어떻게 실행되는지 그 형태에 따라 __name__ 변수의 값이 달라진다.

(직접 실행일 경우 __main__이고 아닌 경우는 파일 명으로 저장된다.)

 


2. Flask를 활용해 파이썬과  HTML, API를 연동하기(백엔드)

 

본격적으로 플라스크를 활용해 보는 과정

4주 차 수업 폴더 안에 templates라는 폴더를 따로 만들었다.

폴더 이름은 플라스크에서 정의한 이름이므로 잘못 입력하지 않도록 주의해야 한다.

 

templates 폴더 안에 제작한 웹사이트의 html코드를 저장해 놓고(일종의 경로 설정과 같다) 플라스크를 활용해 그 파일을 URL주소와 잘 연결해서 html코드를 반환해 사용자가 내가 제작한 웹사이트를 보게 하는 것이 기본 원리!

 

from flask import Flask, render_template
app = Flask(__name__)

@app.route('/')
def hello_world():
    return render_template('hello_world.html')

위 코드와 겹치는 부분은 제외했다. 맨 윗줄에 render_template라는 함수를 사용할 거라고 추가로 선언했고, 미리 작성한 hello_world.html 파일을 render_template 함수를 사용해 반환하도록 했다.

 

 

html연동이 됐으니 다음은 api차례

둘의 차이점은, html은 웹페이지를 결과로 반환하고 api는 데이터를 결과로 반환한다는 점이다.

 

@app.route('/fc')
def fastcampus():
    res = []
    for i in range(10):
        res.append(
            {"title" : str(i) + " title"}
        )
    return jsonify(res)

api를 활용하기 위해서 코드 첫째 줄에 jsonify함수를 사용하겠다고 추가로 선언해 준다

/fc 경로에 적용해 볼 건데, data 형식으로 저장하기 위해서는 json, 즉 키와 정보가 쌍으로 이루어진 형태로 저장되어야 한다. 따라서 리스트 형식으로 데이터를 저장해 볼 건데, 그러기 위해 빈 리스트를 하나 만들고 반복문을 사용했다.

append 함수는 괄호 안의 정보를 리스트 안에 새로 추가하는 기능을 수행하는 함수이다.

리스트를 반환할 때, return res만 사용하면 오류가 발생한다. res는 데이터 형태로 저장되어 출력에 적합하지 않은 형태이기 때문이다. 따라서 jsonify함수를 사용해 데이터를 반환해 줄 필요가 있다.

 

/fc경로에 접속하면 위와 같은 화면이 출력된다.

 


3. Flask에서 파일 관리하기

이전에 html 작성에서 공부했을 때, css 파일을 따로 작성해서 그 경로를 첨부해 링크를 넣는 방식으로 작성한 적이 있는데, 플라스크를 사용하면 백엔드에서 경로를 이미 관리하고 있기 때문에 방식이 조금 달라진다.

따라서 효율적인 파일 관리를 위해서 필수적으로 그 방식을 숙지해야 한다.

4주 차 폴더 안에 static 폴더를 생성한다. templates처럼 Flask에서 지정한 이름이니 오타가 없도록 주의한다.

 

<html>
    <head>
        <link rel="stylesheet" href="/static/styles.css">
    </head>
    <body>
        <h1 class="red">제목입니다!</h1>
    </body>
</html>

 

 

플라스크에서의 경로 지정은 위 화면의 코드 3열처럼 /static으로 시작하면 static 폴더 내부의 주소를 플라스크가 폴더와 주소를 자동으로 연동해 준다.

 

 


4. 모바일 청첩장

 

이제 배웠던 내용을 총합해서 웹페이지를 만들어보는 연습 단계에 들어간다. 배운 걸로 만들 수 있는 게 맞나 하는 의문도 들지만 강의를 천천히 들으면서 하다 보면 생각보다 할만했고 기본적인 html 뼈대나 css코드는 제공되어서 빠르게 스킵할 수 있어서 좋았다.

 

https://pictogrammers.com/library/mdi/

 

Material Design Icons - Icon Library - Pictogrammers

The original. Following Google's Material Design guidelines for system icons, MDI is our largest library, touting over 6500 unique icons!

pictogrammers.com

모바일 청첩장 만들 때 쓰는 전화 이모티콘을 가져온 사이트이다. 비용은 들지 않는 것 같고, 원하는 검색어를 검색하고 나온 이모티콘 중 마음에 드는 이모티콘을 선택 후 </> 아이콘을 눌러 svg코드를 복사해 올 수 있다. svg 코드가 아니라 이미지 저장으로도 가져올 수 있지만 이렇게 코드로 가져올 경우 색이나 크기의 조절이 더 자유롭다는 장점이 있다.

 

*현재 시각을 기준으로 며칠 남았는지 계산하는 기능

index.html파일이 아닌 app.py 파일에서 사용해야 한다.

접속 시간을 가져올 수 있는 datatime이라는 패키지를 사용하기 위해 맨 윗줄에 import datetime 코드를 추가한다.

이 패키지는 파이썬에 기본적으로 내장되어 있는 함수로, 따로 패키지를 설치할 필요는 없다.

 

def index():    #파이썬에서는 함수를 정의할 때 def를 사용
    now = datetime.datetime.now()
    wedding = datetime.datetime(2023, 1, 27, 0, 0)
    diff = (wedding - now).days
    return render_template('index.html', diff=diff)

위와 같이 사용할 수 있다.

1) now 함수를 사용해 현재 시각을 가져오고, 결혼식 날짜를 wedding이라는 변수에 저장한다. 이때 괄호 안의 숫자들은 순서대로 연도, 월, 일, 시, 분을 나타낸다.

2) 이 둘의 차이를 구하기 위해서 diff라는 임의의 변수를 만들고 두 시간 상의 차이를 구한 후. days를 사용해 일 단위로 나눈다.

3) return 함수 안에 diff값을 넣어 주어 html코드 안에서도 diff 값을 사용할 수 있도록 한다. 다섯 번째 줄의 diff=diff에서 앞의 diff변수는 index.html 파일에서 사용할 변수 값이고, 뒤의 diff변수는 실제로 파이썬에서 계산한 값이다. 복잡해 보이지만 코딩에서 변수를 지정할 때와 같이, A=B 식의 변수 지정과 같다. A와 B가 같다는 의미가 아니라 B를 A에 집어넣겠다는 뜻이 더 적절할 듯. 변수의 이름이 같아서 혼란이 발생할 수 있으니 주의할 필요가 있어 보인다.

4) diff 값을 실제로 적용할 위치에서는 중괄호를 두 개 사용하면 된다. {{diff}}라고 입력하면 자동으로 변환된다.

 

 

*사이트에 방명록 만드는 기능

방명록은 남기는 사람의 이름과 내용, 시간 등이 저장되어야 하므로 몽고 DB를 이용해야 한다.

웹페이지를 실행하는 app.py파일로 돌아와 /write 링크를 한 개 더 만들어 준다. method는 POST이다.

@app.route('/write', methods=['POST'])
def write():
	return ''

def 함수 안에 들어갈 내용은 몽고 DB를 연결한 후에 추가함

 

몽고 DB와 플라스크 두 개를 동시에 사용하기 위해서는 새로운 패키지를 설치해야 한다.

새 터미널을 열고 pip install flask-pymongo를 입력한다. Successfully installed라는 문구 나오면 성공.

만약에 실패하면 VScode 화면 오른쪽 아래 파란색으로 버전이 쓰여있는 부분을 클릭해

인터프리터 선택창을 열고 아래 나와있는 프로그램 중 파이썬 선택하면 된다고 함. 

코드 처음 부분의 패키지 사용 선언하는 줄 사이 아무 데에서나 아래와 같은 코드를 입력한다.

from flask_pymongo import PyMongo

flask_pymongo라는 패키지에서 PyMongo를 가져오겠다는 선언

추가로 플라스크 패키지 선언에 request, redirect도 사용하겠다고 추가해 준다.

 

몽고 DB 기본 설정은 3주 차에서 배웠던 대로 하면 됨

 

이제 html 파일로 가서 캘린더 아래 부분에 따로 div 태그를 만들어 방명록 칸을 추가한다.

<div class="row">
    <h2>방명록 남기기</h2>
    <form method="POST" action="/write">
        <input type="text" name="name">
        <textarea rows="3" name="content"></textarea>
        <button type="submit">남기기</button>
    </form>
</div>

form 태그는 처음 나왔는데, 작성한 데이터를 서버로 전송할 때 사용하는 태그이다. method와 action을 지정해 어떤 정보 형식으로 전달할지와 어디로 전달할지를 정할 수 있다.

form 태그 안의 첫째 줄 input~은 이름을 작성하는 칸이고 그 아래줄은 내용을 작성하는 칸이다. 이름보다 내용이 훨씬 많이 들어가야 하므로 여러 줄을 설정할 수 있다. 최대 줄 개수는 현재 세 줄로 되어있는데 조정 가능하다.

셋째 줄의 button은 submit, 즉 제출하는 타입을 가지고 있는데 이는 form태그와 함께 사용된다.

 

코드를 저장하고 실행한 다음 서버에 들어가면 아래와 같은 화면이 나온다.

디자인이 들어가지 않은 날것 그대로의 코드..^^

 

이름과 내용을 작성했을 때 redirect에 의해서 화면이 새로고침되는 것까지 확인하면 여기까지는 성공적

이름과 내용을 각자 받아서 이를 딕셔너리 형태로 몽고 DB에 저장하면 연동 끝

데이터베이스 이름은 몽고 DB에 들어가서 따로 만들지 않아도 없는 이름이면 자동으로 생성해 준다.

아직 데이터베이스 내용을 불러오는 것까진 안 했으니 직접 몽고 DB에 들어가

샘플로 작성한 이름이 wedding에 잘 저장되어 있는지 확인했다.

 

디자인적인 요소를 추가하기 위해서 배경색과 마진값, 패딩값, 폰트 굵기 등등 이런저런 디자인 요소들을 추가한다.

text 입력 칸에 어떤 내용인지 미리 보여주기 위해서는 placeholder=" "를 사용하면 된다.

+)한 태그에 클래스 속성을 여러 개 입힐 때 띄어쓰기 하면 된다

css파일에 디자인 요소 다 추가하고 나면 아래와 같은 모습이 된다.

대충 고른 색 치곤 의외로 예쁜 것 같기도 하고

*방명록 출력하기(데이터베이스 값 가져오기)

guestbooks = mongo.db['wedding'.find]

위와 같은 코드를 index함수 안에 넣어준다. find함수는 값을 가져오는 함수이므로

wedding이라는 데이터베이스 안에 있는 정보를 guestbooks라는 변수로 가져올 수 있다.

이 값을 반환해 출력해야 하므로 diff=diff 옆에 guestbooks=guestbooks도 추가해 준다.

 

{% for gb in guestbooks %}
{{ gb.name }}
{% endfor %}

html 안에서 반복문을 사용하기 위해서는 반드시 위와 같이 {% %} 안에 사용해야 하며 {% endfor %}로 끝내야 한다.

 

그래서 이걸 반복하는 방법은 알겠는데 어떻게 방명록형식으로 깔끔하게 보여줄 수 있나 가 궁금했는데

테이블 태그 안에 반복문을 넣어서 아래와 같이 사용했다. 대박..

<table>
    <tbody>
        {% for gb in guestbooks %}
        <tr>
            <td> {{ gb.name }} </td>
            <td> {{ gb.content }} </td>
        </tr>
        {% endfor %}
    </tbody>
</table>

나머지 디자인적인 요소들은 css파일에서 guestbook-row 클래스의 table 태그에 대해서 수정하면 된다.

+) border-collapse:collapse;로 설정을 활성화하면 행마다 줄을 그을 수 있다

+) 내용에서 줄 띄움이 적용되게 하려면 content가 있는 td 태그의 클래스의 스타일을 설정할 때 white-space: pre;로 설정하면 입력한 값이 그대로 띄워지게 되면서 입력 시 엔터키를 눌렀다면 <br> 태그를 사용한 것과 같은 효과를 볼 수 있다.

 


4주 차 첫 번째 수업 후기

 

사실 3주 차부터 토익시험도 겹치고 바빴는데 4주 차에는 명절이 겹쳐서 본가 갔다 오는 것부터

오랜만에 시간 낸 대학 친구들하고 얼굴도 보고 하느라 진짜 바빴다. 그리고 그 와중에 술병이 걸려 이틀정도 누워있었다...

 

강의 시간이 일주일에 2시간이래도 내가 나노단위로 멈추고 글로 정리하고 돌려보고 이러느라 훨씬 오래 걸린 것 같기도 하다. 체감상 하루에 두 시간씩 일주일 들은 것과 같은 효과... 10분짜리를 최소 30분은 걸려서 듣는다.

그리고 백엔드 부분이 본격적으로 나오기도 했고 갑자기 휘몰아치는 코딩에 좀 어지러워서 쉬면서 천천히 들었다.

이번주 수업이 확실히 내가 수강신청하기 전에 듣기를 기대하면서 신청한 그 내용이 맞아서 신기한 한편 (당연하게도) 너무 어려워서 현타가 몇 번 올 때가 있었다. 그래도 나름대로 글로 정리하면서 어영부영 따라가 보고 있는데 나중에 다 기억났으면 좋겠다... 

 

댓글