python中的flask框架Jinja 模板入门教程

目录
  • 1、快速体验
  • 2、Flask 最小 DEMO
  • 3、模板继承
  • 4、Super Blocks
  • 5、Macros
  • 6、自定义过滤器
  • 7、结论

Flask 和 Django 附带了强大的 Jinja 模板语言。

对于之前没有接触过模板语言的人来说,这类语言基本上就是包含一些变量,当准备渲染呈现 HTML 时,它们会被实际的值替换。

这些变量放在标记或分隔符之前。例如:Jinja 模板使用 {% ... %} 表示循环,{{ ... }} 表示一个表达式运算结果返回。

Jinja 模板其实是 html 文件。一般情况下放在 Flask 工程的 /templates 目录下

1、快速体验

跑下面的各种 demo 之前,确保你已经安装了 Jinja (pip install jinja2)

>>> from jinja2 import Template
>>> t = Template("Hello {{ something }}!")
>>> t.render(something="World")
u'Hello World!'

>>> t = Template("My favorite numbers: {% for n in range(1,10) %}{{n}} " "{% endfor %}")
>>> t.render()
u'My favorite numbers: 1 2 3 4 5 6 7 8 9 '

这个 demo 展示了模板中的变量(表达式)是如何最终被替换和渲染的。

2、Flask 最小 DEMO

整个的参考代码可以在这里获得:HERE

不过博主建议按照下面步骤一步步来:

1)安装 flask

➜  pip install flask

2)创建工程目录结构:

➜  mkdir flask_example
➜  cd flask_example
➜  mkdir templates
➜  cd ..
➜  touch run.py
➜  touch requirements.txt

3)编写 run.py

from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def template_test():
    return render_template('template.html', my_string="Wheeeee!", my_list=[0,1,2,3,4,5])
if __name__ == '__main__':
    app.run(debug=True)

这里,我们创建了一个 / 路由,当我们访问服务器根路由时,会通过 render_templatetemplate.html 渲染,其中 my_stringmy_list 就是准备传给模板的实际的值。

4)编写 template.html 模板

在 templates 目录下,创建一个 template.html:

<!DOCTYPE html>
<html>
  <head>
    <title>Flask Template Example</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" media="screen">
    <style type="text/css">
      .container {
        max-width: 500px;
        padding-top: 100px;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <p>My string: {{my_string}}</p>
      <p>Value from the list: {{my_list[3]}}</p>
      <p>Loop through the list:</p>
      <ul>
        {% for n in my_list %}
        <li>{{n}}</li>
        {% endfor %}
      </ul>
    </div>
    <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
    <script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
  </body>
</html>

5)运行观察效果

➜  python run.py

效果如下:

可以看到,将模板中的 my_string、my_list[3] 替换掉了,并且用 for 循环语句,生成了一个 list。

3、模板继承

模板通常利用继承,继承包括定义所有后续子模板基本结构的单个基础模板。您可以使用标记 {% extends %}{% block %} 来实现继承。

这样做的用例很简单:随着应用程序的增长,以及您继续添加新模板,您将需要保持公共代码(如HTML导航栏、Javascript库、CSS样式表等)同步,这可能需要大量工作。使用继承,我们可以将这些公共部分移动到父/基模板,这样我们就可以创建或编辑这样的代码一次,所有子模板都将继承该代码。

注意:您应该总是尽可能多地向基本模板添加重复代码,以节省将来的时间,这将远远超过初始时间投资。

让我们给我们的 DEMO 增加模板:

1)创建基础模板(保存为 layout.html

<!DOCTYPE html>
<html>
  <head>
    <title>Flask Template Example</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" media="screen">
    <style type="text/css">
      .container {
        max-width: 500px;
        padding-top: 100px;
      }
      h2 {color: red;}
    </style>
  </head>
  <body>
    <div class="container">
      <h2>This is part of my base template</h2>
      <br>
      {% block content %}{% endblock %}
      <br>
      <h2>This is part of my base template</h2>
    </div>
    <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
    <script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
  </body>
</html>

你注意到 {%block%} 标记了吗?这定义了子模板可以填充的块或区域。此外,也可实现覆盖的作用。

2)用模板更新 template.html:

{% extends "layout.html" %}
{% block content %}
  <h3> This is the start of my child template</h3>
  <br>
  <p>My string: {{my_string}}</p>
  <p>Value from the list: {{my_list[3]}}</p>
  <p>Loop through the list:</p>
  <ul>
    {% for n in my_list %}
    <li>{{n}}</li>
    {% endfor %}
  </ul>
  <h3> This is the end of my child template</h3>
{% endblock %}

