python FLASK, JINJA관련 정리, HTML 연동(feat.route, blueprint, block)

David's Data Science·2021년 9월 29일
0
post-thumbnail

FLASK

APP을 만들기 위한 Framework. Django는 조금 무거운 편이나, FLASK는 정말 뼈대만 있는 느낌의 Framework이기 때문에 보다 유연하게 코드를 넣고 뺄 수 있으며, 가볍고 작은 용량으로 사용하기 좋다. 가볍고 뼈대만 제공한다고 하여 Micro Framework라고 한다.

콘다 가상환경(python)에서 pip install flask로 설치할 수 있다.

Framework: 어떠한 목적을 위해서 사용될 도구들이 모여있는 '틀'이라고 볼 수 있다. flask의 경우 APP을 만들 때 사용하는 도구의 모음이기에 framework라고 한다.
라우트(route): @(decorator)와 함께 사용하여 서버로의 요청을 진행시킬 URI를 지정하고, 아래 정의된 함수의 결과를 웹 브라우저로 반환하는 역할을 한다.



FLASK로 LOCAL APP 작성해보기

글은 APP(애플리케이션)이라고 써놨지만, 그저 로컬에서만 보이는 웹 페이지를 작성하는 것처럼 보일 수 있다. 하지만 이 작업이 Frontend의 시작이고, 더 나아가 서버구축을 하면서 Backend까지 진행하게 된다.


1. flask_app 폴더, __init__.py 생성하기

flask로 app을 실행하기 위해선 flask_app을 실행할 폴더 상위폴더에서 진행을 해야하며, flask_app 폴더 내에 __init__.py 파일이 생성되어 있어야 한다.

1) flask_sample 폴더 생성
2) flask_app 폴더 생성
3) __init__.py 파일 생성


2. 기본 화면 index 정의하기 ('/') in localhost

# flask 패키지 import하기
from flask import Flask

# Flask 객체를 생성(__name__ 은 flask_app을 의미)
app = Flask(__name__)

@app.route('/') # URL 끝에 /만 있는 기본 페이지를 정의
def index():
    return "hello", 200     # 웹페이지에 "hello"출력, 응답코드는 200(정상)

# init파일에서의 __name__이 __main__으로 반환이 되면 app을 실행
if __name__=='__main__':
    app.run(debug=True) # debug는 옵션사항
   

위와 같이 Flask를 이용해 로컬호스트의 :5000 port로 들어가면 의도했던대로 "hello"를 웹페이지 상에 출력하는 것을 볼 수 있다.


3. 라우트(route)와 end point를 이용한 URL 지정

@app.route('/user/<username>')    # URL 끝에 /user/기재했을 때의 정의
def name_print(username):
    return f"hello {username}", 200  # number를 웹페이지에 출력

end point는 라우트에 기재된 <<username>>과 같이 꺽새로 표기하고 그에 할당하는 함수에 해당하는 ene point를 parameter로 두어 작성한다. name_print라는 함수를 정의 해준 뒤, hello 뒤에 출력되도록 했고, 문제없이 원하는 내용이 출력되는 것을 볼 수 있다.


4. 블루 프린트(Blueprint)를 이용해 라우트 정리 및 호출

블루프린트의 사용 이유

페이지 이동에 따라 여러가지 페이지를 만들다 보면 라우트가 많아__init__.py 파일 내에 코드가 너무 많아지게 되는데, 이를 방지하고자, route 별로 따로 python 파일을 작성하여 이를 blueprint로 호출한다.


블루프린트의 사용 방법

1) routes 폴더를 따로 생성 (template과 같이 필수는 아니지만, 관리차원에서 폴더링하면 좋다)

2) 해당 route용 py파일 생성

# welcome_route.py
from flask import Blueprint		# 블루프린트 패키지 import

# 라우트 네임 = welcome, 실행파일명 = __name__, 적용 url = /welcome
bp = Blueprint('welcome', __name__, url_prefix = '/welcome')

@bp.route('/')
def naming():
    return "hello, welcome to David's web"

3) 해당 블루프린트 import 및 register_blueprint(블루프린트명)

# flask 패키지 import하기
from flask import Flask, render_template
from flask_app.routes.welcome_route import bp

# Flask 객체를 생성(__name__ 은 flask_app을 의미)
app = Flask(__name__)

app.register_blueprint(bp)

@app.route('/') # URL 끝에 /만 있는 기본 페이지를 정의
def index():
    return render_template('html_sample.html')    


if __name__=='__main__':
    app.run(debug=True) # debug는 옵션사항


블루프린트를 이용해 welcome이라는 route 설정이 추가적용 된 것을 확인할 수 있다.



5. 렌더링(render template)를 이용해 html 페이지에 입력하기

html를 flask에 연동 시에, 모든 html 코드를 init파일에 넣을 수도 있지만, 제대로된 관리가 힘들고 코드가 너무 길어져서 작업이 불편해질 수 있다. 이런 부분을 개선하는 것으로 렌더링 방법을 들 수 있다. render_template 패키지를 이용해 다른 폴더의 html과 연동하며, init파일에는 호출만 하는 방식이다.

1) flask_app 폴더 내에 templates 폴더를 생성한다. html 파일이 반드시 이 폴더안에 있어야 동작한다.

