为了把业务逻辑和表现逻辑分开,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。