[Flask] 파이썬 코드를 웹페이지에 띄워보자! 사용자 ID 체크 웹페이지 만들기
본 포스팅에서는 Flask를 활용하여 간단한 웹페이지를 만들어 볼 것이다
최소한의 html을 사용하고, python의 for문 if문을 활용한 웹페이지를 구현해 보며 동작 원리를 이해해 본다.
파이썬 공부를 어느정도 하다보면 본격적으로 응용을 하고 싶어지게 된다.
처음에는 스스로 짠 코드를 실행하는 기쁨과 만족감을 느끼는걸로도 족하지만, 내가 짠 기발한 코드를 친구들이나 다른 많은 사람들에게 공유하고 싶은 순간이 오는 것 같다. 그러기 위해서는 웹페이지를 만드는게 가장 빠른 길일 것이다.
파이썬으로 웹페이지를 만드는 방법은 다양하지만 대표적인 방법은 Django나 Flask라는 파이썬 웹 프레임워크를 활용하는 것이다. 코드 몇 줄 만으로 웹페이지를 띄울 수 있으며, 조금만 응용하면 내가 짠 Python 코드가 작동하는 웹서비스를 만들 수도 있다.
본 포스팅에서는 Flask를 활용하여 간단한 웹페이지를 만들어 볼 것이다. 최소한의 html을 사용하고, python의 for문 if문을 활용한 웹페이지를 구현해 보며 동작 원리를 이해해보자.
최종 결과물은 다음과 같다.
미션 정의
사용자 아이디를 주어진 조건에 맞게 입력 되었는지 확인하고 결과에 따라 피드백을 주는 웹페이지를 만든다.
만들 웹페이지는 심플하게 2 페이지로 나뉜다.
- 사용자에게 비밀번호를 입력받아 Submit 받는 페이지
- 입력된 비밀번호가 조건에 맞는지 확인하고 사용자에게 피드백을 주는 페이지
- 조건에 맞다면 : 가입을 축하합니다
- 조건에 맞지 않다면 : 어떤 조건이 맞지 않는지 피드백 후 입력받는 화면으로 돌아가는 버튼
웹페이지는 다음과 같이 4개 파일로 구성된다.
- check_id.py : flask를 구동하고 웹페이지를 라우팅하고 렌더링하여 띄워 줄 python 파일이다.
- Base.html : 공통 html 내용을 상속해 줄 페이지이다. (NavBar와 Home Link)
- 공통으로 사용되는 Navigation bar와 home link를 여러 파일에 걸쳐 띄워야 하는데 코드를 각 페이지마다 반복하지 않도록 할 수 있는데, 상속을 활용한다.
- index.html : 아이디를 입력받고 submit 버튼을 눌러 결과 페이지로 이동하는 페이지
- report.html : 입력 결과를 확인하는 페이지
입력받을 사용자 ID의 요구 조건은 다음과 같이 세 가지다.
- 최소한 하나의 대문자 포함한다.
- 최소한 하나의 소문자를 포함한다.
- 마지막은 숫자로 끝나야 한다.
준비가 되었다면
출발!!
사용자 ID 확인 코드 작성
먼저 사용자 ID를 확인하는 코드를 짜보자. colab이나 jupyter에서 주요 코드를 미리 짜놓으면 편리하다.
우리의 요구 조건인 대문자를 포함, 소문자를 포함하는 것을 확인하려면 파이썬의 isupper, islower 함수를 쓰면 된다.
실행해보면 다음과 같다. 한 글자만 대문자가 아니라 모든 글자가 대문자여야 True를 반환한다.
("Tiger").isupper()
>>False
("TIGER").isupper()
>>True
한 문자만이라도 대문자일때 True를 받으려면 반복문과 any를 써주어야 한다.
List comprehention으로 각 글자에 대문자가 들어가는지 확인하는 변수를 짜주었다.
List comprehention에 대한 가장 쉬운 설명은 여기!
데이터 사이언티스트라면 반드시 알아야하는 5가지 필수 파이썬 스킬(feat. 꿀팁)
upper_letter = any(c.isupper() for c in userid)
소문자를 체크하는 변수도 동일하게 추가를 해주고..
마지막 글자가 숫자인걸 확인하는 함수는 str.isdigit()를 사용한다.
문자열 인덱스로 마지막글자가 숫자임을 확인하는 것임.
마지막으로, 세 조건이 모두 맞았을 때 True를 돌려주는 코드를 & 조건으로 짜준다.
lower_letter = False
upper_letter = False
num_end = False
upper_letter = any(c.isupper() for c in userid)
lower_letter = any(c.islower() for c in userid)
num_end = userid[-1].isdigit()
report = lower_letter & upper_letter & num_end
그 다음 Flask로 웹페이지를 만들어 보자.
Flask
먼저 기본적으로 계획했던 파일들을 셋팅해주자.
check_id.py 를 메인으로 하고,
templates 폴더에 html 파일들을 생성해준다.
- base.html
- index.html
- report.html
요렇게 생성되었다.
check_id.py로 웹서버를 띄워 준다. 나중에 해도 괜찮지만, 먼저 해준다.
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True)
터미널에서 파일을 실행하고
python check_id.py
http://127.0.0.1:5000 을 실행하면 아무것도 없는 흰색 index.html 파일이 뜬 것을 볼 수 있다. 이제 내용을 채워갈 것이다.
debug 모드를 띄워놓고, 브라우저를 새로고침하면서 개발을 진행하면 바로바로 피드백을 받을 수 있어 편리하다!
base.html
base.html 부터 작성해주자. base에는 모든 html에 상속시켜 적용할 공통 코드를 넣어준다.
홈버튼, Nav bar 를 bootstrap 을 적용시켜 넣어주었다.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Puppy World</title>
# bootstrap css 적용
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
# bootstrap js 적용
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
</head>
<body>
#bootstrap Navigation bar 적용(그냥 복붙 하면 됨.)
<nav class="navbar navbar-dark bg-primary">
<a class="navbar-brand" href="{{url_for('index')}}">PUPPY WORLD</a>
</nav>
#HTML 상속을 위한 block content 추가.
{% block content %}
{% endblock %}
</body>
</html>
이렇게 base.html을 작성해 주었다.
base.html은 화면에 직접 보여지는 파일이 아니라 공통적인 포맷을 뿌려주는 역할을 하게 된다.
index.html
그다음은 index.html을 작성해보자.
사용자 ID를 입력 받는 페이지이다.
# html 상속
{% extends "base.html"%}
{% block content %}
#Bootstrap UI 요소 추가
<div class="jumbotron">
<h2>Puppy World에 오신걸 환영합니다!</h2>
<p>사용자 ID를 확인하는 페이지입니다. 다음 조건을 유의하여 ID를 입력해주세요.</p>
<ul>
<li>최소한 하나의 대문자 포함한다.</li>
<li>최소한 하나의 소문자를 포함한다.</li>
<li>마지막은 숫자로 끝나야 한다.</li>
</ul>
#입력 form을 추가 하고 “report” 페이지로 연결한다.
<form action="{{url_for('report')}}">
<label for="first">User ID : </label>
<input type="text" name="userid">
#submit 버튼을 추가한다.
<input class="btn btn-primary" type="submit" value="Submit Form">
</form>
</div>
{% endblock %}
#block content ~~ endblock 사이의 내용만 추가 되는것이고,
#나머지 내용은 상속해준 base.html의 내용을 따라가게 되어
#반복적으로 복잡한 코드를 적을 필요가 없게 된다.
이렇게 index.html에서 사용자 ID를 받았다.
이제 가장 중요한 입력받은 사용자 ID를 확인하여 피드백을 주는 부분을 짜 본다.
check_id.py
check_id.py로 돌아가서 아까 짜준 코드를 report.html에 jinja template으로 넣어주자.
from flask import Flask, render_template
from flask import request
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
# report 페이지에 주요 변수들과 함수들을 정의해 준다.
@app.route('/report')
def report():
#입력받은 userid를 변수로 사용한다는 선언이다.
userid = request.args.get('userid')
# 기본적으로 False로 시작하고 아래에서 True일 경우 덮어씌워진다.
lower_letter = False
upper_letter = False
num_end = False
# 아까 짰던 코드들을 넣어주자.
upper_letter = any(c.isupper() for c in userid)
lower_letter = any(c.islower() for c in userid)
num_end = userid[-1].isdigit()
report = lower_letter & upper_letter & num_end
# 사용될 모든 변수들을 render_template에 정의해주어야 html에서 작동할 수 있다.
return render_template('report.html',userid=userid, lower=lower_letter, upper = upper_letter, num_end=num_end, report=report)
if __name__ == '__main__':
app.run(debug=True)
자 이제, py 파일 정의가 끝났으니, html로 넘어가 jinja template 형식으로 로직을 집어넣어주자.
report.html
아까와 동일하게 base.html에서 상속을 받아 코드가 심플해졌다.
{% extends "base.html"%}
{% block content %}
<div class="jumbotron">
<h1>Thank you for signing up {{id}}!</h1>
#python의 코드와 다른 점은 endif를 꼭 선언해 주어야 한다는 것!!
{% if report %}
<h2>환영합니다 {{userid}}! </h2>
{% else %}
<h2>아이쿠! 사용자 ID에 문제가 있어보여요.</h2>
<ul>
{% if not lower %}
<li>소문자가 포함되지 않았어요.</li>
{% endif %}
{% if not upper %}
<li>대문자가 포함되지 않았어요.</li>
{% endif %}
{% if not num_end %}
<li>숫자가 포함되지 않았어요.</li>
{% endif %}
</ul>
{% endif %}
</div>
{% endblock %}
이제 모든 준비가 끝났다.
터미널에서 실행해주자.
python check_id.py
실행
다음과 같이 실행 되었다. Bootstrap을 적용해 준 덕분에 css를 따로 쓰지 않았지만 나름 깔끔한 UI를 얻었다.
bootstrap에 대한 내용은 링크를 참고하자
소문자만 입력해 본다.
의도한대로 두가지의 보완점 피드백을 주었다.
다시한번 시도해 보자.
입력 : stevejobs55
이번엔 대문자랑 소문자, 숫자까지 섞어서!!
야홋! 성공하였다!
마이너 수정 작업
실패했을 때, 뒤로가기를 누르거나 홈 버튼을 누르지 않고 원래 페이지로 돌아가는 UI를 추가해주고 싶어졌다.
돌아가기 버튼을 추가해 보자.
report.html로 돌아가서,
실패했을 경우니까 else 조건 맨 아래에 <a href> 문을 추가해 준다. bootstrap의 버튼을 활용한다.
{% extends "base.html"%}
{% block content %}
<div class="jumbotron">
{% if report %}
<h1>환영합니다 {{userid}}! 가입 성공이에요 </h1>
{% else %}
<h1>아이쿠! 사용자 ID에 다음과 같은 문제가 있어보여요.</h1>
<ul>
{% if not lower %}
<li>소문자가 포함되지 않았어요.</li>
{% endif %}
{% if not upper %}
<li>대문자가 포함되지 않았어요.</li>
{% endif %}
{% if not num_end %}
<li>숫자가 포함되지 않았어요.</li>
{% endif %}
</ul>
<a class = "btn btn-primary" href="{{url_for('index')}}">돌아가기</a>
{% endif %}
</div>
{% endblock %}
수정 후 저장하고 새로고침을 하면
“돌아가기” 버튼이 추가되었다!
마무리
이 포스팅을 작성하면서 파이썬 코드를 웹에서 어떤식으로 작동하는지 알아보았다.
필자가 이번 연습을 통해 느낀 점을 정리 해 본다.
- Flask는 정말 간편하게 코드 몇 줄만으로 내 웹페이지를 띄울 수 있었다.
- 기존 html, css, javascript 개발 방식보다 python에 집중할 수 있어 오히려 심플하게 느껴졌다.
- Python을 할 줄 알고 HTML 기초 상식만 있다면, 얼마든지 웹페이지를 만들 수 있다.
- bootstrap을 활용하면 단어 몇개 추가하는 것만으로 어느정도 깔끔한 웹페이지 디자인을 구현할 수 있다.
- Flask의 작동원리에 대한 이해가 필요하고, 이를 위해 어느정도 스터디와 실습이 필요하다.
자 이렇게 python의 flask 를 활용하여 웹페이지를 띄우고 간단한 python 코드를 실행할 수 있는 코드를 짜보았습니다.
도움이 되셨길 바라며 오늘은 여기서 마칩니다!!
Flask 관련 책을 보려고 서점에 왔습니다.
여러 책을 살펴보고 있는데 "파이썬 웹 프로그래밍 - 플라스크를 이용한 쉽고 빠른 웹개발" 이라는 책이 내용이 매우 알차고 미니 트위터 같은 아주 간단한 연습과 포토로그라는 꽤 복잡한 웹사이트를 만드는 연습을 해 볼 수 있는 내용이 있네요!