这样 layout.html 模板中的 content 块就会被 template.html 中的新定义给替换掉,最终效果如下:

那么,我们就可以通过修改 layout.html 给其添加通用导航栏了:(将下列代码插入到 layout.html<body> 标签之后)

<nav class="navbar navbar-inverse" role="navigation">
  <div class="container-fluid">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
        <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="/">Jinja!</a>
    </div>

    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav">
        <li class="active"><a href="#">Link</a></li>
        <li><a href="#">Link</a></li>
      </ul>
      <form class="navbar-form navbar-left" role="search">
        <div class="form-group">
          <input type="text" class="form-control" placeholder="Search">
        </div>
        <button type="submit" class="btn btn-default">Submit</button>
      </form>
      <ul class="nav navbar-nav navbar-right">
        <li><a href="#">Link</a></li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
          <ul class="dropdown-menu">
            <li><a href="#">Action</a></li>
            <li><a href="#">Another action</a></li>
            <li><a href="#">Something else here</a></li>
            <li class="divider"></li>
            <li><a href="#">Separated link</a></li>
          </ul>
        </li>
      </ul>
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
</nav>

现在,从基础扩展的每个子模板都将具有相同的导航栏。借用Java哲学的一句话:"Write once, use anywhere."

4、Super Blocks

如果需要从基础模板渲染块,使用 super block:

{{ super() }}

给基础模板增加一个页脚:

<body>
<div class="container">
 ...
  <h2>This is part of my base template</h2>
  <br>
  <div class="footer">
    {% block footer %}
      Watch! This will be added to my base and child templates using the super powerful super block!
      <br>
      <br>
      <br>
    {% endblock %}
  </div>
</div>
...

此时,我们可以给 template.html 增加 super block,从而实现子模板复用父模板中的块:

{% extends "layout.html" %}
{% block content %}
  <h3> This is the start of my child template</h3>
  <br>
  <p>My string: {{my_string}}</p>
  <p>Value from the list: {{my_list[3]}}</p>
  <p>Loop through the list:</p>
  <ul>
    {% for n in my_list %}
    <li>{{n}}</li>
    {% endfor %}
  </ul>
  <h3> This is the end of my child template</h3>
  {% block footer %}
  {{super()}}
  {% endblock %}
{% endblock %}

效果如下:

super block 用于模块共享父模块的 block,当然还有一些高级玩法,比如下面的例子:

父模板:

{% block heading %}
  <h1>{% block page %}{% endblock %} - Flask Super Example</h1>
{% endblock %}

子模板:

{% block page %}Home{% endblock %}
{% block heading %}
  {{ super() }}
{% endblock %}

这样当访问子模块时,会拼接一个 <h1>Home - Flask Super Example</h1> 字段。发现没,我们通过这样的方法,实现了标题的继承(有一定的继承,也有一定的子模块自己的信息)。

回归正轨,对于更新标题,我们这里这样设计(修改 template.html 中的两行代码)

{% block title %}{{title}}{% endblock %}
...
{% block page %}{{title}}{% endblock %}

这样我们可以通过 python 进来直接修改标题了(修改 run.py):

@app.route("/")
def template_test():
    return render_template(
        'template.html', my_string="Wheeeee!",
        my_list=[0,1,2,3,4,5], title="Home")

5、Macros

在 Jinja 中,我们可以使用宏来抽象常用的代码段,这些代码段被反复使用以避免重复。例如,通常会在导航栏上突出显示当前页面的链接(活动链接)。否则,我们必须使用 if/elif/else 语句来确定活动链接。使用宏,我们可以将这些代码抽象成一个单独的文件。

新增一个 macros.html 文件:

{% macro nav_link(endpoint, name) %}
{% if request.endpoint.endswith(endpoint) %}
  <li class="active"><a href="{{ url_for(endpoint) }}">{{name}}</a></li>
{% else %}
  <li><a href="{{ url_for(endpoint) }}">{{name}}</a></li>
{% endif %}
{% endmacro %}

这里,我们使用了 Flask 的 request object(Jinja 的默认一部分),用来检查请求端点,然后将活动 class 分配给该端点。

使用基础模板中的nav navbar nav类更新无序列表:

<ul class="nav navbar-nav">
  {{ nav_link('home', 'Home') }}
  {{ nav_link('about', 'About') }}
  {{ nav_link('contact', 'Contact Us') }}
</ul>

此外,请确保在模板顶部添加导入:{% from "macros.html" import nav_link with context %}

