*Flask
- Python으로 구동되는 웹 프레임워크, 내가 만든 프로그램에 서버를 구동시켜주는 편한 코드 모음
- 파이썬의 다른 프레임워크인 Django보다 가벼움
- 서버 스케일이 작은 것부터 큰 것까지 만들 수 있다.
- 라이트한 특성 때문에 간단한 API서버 구축에 적합
*MVC 패턴 구조
- Model , View , Controller 의 합성어로 소프트웨어 공학에서 사용되는 소프트웨어 디자인 패턴입니다.
- Model : 백그라운드에서 동작하는 로직을 처리합니다.
- View : 사용자가 보게 될 결과 화면을 출력합니다.
- Controller : 사용자의 입력 처리와 흐름 제어를 담당합니다.
*프로젝트 구조 만들기
app-static-css
-img
-js
app-templates
app-routes.py
app-README.md
1. 도메인의 root url /로 접속한다면 홈페이지로 이동
2. routes.py는 url / 에서 python flask를 실행
3. flask는 templates/ 폴더 안의 템플릿을 찾는다.
4. 템플릿은 static/ 폴더 안에서 HTML 페이지를 표시하기 위한 image 파일, CSS, java script 파일을 찾는다.
5. 생성된 HTML 페이지는 routes.py로 다시 보내짐
6. routes.py가 브라우저에 HTML을 보낸다.
사용자가 주소창에 URL을 타이핑하면, python flask 코드가 포함된 routes.py를 실행하게 됨
flask는 templates/ 폴더에서 템플릿을 찾고 HTML 페이지를 만들어 다시 브라우저로 보냄
flask는 database에서 내용을 가져다 템플릿에 넘겨줄 수도 있다.
웹 템플릿이 하는 일 = 반복적인 HTML문을 작성하는 것보다 하나의 페이지 layout을 정해 놓고, 필요할 때마다 내용을 집어 넣는 역할
웹 템플릿은 단순히 text 파일이지만, 변수와 제어문을 포함하고 .html 또는 .xml 확장명을 가짐
웹 템플릿이 사용될 때마다 변수들은 내용에 따라서 변경됨
웹 템플릿은 반복적인 일을 없애고, 내용을 디자인으로부터 분리해서 앱을 관리하기 쉽게 만들어 줌
flask는 jinja2 템플릿 엔진을 사용함
1. HTML 문서의 뼈대로 사용될 layout.html 파일을 만들어 templates/ 폴더에 넣는다.
2. app/templates/layout.html
3. {% block content %} {% endblock %}
4. app/templates/home.html
4-1. app/templates/home.html 안에 {% extends "layout.html" %}
5. layout.html에는 content라고 불리는 자식 템플릿이 들어가는 블럭이 정의되어 있음
6. home.html 파일은 layout.html 의 자식 템플릿으로 여러가지 특징을 상속받음
7. app/routes.py
8. flask class와 함수 render_template을 가져옴
9. URL / 에 함수 home()을 mapping : "template/" 폴더에서 home.html을 렌더링하여 브라우저로 보냄
10. run() 을 사용하여 로컬 서버에 app을 실행, debug 모드를 true로 설정했기 때문에 우리가 뭔가 잘못하는 경우 해당 오류 메시지를 볼 수 있음
11. python routes.py
12. http://localhost:5000/ 에 접속하면 routes.py 에 파이썬 함수 home() 이 실행됨
13. home() 은 서식 파일에 있는 웹 템플릿 home.html을 렌더링하고 그것을 우리의 브라우저 상에서 보여줌
14. CSS코드를 추가해 꾸며주기
15. static/css/main.css
16. <link rel="stylesheet" href="{ { url_for('static', filename='css/main.css') } }">
17. flask의 함수 url_for 을 사용해 static 폴더의 main.css 파일의 URL주소를 생성
18. 웹 템플릿 about.html을 만들어 templates/ 폴더에 넣는다.
19. @app.route('/about')
def about():
return render_template('about.html')
20. 네비게이션 : 대부분 웹사이트에 header에 메인페이지로 돌아가는 링크가 있음
21. layout.html 에 <nav> element를 추가
@app.route('/')
: URL의 / 경로를 요청하면, 하위에 기재된 코드를 실행(라우팅)
if __name__ == "__main__"
: 모듈을 import해서 사용하는 경우인지 직접 실행한 경우인지를 구분하기 위한 것
1. flaskr/flaskr 의 형태
2. flaskr/flaskr/schema.sql 파일을 생성, 블로그에서 사용할 간단한 테이블
3. Alembic 같은 migration 도구, drop 테이블 = migration 도구와 비슷하게 사용하려는 것으로 보임
4. flaskr/flaskr/flaskr.py 파일 생성
5. app.config.update()
6. app.root_path는 Flask Application 객체에 있는 속성인데, 문서를 보면 자동으로 application root 경로로 잡힌다.
7. flaskr/flaskr/flaskr.py 파일이 있는 /Users/outsider/flaskr/flaskr/ 가 이 값이 되고, flaskr.db와 연결
8. 보통 한 프로세스에서 여러 application을 띄울 수 있으므로 app.root_path를 사용한다.
9. 실제 application에서는 Instance Folder를 추천함
10. 인스턴스 폴더는 Flask application을 생성할 때, app=Flask(__name__, instance_path='/path/to/instance/folder') 처럼 지정할 수 있음
11. app.root_path 는 패키징되지 않은 경우에만 잘 동작함
12. Flask처럼 web application을 작성하는 상황에서 Flask application을 다른 곳에서 불러다 사용하는 경우, root_path는 패키지의 루트 경로가 될 것이므로, 불러올 구성 파일 같은 경우도 패키지에 포함되어야 함
13. 설정 파일 분리, 보통은 .ini 나 .py 파일로 분리한 뒤 가져와서 사용함
14. 환경변수에서 가져오는 방법, app.config.from_envvar('FLASKR_SETTINGS', silent=True)를 사용하면 FLASKR_SETTINGS 라는 환경변수의 경로에 있는 파일에서 값을 가져와서 Config 객체에 설정할 수 있다.
15. config.cfg를 만들고, FLASKR_SETTINGs=/Users/outsider/flaskr/config.cfg 환경 변수를 지정하면 Config 객체에 내용이 들어감. silent = True 를 하면 해당 환경변수가 없어도 오류가 나지 않음
16. json 사용하고 싶으면, app.config.from_json(os.environ['FLASKR_SETTINGS'], silent=True) 처럼 사용 가능
17. flaskr/flaskr/flaskr.py 파일에 DB접속에 사용한 함수를 추가
긴 HTML 코드 블럭을 application 코드 내에 삽입한다는 것은 가독성이 너무 떨어짐. 그래서 사용자에게 보여질 부분(HTML)과 실제로 처리하는 부분(application 코드)을 구조적으로 나눈다.
Flask에서는 보여지는 부분과 처리하는 부분으 나누기 위해 템플릿이라는 기능을 제공
템플릿에 사용되는 파일 : 'templates' 디렉터리에 저장, 일반적으로 html파일을 사용
css같은 파일 : 'static' 디렉터리에 저장
application 상에서 이러한 html 파일들을 랜더링할 수 있도록 Flask에서는 'render_template'을 제공
Jinja2 템플릿 엔진을 사용해서 html 문서 내에 코드 조각들을 삽입하여 웹페이지를 동적으로 생성할 수 있음
Flask 템플릿의 강력한 기능 : 계층 구조를 지원
사이트에서 사용되는 동일한 구성요소는 'layout.html' 파일에 넣어두고, 나머지 페이지들은 이를 상속 받아서 사용
{% extends 'layout.html' %}
{% block content %}
{% endblock %}
템플릿 디렉터리 하위에 'layout.html' 파일을 만듬
Jinja2 템플릿 엔진은 구문의 경우 {% %}로, 표현은 '{{}}', 주석은 '{# #}'
Jinja2 조건문
{% if "조건문1" %}
조건문1이 참인 경우 실행되는 문장
{% elif "조건문2" %}
조건문2이 참인 경우 실행되는 문장
{% else %}
조건식이 만족하지 않은 경우 실행되는 문장
{% endif %}
템플릿에 parameter를 전달하려면 'render_template' 함수에 템플릿에 정의된 변수 이름과 동일한 이름을 넘겨주면 됨
def about():
return render_template('about.html', title='About')
def index():
return render_template('index.html', posts=posts)
index.html 내에서
<div>
<div>
<article>
<h1> </h1>
<p> </p>
<div>
<p> </p>
<p> </p>
</div>
</article>
</div>
</div>
*URL 동적 생성
flask에서는 'url_for'라는 함수로 지원
'url_for' 함수는 endpoint 함수명을 인자로 받음
'url_for('index')'
'url_for('about')' : '/about' 주소를 생성하고 싶다면
'url_for('static', filename=<파일 이름>)' : 'url_for' 함수로 'static' 폴더 내에 있는 리소스의 주소를 생성
app.run(debug=True) : 서버 실행(디버그 모드 True)
*Flask -File upload
■upload.html
<form action = 'http://localhost:5000/fileUpload" method="POST" enctype="multipart/form-data">
<input type="file" name="file"/>
<input type="submit"/>
</form>
■flask_upload.py
@app.route('/upload')
def render_file():
return render_template('upload.html')
=> 브라우저 주소창에 /upload 요청 시에 upload.html 랜더링 하는 함수 선언
=> upload.html 에서 form submit 할 때, request된 파일 데이터를 처리하는 함수
<form> 태그의 속성
- method : 전송 방식
- action : 전송 목적지
- enctype : 전송되는 데이터 형식
enctype 속성
- application/www-form-urlencoded : form data는 서버로 전송되기 전에 URL-Encode 한다
- multipart/form-data : 파일이나 이미지를 서버로 전송할 경우 사용, method는 post로 지정
(enctype이 있으면 type=file인 input은 file 데이터를 request에 담는다.)
- text/plain : 인코딩을 하지 않은 문자 상태로 전송
GET 방식 : URL에 form data가 노출되기 때문에 입력 내용의 길이 제한이 있고, 256~4096byte까지의 데이터를 전송할 수 있음 (URL에 입력한 내용이 노출되기 때문에 보안이 민감한 경우 사용하지 않는다.)
POST 방식 : URL에 노출되지 않고 데이터를 전송하기 때문에, 입력 내용의 길이에 제한을 받지 않음,
파일이나 용량이 큰 데이터를 전송할 때 쓰는 form data 전송방식이 ENCTYPE 속성의 'multipart/form-data'
'스타트업 > 프로그래밍' 카테고리의 다른 글
[프로그래밍] HTTP 통신 (0) | 2020.09.02 |
---|---|
[프로그래밍] HTTP 통신 vs Socket 통신 (0) | 2020.09.02 |
[프로그래밍] Python Network Socket (0) | 2020.09.01 |
[프로그래밍] Flask Streaming (0) | 2020.06.17 |
[프로그래밍] Flask File Upload (0) | 2020.06.17 |