为了把业务逻辑和表现逻辑分开,Flask把表现逻辑移到JinJa2模板,模板是一个包含响应文本的文件。它用占位变量表示动态部分,其具体要从请求上下文才知道。
把真实值替换掉占位变量成为渲染,JinJa2模板的创造者也是Flask的创造者,所以不需要额外安装包。
1. Flask使用模板
1.1 建立模板
在程序的同一级目录下建立templates目录,在该目录下建立user.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>Hello {{ name }}!!!</h1> </body> </html>
{{ name }}就是一个变量符,它的值要渲染得到
1.2. 加载模板
from flask import Flask from flask import render_template app=Flask(__name__) @app.route('/user/<name>') def user(name): return render_template('user.html',name=name) if __name__ == '__main__': app.run(debug=True)
1.3 变量和过滤器
JinJia2可以识别所有类型变量,如:
{{ MyList[1] }}
{{ MyObj.test() }}
Jinja2还提供了过滤器用于修改变量
用法: {{ name|uppr }}
1.4 控制结构
判断:
{% if user %} Hello,{{ user }} {% else %} Please input your name!!! {% endif %}
循环:
{% for name in user %} <li>{{ name }}</li> {% endfor %}
1.5 定义宏
宏类似于Python中的函数,可以被重复使用
macro.html
{% macro render_comment(comment) %} <li>{{ comment }}</li> {% endmacro %} <ul> {% for comment in comments %} {{ render_comment(comment) }} {% endfor %} </ul>
在模板中导入这个宏文件
<body> {% import 'macro.html' as macros %} <ul> {% for user in names %} {{ macros.render_comment(user) }} {% endfor %} <ul> </body>
1.6 继承
base.html
<!DOCTYPE html> <html lang="en"> <head> {% block head %} <title>{% block title %}{% endblock %} - My APP</title> {% endblock %} </head> <body> {% block body %} {% endblock %} </body> </html>
继承base.html
{% extends "base.html" %} {% block title %}Index{% endblock %} {% block body %} <h1>hello world</h1> {% endblock %}
2. 使用Flask-BootStrap
想要在程序中继承bootstrap,可以使用flask-bootstrap的flask拓展,简化集成过程。
2.1 安装Flask-BootStrap
pip install flask-bootstrap
2.2 继承bootstrap/base.html
user.html
{% 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> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/">Flasky</a> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a href="/">Home</a></li> </ul> </div> </div> </div> {% endblock %} {% block content %} <div class="container"> <div class="page-header"> <h1>Hello, {{ name }}!</h1> </div> </div> {% endblock %}
navbar和content分别表示导航条和主体内容
页面效果:
bootstrap/base.html定义的所有块
3.3 定义错误页面
hello.py
from flask import Flask, render_template from flask_bootstrap import Bootstrap app = Flask(__name__) bootstrap = Bootstrap(app) @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 @app.route('/') def index(): return render_template('index.html') @app.route('/user/<name>') def user(name): return render_template('user.html', name=name) if __name__ == "__main__": app.run()
编写base.html
{% 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> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/">Flasky</a> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a href="/">Home</a></li> </ul> </div> </div> </div> {% endblock %} {% block content %} <div class="container"> {% block page_content %}{% endblock %} </div> {% endblock %}
编写404.html
{% extends "base.html" %} {% block title %}Flasky - Page Not Found{% endblock %} {% block page_content %} <div class="page-header"> <h1>Not Found</h1> </div> {% endblock %}
3.4 静态文件
{% extends "bootstrap/base.html" %} {% block title %}Flasky{% endblock %} {% 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 %} {% 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> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/">Flasky</a> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a href="/">Home</a></li> </ul> </div> </div> </div> {% endblock %} {% block content %} <div class="container"> {% block page_content %}{% endblock %} </div> {% endblock %}
url_for会找到视图函数对应的URL。