Flask Web Development 제3장 독서 노트 템플릿

19843 단어

제3장 템플릿


순서


왜 헤어져


유지보수하기 쉬운 코드는 간단한 구조를 유지하는 것이 관건이다.우리가 전에 쓴 Hello.py는 간단하지만 두 가지 다른 부분을 혼합했다. 그것이 바로 페이지 데이터를 어떻게 생성하고 어떻게 표시하는가이다.이 두 부분을 혼합하면 복잡성을 가져올 수 있다.
주의hello.py return '

Hello, world

'.첫 번째 부분은 데이터 생성: Hello,world 생성, 두 번째 부분은 어떻게 표시됩니까?

일급 표제.

템플릿이 필요한 이유


이별 후 우리는 Hello, World!이런 html 페이지는 단독으로 저장한다.이렇게 하면 사용자가 웹 주소를 열 때 서버는 즉시 대응하는 html 페이지를 그에게 발송한다.그러나 일이 이렇게 간단했으면 좋겠다. 많은 html 페이지의 물건은 고정불변한 것이 아니다.우리는 페이지의 일부분을 동적으로 변화시킬 수 있는 기술이 필요하다. 그것이 바로 렌더링이다.Flask는 템플릿을 렌더링하기 위해 Jinja2를 사용합니다.

3.1 Jinja2 템플릿 엔진


순서


간단한 정적 템플릿:templates/index.html

Hello world!


동적 부분 추가 형식:templates/user.html

Hello ,{{ name }}!


첫 번째 템플릿은 Jinja2 없이도 지원할 수 있는 정적 템플릿입니다.진자2는 두 번째 템플릿의 동적 부분과 같은 동적 부분을 교체한다.이때 html로 직접 해석하면 오류가 발생할 수 있으며 진자2와 유사한 템플릿 엔진이 있어야 합니다.
프로그램을 간소화하기 위해서, Flask 프로그램에서 Jinja2를 호출하는 것을 표시할 필요가 없습니다.

3.1.1 렌더링 템플릿


템플릿 사용 방법


Flask 프로그램에서render 호출template 함수를 사용한 후 템플릿을 사용했습니다.
   3-3 hello.py:       
from flask import Flask, render_template
 
# ...
  
@app.route('/')
def index():
    return render_template('index.html')
  
@app.route('/user/')
def user(name):
    return render_template('user.html', name=name)

템플릿 매개 변수 및 검색 경로