最后,让我们向控制器添加三个新端点:

@app.route("/home")
def home():
    return render_template(
        'template.html', my_string="Wheeeee!",
        my_list=[0,1,2,3,4,5], title="Home")

@app.route("/about")
def about():
    return render_template(
        'template.html', my_string="Wheeeee!",
        my_list=[0,1,2,3,4,5], title="About")

@app.route("/contact")
def contact():
    return render_template(
        'template.html', my_string="Wheeeee!",
        my_list=[0,1,2,3,4,5], title="Contact Us")

刷新页面。测试顶部的链接。当前页面是否突出显示?(每次点击 Home, About, Contact Us,浏览器会自动跳转到对应的 url,并加载页面)

6、自定义过滤器

Jinja 使用过滤器修改变量,主要用于格式化目的。

这有个例子;

{{ num | round }}

这将使 num 变量四舍五入。因此,如果我们将参数 num=46.99 传递到模板中,那么将输出47.0。(把大括号中的语句当做 shell,就明白了,竖线是传递作用,round是个过滤器,这里是所有的过滤器)

再来个例子:

{{ list|join(', ') }}

可以给 list 数组中的变量加个逗号。

其实,除了自带的过滤器,我们也可以自定义:

1)在 run.py 的所有函数前增加 app = Flask(__name__) 用于创建一个 app
2)增加一个 datetimefilter 函数,并将其注册到 app 的过滤器

@app.template_filter() # 声明,这是个过滤器
def datetimefilter(value, format='%Y/%m/%d %H:%M'):
    """Convert a datetime to a different format."""
    return value.strftime(format)

app.jinja_env.filters['datetimefilter'] = datetimefilter

3)这样,我们在子模板中插入如下代码:

<h4>Current date/time: {{ current_time | datetimefilter }}</h4>

4)最后,只要在 python 中将时间传入模板即可:

current_time = datetime.datetime.now()

5)效果如下:

7、结论

这样,就送大家快速入门了 Jinja,源码:https://github.com/mjhea0/thinkful-mentor/tree/master/python/jinja/flask_example

参考链接

[1]. 本文源码
[2]. Primer on Jinja Templating(本文翻译并参考这篇)
[3]. Flask 官方文档
[4]. 真正搞明白Python中Django和Flask框架的区别
[5]. Flask 主页
[6]. 一个 Soft UI Dashboard - Free Jinja Template
[7]. Appseed 这个网站有很多 Flask 模板
[8]. Nginx 服务器 SSL 证书安装部署
[9]. python django web 开发 —— 15分钟送到会用(只能送你到这了)

