1. Flask 설치 및 설정
$ pip install flask
1-1) 제대로 설치 되었는지 확인하기
# on python
import flask
오류가 발생하지 않으면 제대로 설치된 상태입니다.
1-2) app을 저장할 새로운 디렉터리 생성
# 폴더 생성
$ mkdir Flask_app # Flask_app is your app name
# 파일 생성
$ touch Flask_app.py
1-3) py파일안에 기본적인 Flask 설정
# on Flask_app.py
from flask import Flask # flask에서 Flask 클래스를 추출해옴
app = Flask(__name__) # app 변수를 Flask 클래스의 인스턴스로 설정
# route()데코레이터를 사용하여 Flask에 함수를 트리거해야하는 URL을 알려줍니다.
# route('/') 는 이후의 설정이 Root page (= Home page) 내용임을 알 수 있음
@app.route('/')
def hello_world():
return 'Hello, World!'
@app.route('/') = http://127.0.0.1:5000 (Root page)
@app.route('/page2') = http://127.0.0.1:5000/page2
1-4) 어플리케이션 환경변수 설정 후 플라스크 실행
# on Consol
$ export FLASK_APP=Flask_app.py # 어플리케이션에 환경 변수를 설정
$ flask run # 플라스크 실행
1-5) 결과창 (오류가 없다면 아래와 같은 결과가 나와야 합니다.)
$ flask run
* Serving Flask app "Flask_app.py"
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1:5000에 플라스크 앱을 제공하고, 이것은 로컬 IP주소입니다. (내장서버)
http://127.0.0.1:5000/로 이동하면 hello world 인사말이 표시됩니다.
(VSC의 경우 링크를 클릭하면 바로 이동합니다)
2. 웹 페이지 설정
1-6) 디버그 모드 활성화
# on console
$ export FLASK_DEBUG=1 # 디버그 모드 on, off는 다시 FLASK_DEBUG=0으로 설정
디버그 모드에서는 flask를 재실행할 필요없이 웹 페이지를 새로 고침하면 변경사항이 반영되어 있습니다.
1-7) 명령어를 통한 디버그 모드 활성화
# on Flask_app.py
if __name__ == '__main__':
app.run(debug=True)
if __name__ == '__main__':
__name__은 모듈의 이름이 저장되는 변수이며, import로 모듈을 가져왔을때 모듈의 이름이 들어갑니다.
파이썬 인터프리터로 스크립트 파일을 직접 실행했을때는 모듈의 이름이 아니라 '__main__'이 들어갑니다.
파이썬은 최초로 시작하는 스크립트 파일과 모듈의 차이가 없습니다.
어떤 스크립트 파일이든 시작점이나 모듈이 될 수 있으므로 __name__변수를 통해 현재 스크립트 파일이 시작점인지 모듈인지 판단합니다.
즉, if __name__ == '__main__': 코드를 통해서 현재 스크립트 파일이 프로그램의 시작점이 맞는지 판단하는 것입니다.
# on console
$ python Flask_app.py
위의 내용이 이해가 안된다면
1. python 인터프리터로 Flask_app.py 파일 실행시 ->
2. if __name__ == '__main__': 조건문 안으로 들어와서 app.run(debug=True) 코드를 실행 ->
3. 자동으로 디버그 모드가 활성화 된다라고 이해하면 됩니다.
(만약 다른 파일이나 인터프리터에서 import Flask_app을 실행한다면 조건문이 실행되지 않습니다.)
1-8) flask 실행 중 명령줄을 통해 상태확인
현재 코드상에서 http://127.0.0.1:5000/으로 이동하면 아래와 같은 명령줄이 뜰것이다.
127.0.0.1 - - [23/Mar/2021 00:52:50] "?[37mGET / HTTP/1.1?[0m" 200 -
사용자가 GET 요청을 했고, 200응답을 반환했다. 라는 뜻이다.
현재 코드상에서 http://127.0.0.1:5000/about으로 이동하면 아래와 같은 명령줄이 뜰것이다.
127.0.0.1 - - [23/Mar/2021 00:52:57] "?[33mGET /about HTTP/1.1?[0m" 404 -
사용자가 GET 요청을 했고, 404응답을 반환했다. 라는 뜻인데, 이는 /about 페이지가 없으므로
오류났다는걸 알려주는 응답이다.
간단하게 HTTP상태코드는 아래와 같다. (200은 요청 성공, 404는 찾을 수 없음)
1-9) 경로 설정
새로운 경로를 추가하려면 새로운 라우트를 선언하면 된다.
@app.route('/about')
def about():
return '<h1>About Page</h1>'
이제 http://127.0.0.1:5000/ 페이지와 http://127.0.0.1:5000/about 페이지가 존재한다.
두 가지 경로를 통해 동일한 페이지로 접속하려면
@app.route('/')
@app.route('/home')
def home():
return '<h1>Home Page</h1>'
이제 http://127.0.0.1:5000/ 페이지와 http://127.0.0.1:5000/home 페이지는 똑같이 home()함수를 반환한다.
2. 템플릿
제대로된 페이지를 반환해주려면 함수마다 html을 작성해줘야되는 불편함이 있다.
@app.route('/')
@app.route('/home')
def home():
return """
<!doctype html>
<html>
~~
</html>
"""
이를 해결하고자 템플릿을 사용한다.
2-1) 템플릿 파일 생성
# in Flask_app
$ mkdir templates
# in templates
$ touch home.html
$ touch about.html
Flask_app 폴더 안에 템플릿 폴더를 생성하고, 그 안에 페이지 별 html파일을 생성
@app.route('/')
@app.route('/home')
def home():
return '<h1>Home Page</h1>'
위의 함수와 같은 기능을 하는 html 파일
<!-- on home.html -->
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<h1>Home Page</h1>
</body>
</html>
2-2) html 파일 불러오기
생성한 html 파일을 불러오기 위해서는 render_template 기능을 불러와야됩니다.
# on Flask_app.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
@app.route('/home')
def home():
return render_template('home.html')
이제 /, /home으로 접속된 요청은 모두 home()함수를 사용하여 home.html 로 연결됩니다.
2-3) Jinja
Jinja2 문법은 간단히 아래와 같습니다.
- {{ ... }} : 변수나 표현식
- {% ... %} : if나 for같은 제어문
- {# ... #} : 주석
# on Flask_app.py
from flask import Flask, render_template
app = Flask(__name__)
post1 = [
{
'author': 'Sooho Kim',
'title': 'Blog Post 1',
'content': 'First post content',
'date_posted': 'March 23, 2021'
},
{
'author': 'Jane Doe',
'title': 'Blog Post 2',
'content': 'Second post content',
'date_posted': 'March 25, 2021'
}
]
@app.route('/')
@app.route('/home')
def home():
return render_template('home.html', posts=post1)
post1이라는 데이터를 home page의 인수로 전달하여 posts을 템플릿에 전달할 수 있습니다.
<!--on home.html-->
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
{% for post in post1 %}
<h1>{{ post.title }}</h1>
<p>By {{ post.author }} on {{ post.date_posted }}</p>
<p>{{ post.content }}</p>
{% endfor %}
</body>
</html>
{% for post in post1 %}
{% endfor %}
는 jinja2 문법을 이용한 for문입니다.
2-4) jinja를 통한 웹페이지 제목 바꾸기
<!--on home.html, about.html-->
<head>
{% if title %}
<title>Flask app - {{ title }}</title>
{% else %}
<title>Flask app</title>
{% endif %}
</head>
if문을 사용하여 웹페이지 제목을 변경해줄 수 있습니다.
위와 같이 코드를 적어주면 따로 title을 입력하지 않으면 else로 이동하여 디폴트 title이 반환되고,
title 값을 넣어주면 if title로 이동하게 되어 변경된 title이 반환니다.
@app.route('/')
@app.route('/home')
def home():
return render_template('home.html', posts=post1)
@app.route('/about')
def about():
return render_template('about.html', title='About')
about()에서는 title을 설정해줘서 웹페이지의 제목이 변경되고, home()에서는 디폴트 값으로 나오게 됩니다.
이전까지 코드에 따르면 페이지의 제목을 설정하기 위해선 html 마다 코드를 입력해주어야 합니다.
이를 해결하기위해 템플릿 상속을 해주겠습니다.
2-5) 템플릿 상속
<!--on home.html-->
<!DOCTYPE html>
<html>
<head>
{% if title %}
<title>Flask app - {{ title }}</title>
{% else %}
<title>Flask app</title>
{% endif %}
</head>
<body>
{% for post in post1 %}
<h1>{{ post.title }}</h1>
<p>By {{ post.author }} on {{ post.date_posted }}</p>
<p>{{ post.content }}</p>
{% endfor %}
</body>
</html>
반복되는 head 부분을 웹페이지마다 설정해주는것 대신 하나의 파일에서 조작하기위해 layout.html을 만들어 줍니다.
<!--on layout.html-->
<!DOCTYPE html>
<html>
<head>
{% if title %}
<title>Flask app - {{ title }}</title>
{% else %}
<title>Flask app</title>
{% endif %}
</head>
<body>
<div class="container">
{% block content %}{% endblock %}
</div>
</body>
</html>
{% block content %}{% endblock %} 이 부분은 block을 선언해준건데 layout을 따르는 파일들은
다른부분은 다 동일하고, block만 다르게 설정해주겠다는 의미이다.
편의를 위해 <div class="container"> 안에 블록을 설정했다.
<!--on home.html-->
{% extends "layout.html" %}
{% block content %}
{% for post in posts %}
<h1>{{ post.title }}</h1>
<p>By {{ post.author }} on {{ post.date_posted }}</p>
<p>{{ post.content }}</p>
{% endfor %}
{% endblock content %}
기존의 home.html은 위와같이 설정해주면 layout.html의 확장버전이 되고,
{% block content %}{% endblock %} 만 선언하여 내용을 바꿔주면 된다.
※ {% endblock content %} 에서 content는 쓸모없는 코드지만, 해당 block을 쉽게 알아보기위한 코드이다.
<!DOCTYPE html>
<html>
<head>
{% if title %}
<title>Flask app - {{ title }}</title>
{% else %}
<title>Flask app</title>
{% endif %}
</head>
<body>
<h1>About Page</h1>
</body>
</html>
about.html의 경우엔 아래와 같이 바꿔주면 된다.
{% extends "layout.html" %}
{% block content %}
<h1>About Page</h1>
{% endblock content %}
3. Bootstrap (Extention Flask)
getbootstrap.com/docs/5.0/getting-started/introduction/
Introduction
Get started with Bootstrap, the world’s most popular framework for building responsive, mobile-first sites, with jsDelivr and a template starter page.
getbootstrap.com
웹사이트를 쉽게 꾸밀 수 있는 기능을 하는 부트스트랩입니다.
아래는 CDN을 통해 CSS와 자바스크립트를 지원해줘서 다운로드를 할 필요없이 html 파일에 코드를 넣어주면 웹사이트의 스타일이 바뀌는 코드입니다.
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
<title>Hello, world!</title>
</head>
<body>
<h1>Hello, world!</h1>
<!-- Optional JavaScript; choose one of the two! -->
<!-- Option 1: Bootstrap Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/js/bootstrap.bundle.min.js" integrity="sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf" crossorigin="anonymous"></script>
<!-- Option 2: Separate Popper and Bootstrap JS -->
<!--
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.1/dist/umd/popper.min.js" integrity="sha384-SR1sx49pcuLnqZUnnPwx6FCym0wLsk5JZuNx2bPPENzswTNFaQU1RDvt3wT4gWFG" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/js/bootstrap.min.js" integrity="sha384-j0CNLUeiqtyaRmlzUHCPZ+Gy5fQu0dQ6eZ/xAww941Ai1SxSY+0EQqNXNE6DZiVc" crossorigin="anonymous"></script>
-->
</body>
</html>
이 부트스트랩을 우리의 모든 웹페이지에 적용시키려면 layout.html 파일만 아래와같이 수정해주면 됩니다.
<!-- on layout.html -->
<!DOCTYPE html>
<html>
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
{% if title %}
<title>Flask app - {{ title }}</title>
{% else %}
<title>Flask app</title>
{% endif %}
</head>
<body>
<div class="container">
{% block content %}{% endblock %}
</div>
<!-- Optional JavaScript; choose one of the two! -->
<!-- Option 1: Bootstrap Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/js/bootstrap.bundle.min.js" integrity="sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf" crossorigin="anonymous"></script>
<!-- Option 2: Separate Popper and Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.1/dist/umd/popper.min.js" integrity="sha384-SR1sx49pcuLnqZUnnPwx6FCym0wLsk5JZuNx2bPPENzswTNFaQU1RDvt3wT4gWFG" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/js/bootstrap.min.js" integrity="sha384-j0CNLUeiqtyaRmlzUHCPZ+Gy5fQu0dQ6eZ/xAww941Ai1SxSY+0EQqNXNE6DZiVc" crossorigin="anonymous"></script>
</body>
</html>
하지만 CSS와 Javascript를 이용하는 방법도 간단합니다.
main.css 파일을 넣어준다고 가정하겠습니다.
1. app이 있는 폴더에 static 폴더를 만듭니다. (mkdir static)
2. 그 안에 CSS파일과 Javascript파일을 넣습니다. (touch ~~~~.css)
3. 넣은 파일을 인식하기 위해 html 파일안에 코드를 작성합니다.
# on Flask_app.py
from flask import Flask, render_template, url_for
url_for 함수를 사용하기위해 import 해준 후
<!-- on layout.html -->
<head>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='main.css') }}">
</head>
메인 html 파일인 layout.html에서 위 코드를 기입하면 됩니다.
새로운 stylesheet를 작성하고, 타입은 css파일이며, 파일이 위치한 url은 static 디렉토리이며, 파일이름은 main.css라는 뜻입니다.
'데이터 분석 > Flask' 카테고리의 다른 글
JSON (JavaScript Object Notation) (0) | 2021.03.30 |
---|---|
Flask - 패키지 구조화 (0) | 2021.03.27 |
Flask - SQLAlchemy(ORM) (0) | 2021.03.27 |
HTTP (0) | 2021.03.26 |
Flask - 2. Forms and User Input (0) | 2021.03.25 |