2) html 파일을 새로 작성한다. 간단히 body 부분에 내용을 기재해본다.

<!-- html_sample.html -->

<head></head>
    <body>
        안녕하세요, David's Web에 오신 것을 환영합니다. 
    </body>

3) render_template 패키지를 이용해 html파일과 __init__.py가 연결되도록 한다.

from flask import Flask, render_template

# Flask 객체를 생성(__name__ 은 flask_app을 의미)
app = Flask(__name__)

@app.route('/') # URL 끝에 /만 있는 기본 페이지를 정의
def index():
    return render_template('html_sample.html') 

이후 기본 page에서 잘 출력되는 것을 볼 수 있다.






Jinja2를 이용한 flask app

진자(Jinja)는 웹 템플릿 엔진으로 맞춤형 웹 페이지를 만들 수 있도록 돕는 도구.
{}를 이용해 html파일을 일일히 수정하거나, 같은 내용을 중복하지 않도록 코드의 효율을 높인다.
flask 설치 시 jinja2가 자동 설치되기 때문에 추가적인 설치를 필요로하지 않는다.

1. flask에서의 변수 넘기기

1) html에서의 변수 설정

<!-- html_sample.html -->

<head></head>
    <body>
        안녕하세요, David's Web에 오신 것을 환영합니다. 
    </body>
    {{greating}}

기존 html_sample.html 파일에서 body 아랫부분에 greating이란 변수를 추가한다. jinja의 변수 처리는 {}를 이용해서 하기 때문에 {{greating}}으로 기재 해둔다.

2) __init__.py에서의 jinja 변수 파라미터로 인자값 정의

@app.route('/') # URL 끝에 /만 있는 기본 페이지를 정의
def index():
    return render_template('html_sample.html', greating = '다시한번 환영합니다.') 


init 파일에서 기본 index함수의 render_template에 greating의 값을 설정해준 뒤, 실행하면 위와같이 해당 위치의 변수에 정의 해둔 값이 들어간 것을 볼 수 있다.



2. Jinja를 이용한 상속 (extends 이용)

진자를 이용하는 이유 중 하나로는 반복해서 코드를 기재하지 않아도 되기 때문이다. 상속을 이용하면 긴 html 코드를 다시 입력할 필요 없이 기존에 있던 html파일을 부모파일로 두어, 자식 파일을 생성하면서 효율을 높일 수 있다.

@app.route('/sample2') # URL sample2일 경우 아래 html연결
def sample2():
    return render_template('html_sample2.html') 


html_sample2.html파일을 생성하여 extends함수를 통해 html_sample.html을 그대로 가져왔다. url 끝에 sample2를 기재해도 상속을 했던 부모 html인 html_sample.html을 가져온것과 동일한 결과를 반환한다.



3. Jinja block을 이용해 내용 추가하기

block을 이용하여 상속한 내용에 더해 원하는 위치에 내용을 추가할 수 있다.
{% block 블록명 %}으로 블록을 열고{% endblock %}으로 블록을 닫는다. 아래 간단한 예시를 들어본다.

1) 부모 html의 원하는 위치에 block 열고 닫기

<!-- html_sample.html -->

<head></head>
    <body>
        안녕하세요, {% block body %}{% endblock %}David's Web에 오신 것을 환영합니다.   
    </body>

body 태그의 안녕하세요, 뒤에 body라는 이름의 block을 열고 바로 닫아 주었다.

2) 상속된 자식 html에 해당 블록을 열고 내용 기재후 닫기

<!-- html_sample2.html -->
{% extends 'html_sample.html' %}

{% block body %} 멋쟁이 {% endblock %}


html_sample2.html에서 상속 이후body 블록을 연 뒤, '멋쟁이'라고 기재 후 실행하니 정확히 해당 위치에 원하는 코멘트가 추가된 것을 볼 수 있다.



4. Jinja if문

진자를 통해서 if구문도 사용이 가능하다. 조건 문을 기재한 뒤 True일 경우 하위 내용을 적용시킨다

<!-- html_sample.html -->

<head></head>
    <body>
        안녕하세요, 
        {% if True %}
        <h1>멋쟁이</h1>
        {% endif %}
        David's Web에 오신 것을 환영합니다.   
    </body>

위 예시에서 바로 if True를 적용시켜서 실행하면 위와같이 나오는 것을 알 수 있다.
이는 기본 python if구문과 같이 elif, else로 조건문을 추가할 수 있다.



5. Jinja for문

for구문을 통해 순환을 이용하면 list 내의 요소를 나열하게 된다.

<!-- html_sample.html -->


<head></head>
    <body>
        안녕하세요, 
        {% for i in range(0,3) %}
        <h1>멋쟁이{{i}}</h1>
        {% endfor %}
        David's Web에 오신 것을 환영합니다.   
    </body>

for 구문을 통해 i의 내용을 순차적으로 출력했다.

for를 이용해 loop를 이용하게 되면 반복문에서의 정보를 추가적으로 얻을 수 있다.
loop.index / loop.index0 / loop.first / loop.last 등이 있다.

profile
데이터 사이언티스트가 되고싶은 David입니다.

0개의 댓글