到此这篇关于python中的flask框架Jinja 模板入门的文章就介绍到这了,更多相关python flask Jinja 模板内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python的Flask框架中的Jinja2模板引擎学习教程

    Flask的模板功能是基于Jinja2模板引擎来实现的.模板文件存放在当前目前下的子目录templates(一定要使用这个名字)下. main.py 代码如下: from flask import Flask, render_template app = Flask(__name__) @app.route('/hello') @app.route('/hello/<name>') def hello(name=None): return render_template('hello.html

  • Python的Flask框架标配模板引擎Jinja2的使用教程

    Jinja2需要Python2.4以上的版本. 安装 按照Jinja有多种方式,你可以根据需要选择不同的按照方式. 使用easy_install 或pip: #sudo easy_install Jinja2 #sudo pip install Jinja2 这两个工具可以自动从网站上下载Jinja,并安装到python目录的site-packages目录中. 从tar包安装: # 下载Jinja的安装包 # 解压缩 # sudo python setup.py install 基本API用法

  • python中的flask框架Jinja 模板入门教程

    目录 1.快速体验 2.Flask 最小 DEMO 3.模板继承 4.Super Blocks 5.Macros 6.自定义过滤器 7.结论 Flask 和 Django 附带了强大的 Jinja 模板语言. 对于之前没有接触过模板语言的人来说,这类语言基本上就是包含一些变量,当准备渲染呈现 HTML 时,它们会被实际的值替换. 这些变量放在标记或分隔符之前.例如:Jinja 模板使用 {% ... %} 表示循环,{{ ... }} 表示一个表达式运算结果返回. Jinja 模板其实是 htm

  • Python中的flask框架详解

    Flask是一个Python编写的Web 微框架,让我们可以使用Python语言快速实现一个网站或Web服务.本文参考自Flask官方文档,大部分代码引用自官方文档. 安装flask 首先我们来安装Flask.最简单的办法就是使用pip. pip install flask 然后打开一个Python文件,输入下面的内容并运行该文件.然后访问localhost:5000,我们应当可以看到浏览器上输出了hello world. from flask import Flask app = Flask(

  • Flask框架Jinjia模板常用语法总结

    本文实例总结了Flask框架Jinjia模板常用语法.分享给大家供大家参考,具体如下: 1. 变量表示 {{ argv }} 2. 赋值操作 {% set links = [ ('home',url_for('.home')), ('service',url_for('.service')), ('about',url_for('.about')), ] %} 3. if判断 {% if not loop.first %}|{% endif %} 4. for 循环 {% for label,l

  • flask框架jinja2模板与模板继承实例分析

    本文实例讲述了flask框架jinja2模板与模板继承.分享给大家供大家参考,具体如下: jinja2模板 from werkzeug.contrib.cache import SimpleCache from flask import Flask, request, render_template,redirect,abort, url_for CACHE_TIME = 300 cache = SimpleCache() cache.timeout = CACHE_TIME app = Fla

  • Golang中Gin框架的使用入门教程

    目录 安装与简单测试 常见请求与分组请求 获取参数 与 参数合法性验证 获得query中参数 获得multipart/urlencoded form中的参数 模型绑定和参数验证 自定义参数验证 项目结构参考 Gin框架运行模式 Gin如何获取客户ip Gin处理请求结果 以String类型响应请求 以Json格式响应请求 以文件形式响应请求 设置http响应头 Gin处理html模板 Gin访问静态资源文件 Gin处理Cookie操作 Gin文件上传 Gin中间件 官方地址:gin-gonic.

  • python中的测试框架

    一.测试常用规则 一个测试单元必须关注一个很小的功能函数,证明它是正确的: 每个测试单元必须是完全独立的,必须能单独运行.这样意味着每一个测试方法必须重新加载数据,执行完毕后做一些清理工作.通常通过setUp()和setDown()方法处理: 编写执行快速的测试代码.在某些情况下,测试需要加载复杂的数据结构,而且每次执行的时候都要重新加载,这个时候测试执行会很慢.因此,在这种情况下,可以将这种测试放置一个后台的任务中. 在编写代码前执行完整的测试,而且在编写代码后再重新执行一次.这样能保证你后来

  • Python中Pyspider爬虫框架的基本使用详解

    1.pyspider介绍 一个国人编写的强大的网络爬虫系统并带有强大的WebUI.采用Python语言编写,分布式架构,支持多种数据库后端,强大的WebUI支持脚本编辑器,任务监视器,项目管理器以及结果查看器. 用Python编写脚本 功能强大的WebUI,包含脚本编辑器,任务监视器,项目管理器和结果查看器 MySQL,MongoDB,Redis,SQLite,Elasticsearch; PostgreSQL与SQLAlchemy作为数据库后端 RabbitMQ,Beanstalk,Redis

  • python中的unittest框架实例详解

    在python中我们学习了不少理论知识,那么对相关的程序进行测试,就显得很重要了.本篇要讲的是unittest框架,我们可以用它来做一些测试工作,又或者是相关代码的编写.下面我们就unittest框架的说明.特性和4种字模块分别带来介绍,大家一起来看具体内容. 1.unittest说明 unittest是Python自带的单元测试框,具备编写用例.组织用例.执行用例.输出报告等自动化框架的条件,可以用来作自动化测试框架的用例组织执行框架. 2.unittest框架特性 (1)提供用例组织与执行:

  • vue项目中使用ts(typescript)入门教程

    目录 1.引入Typescript 2.配置文件webpack配置 3.让项目识别.ts 4.vue组件的编写 data()中定义数据 props传值 完整代码案例 最近项目需要将原vue项目结合ts的使用进行改造,这个后面应该是中大型项目的发展趋势,看到一篇不错的入门教程,结合它并进行了一点拓展记录之.本文从安装到vue组件编写进行了说明,适合入门. 1.引入Typescript npm install vue-class-component vue-property-decorator --

  • Python中非常实用的Math模块函数教程详解

    目录 math模块常数 1. 圆周率 2. Tau (τ) 3. 欧拉数 4. 无限 5. 不是数字 算术函数 1. factorial() 2. ceil() 3. floor() 4. trunc() 5. isclose() 幂函数 1. exp() 2. 对数函数 其他重要的math模块功能 由于该math模块与 Python 版本一起打包,因此您不必单独安装它,直接导入: import math math模块常数 Pythonmath模块提供了多种预定义常量.访问这些常量提供了几个优点

随机推荐