Backend/Python

Python Flask 웹 페이지 제작(2) - Jinja2 템플릿

땅지원 2021. 12. 21. 20:03

Content

- HTML 렌더링

- 템플릿 렌더링해서 URL에 연결하기

- 템플릿에서 변수 사용하기 

- 템플릿에서 if, for 사용하기

- 템플릿 상속

HTML 렌더링

from flask import Flask

app = Flask(__name__)

@app.route('/')
@app.route('/home')
def home():
    return '''
    <h1>이건 h1 제목</h1>
    <p>이건 p 본문 </p>
    <a href="https://flask.palletsprojects.com">Flask 홈페이지 바로가기</a>
    '''
    
@app.route('/user/<user_name>/<int:user_id>')
def user(user_name, user_id):
    return f'Hello, {user_name}({user_id})!'
    
if __name__ == '__main__':
    app.run(debug=True)

return의 응답들은 텍스트, 데이터 등 다양한 형식이 될 수 있는데 일반적으로 웹 페이지에서 렌더링 할 HTML을 직접 반환하게 될 것이다.

 

템플릿 렌더링해서 URL에 연결하기

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)

위의 html자체를 렌더링 하는 것이 아닌 render_template()을 이용해서 해당 문서를 렌더링해서 반환

 

Jinja2

Flask에서 Jinja2라는 템플릿 엔진을 이용하여 애플리케이션 내 변수와 반복문, 조건문 등을 포함하는 HTML 파일을 렌더링 할 수 있다.

 

템플릿에서 변수 사용하기 (filter 기능 활용)

render_template()을 이용해서 문서를 반환하고 그 템플릿 내에서 변수를 사용하려면 

return render_template("index.html",template_students = student_data)

이와 같이 쉼표로 구분한다. 그리고 템플릿에서는 {{ 변수명 }}으로 값을 불러온다.

 

템플릿에서 if, for 사용하기

#if 조건문

{% if template_variable < 20 %}
  <p>{{ template_variable }}은 20보다 작다.</p> 
{% elif template_variable > 20 %}
   <p>{{ template_variable }}은 20보다 크다.</p> 
{% else %}
   <p>{{ template_variable }}은 20이다.</p> 
{% endif %}
#for 반복문

<ul>
{% for x in range(10) %}
    <li>{{ x }}</li>
{% endfor%}
</ul>
# dictsort 필터를 사용하고 싶을 땐 

<ul>
{% for key, value in template_dict | dictsort %}
    <li>{{ key }} : {{ value  }}</li>
{% endfor%}
</ul>

 

템플릿 상속 (Inheritance)

웹 사이트 레이아웃의 일관성(Consistency) 유지 및 header와 footer를 여러곳에 사용하기 위해서는

템플릿 상속 기능 사용 

 

● 부모문서를 만들고, 자식문서가 들어갈 부분에 {% block content %}, {% endblock %}.

● 자식문서 윗부분에 {% extends 부모문서이름 %}라고 명시한 후 {% block content %}와 % endblock %}사이에 내용을 작성한다.

# run.py

from flask import Flask, render_template

app = Flask(__name__)

student_data = {
    1: {"name": "슈퍼맨", "score": {"국어": 90, "수학": 65}},
    2: {"name": "배트맨", "score": {"국어": 75, "영어": 80, "수학": 75}}
}

@app.route('/')
def index():
    return render_template("index.html", 
            template_students = student_data)
            
@app.route("/student/<int:id>")
def student(id):
    return render_template("student.html", 
            template_name=student_data[id]["name"], 
            template_score=student_data[id]["score"])
            
if __name__ == '__main__':
    app.run(debug=True)
return render_template("index.html", template_students = student_data)

자식 html을 호출해야 부모 html까지 포함된 내용을 나타낼 수 있다.

부모 html을 호출하면 부모html의 내용만 나오게 된다.

 

<!--
base.html
부모 html
-->

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>시험성적 확인 사이트</title>
</head>
<body>
    <div>
        <a href="/">메인화면 바로가기</a>
    </div>
    {% block content %}{% endblock %}
</body>
</html>
<!--
index.html
자식 html
->

{% extends "base.html"  %}

{% block content %}
    <h1>시험 성적 확인하기</h1>
    <p>이름을 클릭하세요.</p>
    <ul>
        {% for key, value in template_students | dictsort %}
            <li><a href="/student/{{ key }}">{{ value["name"] }}</a></li>
        {% endfor%}
    </ul>
{% endblock %}
<!--
student.html
자식 html
->

{% extends "base.html"  %}
{% block content %}
    <h2>{{ template_name }} 님의 성적</h2>
    <ul>
        {% for key, value in template_score.items() %}
            <li>{{ key }} : {{ value }}</li>
        {% endfor%}
    </ul>
{% endblock %}