이전에는 장고만 썼는데, 한 유튜버가 플라스크와 GPT-4o-mini 를 이용하여 자동으로 답변을 달아주는 웹을 만들었길래 이번 기회에 플라스크도 배워볼까한다.
튜토리얼 가이드라인은 GPT-4 에게 도움을 받아 작성하였다.
플라스크의 특징은 단순하고, 가볍고, 빠르다는 점이다.
사용자 마음대로 커스텀이 가능하다는 유연성을 갖기에 개발 속도가 빠르다.
반면, 장고는 웹 개발에 필요한 모든 기능들이 이미 내장되어있는 프레임워크다. 정해진 형식대로 코드를 작성하면 되기에 유지 및 보수에 용이하다는 장점을 갖는다. 더불어, 플라스크에 비해 보안 처리 면에서 우수하기도 하다.
두 프레임워크의 특징을 생각해보면 답이 나온다. 플라스크의 경우, 빠른 프로토타입 개발이 장점이므로 간단한 기능 구현을 할 때, 이놈을 쓰면 유리할 것이다. AI가 댓글을 자동으로 달아주는 웹사이트같이 새로운 기능을 바로 적용하자면 플라스크가 유리할 것이다.
반면, 장고로 웹을 개발하겠다면 장고에서 선보이는 웹 개발에 최적화된 함수라던가, 보안 관련 기능을 이용하는 것이 좋을 것이다. 이는 플라스크와 차별화되는 점이니 포트폴리오에서 해당 부분을 부각해주는 것이 맞지 않나 싶다.
본 프로젝트는 Pycharm 을 이용해 진행하였다. 파이참을 다운로드하면 플라스크 기능을 자동으로 제공하기에 부수적인 작업을 따로 하지 않아도 되서 편리했다.
파이참을 실행하고 New Project 를 선택 후, flask 를 선택해주면 아래와 같이 기본적인 파일을 생성해준다.
app.py 를 아래와 같이 수정해주고 파일을 실행하면 http://127.0.0.1:5000 에서 Hello World! 가 출력되는 화면을 확인할 수 있다.

