Flask 模板

模板

春花不红不如草,少年不美不如老。

为什么引入模板的概念

例如用户在网站中注册了一个新账户,用户在表单中输入电子邮件地址和密码.点击提交按钮。服务器收到包含用户输入数据的请求。然后 Flask 把请求分发到处理注册请求的视图函数.这个视图函数需要访问数据库,添加新用户,然后生成响应回送浏览器.这两个过程分别是业务逻辑层和表现逻辑
把表现逻辑移到模板中能够提升程序的可维护性

模板是一个包含响应文本的文件,其中包含用占位变量表示的动态部分,其具体值只在请求的上下文中才能知道,使用真实值替换变量,再返回最终得到的响应字符串,这一过程称为渲染.为了渲染模板 Flask 使用了一个名为 Jinja2 的强大的模板引擎

Jinja2 模板引擎

  • 形式最简单的 Jinja2 模板就是一个包含响应文本的文件.

<h1>Hello {{name}}!</h1>

渲染模板

默认情况 Flask 在程序文件夹中的 templates 子文件夹中寻找模板.在下一个 hello.py 版本中要把前面定义的模板保存在 templates 文件夹中,并分别命名为 index.html 和 user.html


from flask import Flask,render_template

@app.route("/")
def index():
    return render_template('index.html')

@app.route('/user/<name>')
def user(name):
    return render_template('user.html',name=name)
  • Flask 提供的 render_template 函数把 Jinja2 模板引擎集成到了程序中.render_template 函数的第一个参数是模板的文件名,随后的参数都是键值对,表示模板中变量对应的真实值.在这段代码中,第二个模板收到一个名为 name 的变量

  • 上例中 name=name 是关键字参数,这类关键字参数很常见,左边 name 表示参数名,就是模板中的占位符,右边的 name 就是当前作用域的变量,表示同名参数的值

变量

示例中在模板使用的结构表示一个变量,它是一种特殊的占位符,告诉模板这个位置的值从渲染模板时使用的数据获取

Jinja2 能识别所有类型的变量,甚至是一些复杂的类型,例如列表,字典,和对象.在模板中使用变量的一些示例


<p> value from a dictionary {{mydict['key']}}</p>
<p> value from a list:{{mylist[3]}}</p>
<p> value from a list ,with a variable index:{{mylist[myintvar]}}</p>
<p> value from an object  method:{{myobj.somemethod()}}</p>
  • 也可以使用过滤器修改变量,过滤器名添加在变量名之后,中间使用竖线分割.例如下述模板以首字母大写形式展现变量 name 的值

Hello, {{name|capitalize}}
过滤器变量名 说明
safe 渲染值时不转义
capitalize 把值的首字母转换成大写, 其他字母转换成小写
lower 把值转变成小写
upper 把值转变成大写
title 把值中每个单词的首字母都转换成大写
trim 把值的首尾空格去掉
striptags 渲染之前把值中所有的 HTML 标签都删掉

特别说明的是 safe 默认情况下 出于安全考虑 Jinja2 会转义所有的变量,例如一个变量值是’

hello

‘ 它会把小于 大于号都转变类似 &lt 之类的,很多情况下需要显示变量中存储的 HTML 代码,这个时候可使用 safe 过滤器

控制结构

  • 在模板中使用条件控制语句

{% if user %}
    Hello ,{{user}}123
{% else %}
    Hello  Stranger!
{% endif %}
  • for 循环实现调用

<ul>
{% for comment in comments %}
     <li>{{comment}}</li>
  {% endfor %}
</ul>
  • 如果需要重复使用的话

{% include 'common.html' %}
  • 模板继承,创建一个名为 base.html 模板

<html>
  <head>
   {% block head %}
  <title>{% block title %}{% endblock %} - MyApplication</title>
   {% endblock %}
  </head>
  <body>
     {% block body %}
     {% endblock %}
  </body>
</html></title>

block 标签我们定义了名为 head ,title,body 的块


{% extends 'base.html' %}
{% block title %}Index{% endblock %}
{% block head %}
  {{super()}}
  <style>
  </style>

{% endblock %}
{% block body %}
<h1>Hello,world</h1>
{% endblock %}

extends 指令声明这个模板衍生自 base.html 在 extends 指令后,基础模板中的 3 个块被重新定义,模板引擎会将其插入适当的位置.在重新定义新的 head 块,在基础模板中 内部不是空的,所以使用 super()来继承

链接

为了避免这些问题,Flask 提供了 url_for()辅助函数,它可以在程序 URL 映射中保存信息生成的 URL

url_for() 函数最简单的用法是以视图函数名左外参数,返回对应的 url 比如


@app.route('/hi')
def hello:
   return 'haha'
@app.route('/testurlfor')
def testurl:
   print(url_for('hello'),_external=True)

# 这样返回的就是绝对地址 http:localhost:5000/hi 特别注意的就是参数是函数名而不是路由

静态文件

  • 比如说引入图片 css 之类的,可以通过 url_for 来引用比如

url_for('static',filename='css/style.css',_external=True)

# 得到的结果
# http://localhost:5000/static/css/style.css
  • 默认设置下 Flask 在程序根目录中名为 static 的子目录中寻找静态文件.如果需要,可在 static 文件夹中使用子文件夹放文件.服务器收到前面那个 URL 后,会生成一个响应,包含文件系统中 static/css/styles.css

{% block head %}
<link rel="shortcut icon" href="{{url_for('static',filename='favicon.ico')}}" type="image/x-icon">
{% endblock %}

使用 Flask-Moment 本地化时间和日期(了解就好)

要想在服务器上只使用 UTC 时间。有一个使用 JS 开发的优秀客户端开源代码库,名为 moment.js 它可以在浏览器中渲染日期和时间。Flask-Moment 是一个 Flask 程序扩展,能把 moment.js 集成到模板中 Flask-Moment 可以使用 pip 安装


pipenv install flask-moment
  • 初始化 Flask-monent

from flask.ext.moment import Moment
moment = Moment(app)

除了 moment.js 还必须依赖 jquery.js,页面上必须写 jquery.js


{% block scripts %}

{{super()}}

{{moment.include_moment()}}

{% endblock %}

文章作者: 雾烟云
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 雾烟云 !
  目录