Flask에서 Jinja2 템플릿 사용하기 feat. MUMA

Isabel·2022년 3월 16일
0

첫 주에는 flask에서 ajax로 데이터를 받아와 html을 작성해주는 방식으로 프로젝트를 진행했다.
이번 주에는 일일이 다른 페이지를 html에서 작성해 주는 것이 아니고 jinja2 템플릿을 사용하여 서버에서 template을 렌더링하여 데이터만 다른 일관된 구조를 가진 페이지를 만들고자 한다.

Jinja2

Jinja2는 Flask에서 제공하는 웹 프레임워크로, python으로 html 코드를 제어할 수 있다. 템플릿을 사용하면 반복문, 조건문, 변수 등을 활용하여 비교적 간단한 표현을 통해 데이터를 가공하여 웹페이지를 만들 수 있다.

jinja2는 서버에서 클라이언트로 보내준 데이터를 화면에 보여줄 때 사용하는 툴이다. 서버에서 클라이언트로 데이터를 보내주기위해서는 클라이언트에서 ajax를 통해서 서버에 데이터를 보내달라고 요청을 해야만 데이터 송수신이 가능하다.

그래서 ajax를 사용해서 서버에 요청을 보내지 않으면 서버가 클라이언트로 데이터를 보낼 수 없다.

서버 사이드 렌더링 SSR

서버 사이드 렌더링이란 서버에서 페이지를 그려서 클라이언트로 보내 화면에 표시하는 기법이다. 서버 사이드 렌더링을 사용하면 얻는 장점은 크게 검색 엔진 최적화빠른 페이지 렌더링이다. 검색 엔진 최적화란 구글, 네이버와 같은 검색 엔진에서 검색했을 때 결과가 사용자에게 많이 노출될 수 있도록 최적화하는 기법이다. 특히, 링크를 공유했을 때 웹 사이트의 정보를 이미지와 설명으로 표시해주는 OG(Open Graph) Tag를 페이지 별로 다르게 적용하기 위해서는 서버 사이드 렌더링이 효율적이다.

Flask에서 템플릿을 렌더링하여 URL에 연결하기

from flask import Flask, render_template, request, jsonify, redirect, url_for

app = Flask(__name__)

@app.route('/')
def main():

    return render_template("index.html")  # 데이터를 같이 보낼 것이 있으면 ',' 로 연결하여 보내주면 된다

template라는 폴더 안의 index.html을 렌더링하여 클라이언트로 보내준다.(꼭 html파일은 templates라는 폴더에, 이미지와 css파일은 static 폴더에 넣어줘야 한다.)

API의 정보를 렌더링 해주기

@app.route('/') 
def main():
  r = requests.get('http://openapi.seoul.go.kr:8088/6d4d776b466c656533356a4b4b5872/json/RealtimeCityAir/1/99') 
  response = r.json()
  rows = response['RealtimeCityAir']['row']

  return render_template("index.html", rows=rows)

해당 API 주소에 있는 데이터를 requests로 get해온 후, json 형식으로 변형해준다. 이 값을 변수에 담아 렌더링할 때 같이 보내준다.

DB에 있는 정보를 렌더링 해주기

@app.route('/')
def main():
    museums = list(db.muse_info.find({},{"_id":False})) # {"_id":False} id값은 가져오지 않게 함
    return render_template("index.html", museums=museums)
    

DB에 list형식으로 있는 데이터들을 모두 불러와서 words라는 변수에 담아주고 이를 렌더링 할 때에 같이 보내준다.

Jinja2의 문법 기본

변수명

{{ 변수명 }}  or   {{ 변수명 |필터 }}

변수를 담을 때는 {{ }}중괄호 두개를 포개어 사용한다.

<p><span class="info_head">홈페이지</span> : <a href="{{ museum.url }}">{{ museum.url }}</a></p>
<p><span class="info_head">전화번호</span> : {{ museum.phone }}</p>
<p><span class="info_head">영업시간</span> : {{ museum.open }} ~ {{ museum.close }}</p>
<p><span class="info_head">휴무정보</span> : {{ museum.rest_info }}</p>
<p><span class="info_head">주 소</span> : {{ museum.addr }}</p>
<p><a href="javascript:void(0);" id="show_map" class="show_map" onclick="hey_map()">👉 지도로 보기</a></p>
<p class="db-intro">{{ museum.introduce }}</p>

제어문 (if문, for문 등)

{% if ~~ %} 실행문 {% endif %}
{% for ~ %} 실행문 {% endfor %}

ex) jinja2 템플릿으로 if문 사용하기

{% if museum.img_src == none %}
     <img src="/static/museum-art.png" alt="aba"/>
{% else %}
     <img src="/static/{{ museum.img_src }}" alt="aba"/>
{% endif %}

주석 달기

{# 주석을 작성해주세요 #}

하지만 서버사이드 렌더링에도 단점은 있다.

  • 프로젝트의 복잡도
  • 성능 악화 가능성 있음

이러한 이유로 클라이언트 사이드 렌더링이 더 나은지, 다른 방법은 없는지 프로젝트마다 고민해보고 사용을 해야할 것 같다.

reference

0개의 댓글