URL과 함수를 연결하여 특정 URL에 접속했을 때, 어떤 동작을 수행할 지 정의하는 것.
플라스크 역시 장고처럼 라우팅 기능을 제공한다.
라우팅은 아래와 같이 @app.route(url) 형식으로 설정할 수 있다.
아래 예제에서는 웹이 실행될 때, home 함수를,
subPage 에 들어갔을 때, subPage 함수를 실행하도록 작성하였다.
이제 로컬 서버에서 해당 url 을 입력하여 페이지를 이동해보면 각각의 함수가 잘 작동하는 것을 확인할 수 있다.
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'Welcome to the Main Page!'
@app.route('/subPage')
def subPage():
return 'This is the subPage.'
유저 정보에 따라 해당 유저의 정보창으로 라우팅을 해야하는 경우, 동적 라우팅이 필요하다. 플라스크에서 동적 라우팅은 <> 를 이용하여 정의할 수 있다.
아래 예제를 살펴보자.
'user/유저이름' 으로 접속을 시도했을 때, 해당 유저의 이름을 출력하도록 설정하였다.
'post/게시물 아이디' 로 접속을 시도했을 때, 해당 게시글의 아이디를 출력하도록 설정하였다.
예를 들어, url 창에 'user/ciracino' 라고 입력하면, 'User: ciracino' 라는 창을 반환한다.
'post/1' 이라고 입력하면, 'Post ID: 1' 이라는 창을 반환한다.
@app.route('/user/<username>')
def show_user_profile(username):
return f'User: {username}'
@app.route('/post/<int:post_id>')
def show_post(post_id):
return f'Post ID: {post_id}'
장고처럼 플라스크도 템플릿 기능이 존재한다. 미리 템플릿 폴더에 작성해둔 HTML 과 CSS 파일들을 필요한 url 에다가 매핑해주는 것이다.
템플릿 관련 파일들은 모두 'templates' 폴더 안에 작성된다. 파이참에서 플라스크 프로젝트를 생성할 때, templates 폴더를 자동으로 만들어주었기에 이를 이용하였다.
templates 폴더 안에 'home.html' 파일을 생성하고 아래와 같이 작성해주자.
주목할 점은 {{ message }} 라고 작성된 부분이다.
장고와 유사하게, 플라스크에서도 템플릿에서 동적 처리할 부분은 이렇게 중괄호를 이용해서 처리한다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Home</title>
</head>
<body>
<h1>Welcome to the Home Page!</h1>
<p>{{ message }}</p>
</body>
</html>
app.py 파일도 아래와 같이 수정해준다.
플라스크에서 템플릿을 적용하는 방법은 render_template 을 이용하는 것이다.
해당 함수는 매개변수로 어떤 템플릿을 적용할지와, 해당 템플릿에서 동적 처리할 부분에 대한 값을 받는다.
home.html 에서는 message 부분을 동적 처리하기로 했으니, 이를 정의하여 넘겨준다.
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def home():
message = "This is a dynamic message passed from the view function."
return render_template('home.html', message=message)
@app.route('/subPage')
def subPage():
return 'This is the subPage.'
@app.route('/user/<username>')
def show_user_profile(username):
return f'User: {username}'
@app.route('/post/<int:post_id>')
def show_post(post_id):
return f'Post ID: {post_id}'
템플릿 상속은 이전에 사용했던 템플릿을 그대로 가져와 다른 템플릿에 적용하는 것을 의미한다.
layout.html 이라는 파일을 만들고 해당 템플릿을 home.html 에 그대로 상속해보겠다.
먼저, layout.html 을 만들고 아래와 같이 작성해준다.
{% block content %}{% endblock %} 은 상속받은 템플릿에서 처리할 부분을 의미한다.
따라서 home.html 에서는 이 부분만을 작성해주면 된다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>GPT-4o-mini-website - ciracino88</title>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300;400;500;700&display=swap" rel="stylesheet">
<style>
</style>
</head>
<body>
<div class="content">
{% block content %}{% endblock %}
</div>
<footer>
<p>created by ciracino88</p>
</footer>
</body>
</html>
이어서 home.html 을 아래와 같이 수정해준다.
템플릿 상속은 extends 를 통해 사용할 수 있다.
{% extends 'layout.html' %}
{% block content %}
<h2>Welcome to the MainPage</h2>
<p>{{ message }}</p>
{% endblock %}
웹에서 데이터를 주고 받을 때는 get, post 등의 http 메서드를 이용한다.
로그인 페이지를 만들고 해당 페이지에서 계정 정보를 주고 받는 작업을 처리해보자.
app.py 파일에 로그인 페이지에 대한 라우팅 작업을 진행해준다.
http 관련 메소드는 request 를 통해 이루어진다.
요청의 종류와 넘겨받은 값에 따라 로직을 어떻게 처리할지를 설계하면 된다.
route 의 매개변수로 methods 를 받았는데, 아마도 허용할 메소드 형식들을 받는 것 같다. 아래 예제에서는 get 과 post 를 받았는데, 이 둘을 제외한 다른 http 메서드가 작동할 경우, 오류를 내뱉는 것으로 보인다.
methods 를 따로 작성해주지 않을 경우, 디폴트는 get 인 것으로 추정된다. (methods 를 지우고 코드 실행해보니, 계속 405 오류 발생함)
error 의 초깃값을 None 으로 설정해준다.
로그인 시 오류가 발생한다면 error 에 메시지 값을 부여하여 login 화면에 오류 메시지를 보여준다.
요청 방식이 post 인지를 확인한다. 로그인 페이지에서 post 방식으로 요청하는 방법은 로그인 폼에 값을 작성하여 넘기는 것이 유일하므로 이외의 방법으로 값을 전달받을 경우 로그인을 실행하지 않을 것이다.
폼 데이터에 접근하는 방법은 'request.form' 을 통해 접근 가능하다.
유저 이름이 admin, 패스워드가 1234 인지를 확인하고 메인 페이지로 넘어갈지를 결정한다.
여기서 url_for 함수를 사용하는데, 어떤 페이지로 넘어갈지를 매개변수로 받는다.
render_template 에 매개변수로 error 를 넘겨준다.
이 값이 존재하면 error 메시지를 띄우고 그렇지 않다면 로그인 화면을 띄우는 것이다.
from flask import Flask, render_template, request, redirect, url_for
@app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
if username == 'admin' and password == '1234':
return redirect(url_for('home'))
else:
error = 'Invalid username or password.'
return render_template('login.html', error=error)
이 정도라면 내가 진행할 프로젝트를 하는데 필요한 플라스크 지식들은 다 챙겼다고 생각된다.
다음 글에서는 flask 와 GPT-4o-mini 를 연동하여 웹페이지를 제작해보도록 하겠다.