예3-3에서rendertemplate에는 두 개의 인자가 있습니다.
첫 번째는 템플릿 파일 이름으로 html로 끝나며 기본적으로 프로그램/templates 폴더에서 검색됩니다.처음에 우리가 Flask류의 매개 변수(__name__)의 작용을 말한 것을 기억하십니까?
두 번째는 동적 매개 변수의 값입니다. 예를 들어name=name: 앞의 name는 템플릿의 {{{{{name}}} (순서의 두 번째 파일 참조), 즉 템플릿의 동적 부분입니다.다음name는 동적 부분에서 페이지에 표시할 값입니다. 함수user의 매개 변수입니다. 템플릿에 렌더링됩니다.

3.1.2 변수


변수란?


템플릿에 사용되는 두 개의 괄호 패키지의 {{name}} 는 변수를 표시합니다. 이 변수의 값은 Flask 프로그램에서 제공합니다. (렌더링)Jinja2는python의 모든 종류의 변수를 식별할 수 있습니다. 예를 들어 목록, 사전, 대상 등입니다.
템플릿에서 변수를 사용하는 몇 가지 예:

: {{ mydict['key'] }}.

#

html , (paragraph)

: {{ mylist[3] }}.

, : {{ mylist[myintvar] }}.

: {{ myobj.somemethod() }}.


필터


때때로 안전을 고려하거나 변수를 형식적으로 변경할 때 필터를 사용해야 한다.예를 들어 변수name의 값을 알파벳 대문자로 표시합니다: Hello, {{ name|capitalize }} 필터를 사용하고 변수 이름 뒤에 세로줄과 필터 이름을 붙이면 됩니다.

일반 필터

capitalize  #            ,         
safe  #        
lower  #          
upper  #          
title  #                  
trim  #          
striptags  #            HTML      

스페셜 세이프 필터


기본적으로 Jinja2는 보안상의 이유로 모든 변수를 이스케이프합니다.예를 들어 변수의 값이 '

Hello

'라면 Jinja2는 이를 '

Hello h1>'

로 렌더링하고 브라우저는 이 h1 요소를 표시할 수 있으나 설명을 하지 않는다.변수에 저장된 HTML 코드를 표시해야 하는 경우가 많은데, 이때safe 필터를 사용할 수 있다.
사용자가 폼에 입력한 텍스트와 같은 신뢰할 수 없는 값에safe 필터를 사용하지 마십시오.전체 필터 목록은 Jinja2 문서에서 볼 수 있습니다.

3.1.3 제어 구조


if 조건 제어

{% if user %}
    Hello, {{ user }}!
{% else %}
    Hello, Stranger!
{% endif %}

제어문은 {% 키워드%}로 시작합니다. 끝문인 endif가 있음을 주의하십시오.

for 순환


흔히 볼 수 있는 요구 사항은 템플릿에 요소를 렌더링하는 것입니다.
    {% for comment in comments %}
  • {{ comment }}
  • {% endfor %}

같은 endfor가 있습니다. Jinja2의 끝 키워드는 end+시작 키워드입니다. 중간에 빈칸이 없습니다.
  • 에서 목록을 정의하는 항목은 무질서 목록과 질서 목록에서 사용할 수 있다.

  • 웅대하다


    매크로는 다음과 같은 함수와 유사합니다.
    {% macro render(w) %}
        
  • {{ w }}
  • {% endmacro %}
      {% for w in word %} {{ render(w) }} {% endfor %}

    두 번째 for 순환 중의render는 앞에서 정의한 매크로입니다. 서열word의 모든 항목을 렌더링하는 역할을 합니다.
    매크로를 재사용하기 위해 별도의 파일에 저장한 다음 필요한 템플릿에서 가져올 수 있습니다.예를 들어 우리는 약간의 매크로를 Macros에 저장한다.html 이후python 패키지와 유사한 형식으로 가져올 수 있습니다.
    {% import 'macros.html' as macros %}
    
      {% for w in word %} {{ macros.render(w) }} {% endfor %}

    템플릿 상속


    한 가지 방법은include:템플릿을 사용하여 삽입하는 것입니다.여러 곳에서 재사용해야 하는 템플릿 코드 세그먼트는 템플릿의 한 위치에 포함하여 별도의 파일을 쓸 수 있습니다. {% include 'common.html' %}다른 하나는 extends: 템플릿 계승을 사용합니다.이것은 Python 코드의 클래스 계승과 유사하여 더욱 강한 기능을 가지고 있다.우선 베이스라는 이름을 만듭니다.html의 기본 템플릿:
    
        {% block head %}
        {% block title %}{% endblock %} - My Application
        {% endblock %}
    
    

    베이스를 사용합니다.html의 템플릿을 하위 템플릿이라고 하고,base는 부모 템플릿입니다.하위 템플릿은 Block 요소를 수정할 수 있습니다.
    {% extends "base.html" %}
    {% block title %}Index{% endblock %}
    {% block head %}
        {{ super() }}
       
    {% endblock %}
    

    extends 성명 서브 템플릿은base에서 계승됩니다.html, extends는 반드시 첫 줄에 두어야 한다.하위 템플릿이 베이스를 다시 정의했습니다.html의 2개의 Block, 하위 템플릿의 Block에 부모 템플릿의 내용을 포함하려면 {{{super()}}}}을 사용하면 Block에 대응하는 내용을 얻을 수 있습니다.
    이런 방식은include와 다르다. include가 쓴 부분은 수정하지 않고 간단하게 삽입되며, 최종적으로include를 호출한 템플릿으로 렌더링된다.extends 계승은base입니다.html에서 확장 수정을 하고 최종적으로 extends가 있는 템플릿에 렌더링을 합니다.

    3.2 Flask-Bootstrap


    Bootstrap이 뭐예요?


    Bootstrap은 트위터가 개발한 소스 프레임워크로 아름다운 웹 외관을 신속하게 개발할 수 있다.그것은 모든 현대 웹 브라우저를 호환할 뿐만 아니라, 코드 하나로 휴대전화, 컴퓨터, 태블릿PC의 조회를 지원할 수 있다.
    Bootstrap은 클라이언트 프레임워크이기 때문에 서버와 직접 관련이 없습니다.서버에 필요한 것은 Bootstrap과 JavaScript를 사용한 코드만 제공하고, 이 코드에서 필요한 구성 요소를 실례화합니다.이러한 작업의 가장 이상적인 실행 장소는 바로 템플릿이다.

    Flask-Bootstrap이 필요한 이유


    프로그램에서 Bootstrap을 사용하려면 원래 템플릿이 필요한 변경을 해야 합니다.하지만 이 같은 변화를 간소화하기 위해 Flask-Bootstrap을 개발한 사람이 있다.

    Flask-Bootstrap 설치 방법


    Flask-Bootstrap은 pip를 사용하여 설치합니다: (venv) $ pip install flask-bootstrap Flask-Script와 유사하며 Flask 확장은 일반적으로 프로그램의 실례를 만들 때 초기화됩니다.다음은 Flask-Bootstrap을 초기화하는 방법입니다.
    from flask_bootstrap import Bootstrap
    # ...
    bootstrap = Bootstrap(app)
    

    Flask-Bootstrap을 초기화하면 모든 Bootstrap 파일을 포함하는 기본 템플릿을 프로그램에서 사용할 수 있습니다.이 템플릿은 Jinja2의 템플릿 계승 메커니즘을 이용하여 프로그램이 기본적인 페이지 구조를 가진 기본 템플릿을 확장하는데 그 중에서Bootstrap을 도입하는 요소가 있다.

    Flask-Bootstrap 템플릿 사용

    {% extends "bootstrap/base.html" %}
     
    {% block title %}Flasky{% endblock %}
     
    {% block navbar %}
    
    {% endblock %}
     
     
    {% block content %}
    
    {% endblock %}

    이것은 Flask-Script와 같이 Flask의 실례 앱을 초기화했지만 다른 것은Bootstrap 실례에run 방법이 없고 예전처럼 앱을 실행하는 것이다.run().

    이 템플릿에 대한 간단한 설명


    현재 당신이 보고 있는 템플릿은 비교적 복잡합니다. 전체 템플릿이 3개의 블록, title,navbar, 콘텐츠를 정의했다는 것을 알기만 하면 됩니다.title는 웹 페이지 라벨bar에 나타난 사이트 정보임이 분명하다.navbar는 네비게이션 게이지이고 콘텐츠는 웹 페이지의 주체 부분이다.그중의 Flasky, Home, Hello, 너도 스스로 중국어로 바꿀 수 있다.
    extends 뒤에 현재 프로그램에 이bootstrap 디렉터리가 없습니다. 즉, 우리가 쓴 bootstrap은 실제로bootstrap의 템플릿을 인용한 것입니다. 템플릿 이름은base입니다.html, 구체적인 경로는 C:\Python34\Lib\site-packages\blaskbootstrap\templates\bootstrap, 당신의python 버전에 따라 경로의python 34는python 27 또는python 36 등일 수 있습니다.너는 이 경로 아래로 가서 또 어떤 템플릿이 있는지 볼 수 있다.

    Flask-Bootstrap 기본 템플릿에 정의된 블록


    블록 이름
    설명
    doc
    전체 html 문서
    html_attribs
    html
    head
    title </code> </td> </tr> <tr> <td>metas</td> <td> <code><meta/></code> </td> </tr> <tr> <td>styles</td> <td> </td> </tr> <tr> <td>body_attribs</td> <td> <code/> </td> </tr> <tr> <td>body</td> <td> <code/> </td> </tr> <tr> <td>navbar</td> <td> </td> </tr> <tr> <td>content</td> <td> </td> </tr> <tr> <td>scripts</td> <td> JavaScript </td> </tr> </tbody> </table> <p> 3-2 Flask-Bootstrap ,<br/> 。<br/> ,Bootstrap styles scripts 。<br/> ,<br/> Jinja2 super() 。<br/> , <br/> JavaScript , scripts :</p> <pre><code>{% block scripts %} {{ super() }} <script type="text/javascript" src="my-script.js"/> {% endblock %} </code></pre> <h2>3.3 </h2> <h3> </h3> <p> ,<br/> 404 ,<br/> Bootstrap ,<br/> 。</p> <h3> </h3> <p>Flask 。<br/> :</p> <ul> <li>404, ;</li> <li>500, 。</li> </ul> <h3> </h3> <pre><code>@app.errorhandler(404) def page_not_found(e): return render_template('404.html'), 404 @app.errorhandler(500) def internal_server_error(e): return render_template('500.html'), 500 </code></pre> <p> :errorhandler。<br/> 。<br/> e ,<br/> 。<br/> , 。<br/> 。</p> <h3> </h3> <p> Flask 404.html 500.html ,<br/> templates ,<br/> extends bootstrap ,<br/> ,<br/> 。<br/> ,<br/> 。</p> <h3> </h3> <p> templates/user.html,<br/> templates/404.html <br/> templates/500.html,<br/> 。<br/> 。</p> <h3> </h3> <p>Jinja2 。<br/> Flask-Bootstrap ,<br/> , ,<br/> ,<br/> 。<br/> ,<br/> templates/user.html、 templates/404.html templates/500.html。</p> <h3> </h3> <pre><code>{% extends "bootstrap/base.html" %} {% block title %}Flasky{% endblock %} {% block navbar %} <div class="navbar navbar-inverse" role="navigation"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"/> <span class="icon-bar"/> <span class="icon-bar"/> </button> <a class="navbar-brand" href="#!/" rel="nofollow">Flasky</a> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a href="#!/" rel="nofollow">Home</a></li> </ul> </div> </div> </div> {% endblock %} {% block content %} <div class="container"> {% block page_content %}{% endblock %} </div> {% endblock %} </code></pre> <p> content </p><div> ,<br/> page_content ,<br/> 。 <h3> </h3> <p> , ,<br/> Flask-Bootstrap 。<br/> templates/base.html 404 ,</p> <pre><code>{% extends "base.html" %} {% block title %}Flasky - Page Not Found{% endblock %} {% block page_content %} <div class="page-header"> <h1>Not Found</h1> </div> {% endblock %} </code></pre> <p> title ,<br/> ,<br/> 。<br/> index、500 user 。</p> <h2>3.4 </h2> <h3> </h3> <p> , 。<br/> URL ,<br/> URL ,<br/> ,<br/> , 。</p> <h3>url_for() </h3> <p> , Flask url_for() ,<br/> URL URL。</p> <p>url_for() ,<br/> URL。<br/> , hello.py url_for('index') /。<br/> url_for('index', _external=True) ,<br/> http://localhost:5000/。</p> <blockquote> <p> , 。<br/> ,<br/> ,<br/> 。</p> </blockquote> <h3>url_for </h3> <p> url_for() , 。<br/> , url_for('user', name='john', _external=True) http://localhost:5000/user/john。</p> <p> url_for() 。<br/> 。<br/> , url_for('index', page=2) /?page=2。</p> <p> hello.py <code>if __name__</code> <code>app.run</code> 。<br/> 2 :</p> <pre><code>with app.test_request_context(): print(url_for('index')) </code></pre> <blockquote> <p>test_request_context Flask ,<br/> Flask ,<br/> app.run() , print 。</p> </blockquote> <h2>3.5 </h2> <h3> </h3> <p>Web Python 。<br/> ,<br/> HTML 、 JavaScript CSS。</p> <h3> </h3> <p> 2 hello.py URL ,<br/> static 。<br/> ,<br/> /static/<filename>。<br/> , <code>url_for('static', filename='css/styles.css', _external=True)</code><br/> http://localhost:5000/static/css/styles.css。</filename></p> <p> , Flask static 。<br/> , static 。<br/> URL ,<br/> ,<br/> static/css/styles.css 。</p> <blockquote> <p> filename </p> </blockquote> <h3> </h3> <pre><code>{% block head %} {{ super() }} <link rel="shortcut icon" href="{{ url_for('static', filename = 'favicon.ico') }}" type="image/x-icon"/> <link rel="icon" href="{{ url_for('static', filename = 'favicon.ico') }}" type="image/x-icon"/> {% endblock %} </code></pre> <p> block <code>head</code> 。<br/> super() 。</p> <h2>3.6 Flask-Moment: </h2> <h3> </h3> <p> Web ,<br/> 。</p> <p> ,<br/> ,<br/> ( Coordinated Universal Time, UTC)。<br/> UTC ,<br/> ,<br/> 。</p> <h3> </h3> <p> UTC ,<br/> ,<br/> Web ,<br/> , 。<br/> Web ,<br/> 。</p> <h3>Flask-Moment </h3> <p> JavaScript ,<br/> moment.js( http://momentjs.com/),<br/> 。<br/> Flask-Moment Flask ,<br/> moment.js Jinja2 。</p> <h3> </h3> <p>Flask-Moment pip :</p> <pre><code>$ pip install flask-moment from flask_moment import Moment moment = Moment(app) </code></pre> <p> moment.js, Flask-Moment jquery.js。<br/> HTML ,<br/> , ,<br/> ,<br/> ( Content Delivery Network,<br/> CDN) 。<br/> Bootstrap jquery.js,<br/> moment.js 。</p> <p> scripts 。</p> <pre><code>{% block scripts %} {{ super() }} {{ moment.include_moment() }} # moment.js {% endblock %} </code></pre> <h3> Flask-Moment</h3> <p> , Flask-Moment moment 。</p> <ul> <li>hello.py: datetime 。</li> </ul> <pre><code>from datetime import datetime @app.route('/') def index(): return render_template('index.html',current_time=datetime.utcnow()) </code></pre> <ul> <li>templates/index.html: Flask-Moment </li> </ul> <pre><code><p>The local date and time is {{ moment(current_time).format('LLL') }}.</p> <p>That was {{ moment(current_time).fromNow(refresh=True) }}</p> </code></pre> <p>format('LLL') 。<br/> ,<br/> 'L' 'LLLL' 。<br/> format() 。</p> <p> fromNow() ,<br/> 。<br/> “ a few seconds ago”,<br/> refresh ,<br/> 。 ,<br/> , “ a minuteago”“ 2 minutes ago” 。</p> <h3> </h3> <p>Flask-Moment 。<br/> , <br/> lang() :<br/> <code>{{ moment.lang("zh_cn") }}</code><br/> Flask-Moment moment.js format()、 fromNow()、 fromTime()、 calendar()、 valueOf() unix() 。<br/> http://momentjs.com/docs/#/displaying/<br/> moment.js 。</p> <p>Flask-Monet “ ” datetime ,<br/> UTC 。<br/> 1 ,<br/> datetime <br/> https://docs.python.org/2/library/datetime.html</p> </div> </article></div> </div> <!--PC WAP --> <script type="text/javascript" src="/views/front/js/chanyan.js"/> <!-- - -->

    좋은 웹페이지 즐겨찾기