flask——2:flask模板——使用Jinja2

一,模板引擎

flask 使用 Jinja2 引擎来渲染模板。

1,什么是模板

简单来说,在web应用开发中,后端主要负责业务逻辑,完成请求与响应的逻辑处理及数据读写,前端主要负责表现逻辑,完成应用界面表现与交互逻辑。为了实现前后端的解耦,分离前后端逻辑,就可以将表现逻辑分离出来交由模板通过模板引擎渲染来实现。

这样看来,其实模板就是包含静态与动态内容的网页内容。

2,什么是Jinja2

Jinja 是一种现代的、对设计人员友好的 Python 模板语言。它具有快速、广泛使用和安全的特性,并且具有可选的沙箱模板执行环境。

3,什么是模板渲染?

所谓渲染,其实就是向网页中加载静态内容及动态内容值的过程。

4,怎样使用模板

下面是一个最简单的例子:
1,创建flask项目
这里以创建flask项目:Hello,Flask!为例。
2,在项目中的 templates 文件中创建 .html 文件
应用结构及 .html 内容如下:
flask——2:flask模板——使用Jinja2_第1张图片

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Index</title>
</head>     
<body>
    <h1>Hello World!</h1>
</body>
</html>

3,编写路由及试图处理函数
app.py内容如下:

from flask import Flask
from flask import render_template


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


if __name__ == '__main__':
    app.run()
  • 使用 render_template() 渲染模板

4,运行项目
flask——2:flask模板——使用Jinja2_第2张图片
flask——2:flask模板——使用Jinja2_第3张图片

二,向模板传参

当然,动态模板才是最常见的,即多是情况下我们是需要将一些内容传递给模板进行渲染使用的。

1,传递一个参数

app.py:

@app.route('/')
def hello_world():
    content = "首页内容"
    return render_template('index.html', content=content)

index.html:

<body>
    <h1>{{ content }}h1>
body>
  • 通过 {{ var }} 使用传来的参数值。

flask——2:flask模板——使用Jinja2_第4张图片

2,传递多个参数

app.py:

@app.route('/')
def hello_world():
    title = "首页"
    content = "首页内容"
    return render_template('index.html',
                           content=content,
                           title=title)

index.html:

<head>
    <meta charset="UTF-8">
    <title>{{ title }}title>
head>
<body>
    <h1>{{ content }}h1>
body>

flask——2:flask模板——使用Jinja2_第5张图片

3,传递所有参数

上面的方法确实可以向模板传递多个参数,但是太麻烦了, flask 还有另一种方法。
app.py:

@app.route('/')
def hello_world():
    title = "首页"
    content = "首页内容"
    return render_template('index.html', **locals())
  • 使用 **locals() 将所有参数传递给了模板,然后选择性使用。

效果与2是一样的,

三,简单的模板语法

详细的模板语法请参考Jinja2官方文档,这里只作简单介绍。

1,delimiters

在上面的模板中我们看到了一些不同于html原生语法的东西:{{ var }}

{{ }} 这东西叫分隔符,模板语法中的分隔符有好几个:

{% ... %} 用于声明,比如在使用for控制语句时

{{ ... }} 用于打印到模板输出的表达式,比如之前传到到的变量(更准确的叫模板上下文)

{# ... #} 用于模板注释

# ... ## 用于行语句,就是对语法的简化

2,if

模板语法:

{% if condition %}
	do_something
{% elif condition %}
    do_something
{% else %}
    do_something
{% endif %}```

app.py:

@app.route('/')
def hello_world(sex):
    title = "首页"
    content = sex
    return render_template('index.html', **locals())

index.html:

<body>
    {% if content == "男" %}
        <h1>h1>
    {% elif content == "女" %}
        <h1>h1>
    {% else %}
        <h1>性别未知h1>
    {% endif %}
body>

flask——2:flask模板——使用Jinja2_第6张图片

3,for

语法:

{% for item in iteratable_object %}
    do_something
{% endfor %}

app.py:

@app.route('/')
def hello_world():
    title = "首页"
    content = [
        {'name': '张三', 'age': 10},
        {'name': '李四', 'age': 11},
        {'name': '王五', 'age': 12},
    ]
    return render_template('index.html', **locals())

模板:

<body>
    <h1>人员信息:h1>
    {% for info in content %}
        <span>{{ info.name }}  {{ info.age }}span>
        <br>
    {% endfor %}
body>

flask——2:flask模板——使用Jinja2_第7张图片

4,filters

变量可以通过过滤器修改。 过滤器由竖线符号 | 与变量分开,并且括号中可以包含可选参数。 可以链接多个过滤器。 一个滤波器的输出将应用于下一个。

flask 提供了许多内建过滤器。

模板:

<body>
    <h1>人员信息:h1>
    {%for info in content|sort(attribute="age")|sort(reverse=true,attribute="name")%}
        <span>{{ info.name }}  {{ info.age }}span>
        <br>
    {% endfor %}
body>

flask——2:flask模板——使用Jinja2_第8张图片
过滤器本质就是一个处理函数,能自定义过滤器:

  1. 定义处理函数
  2. 使用 add_template_filter() 方法添加到模板
  3. 在模板中使用

自定义过滤器如下:
app.py:

@app.route('/')
def hello_world():
    title = "首页"
    content = [
        {'name': '张三', 'age': 10},
        {'name': '李四', 'age': 11},
        {'name': '王五', 'age': 12},
    ]
    return render_template('index.html', **locals())


def do_add_age_number(age_number):
    age = age_number + 3
    return age


app.add_template_filter(do_add_age_number, 'add_age_number')

模板:

<body>
    <h1>人员信息:h1>
    {%for info in content %}
        <span>{{ info.name }} : {{ info.age | add_age_number }}span>
        <br>
    {% endfor %}
body>

flask——2:flask模板——使用Jinja2_第9张图片

5,Macro

宏可与常规编程语言中的功能媲美。 它们有助于将常用的惯用语放入可重复使用的功能中,从而使一个宏可以被多个模板使用。

1,声明与调用
模板:

<body>
    <h1>人员信息:h1>
    {% macro input(name, value='', type='text', size=20, placeholder="在这里输入内容") -%}
        <input type="{{ type }}" name="{{ name }}" value="{{ value|e }}" size="{{ size }}" placeholder="{{ placeholder }}">
    {% endmacro %}

    <div class="info">
        <p>用户:{{ input('username') }}p>
        <p>密码:{{ input('password', type='password') }}p>
        <p>登录:{{ input(type='submit',   value="登录") }}p>
    div>
body>

flask——2:flask模板——使用Jinja2_第10张图片
2,规范化使用宏
就像C语言中的头文件概念一样,我们最好将宏统一放置:
flask——2:flask模板——使用Jinja2_第11张图片
使用时再导入:

    {% import "macros/login_form.html" as login_form %}
    <div class="info">
        <p>用户:{{ login_form.input('username') }}p>
        <p>密码:{{ login_form.input('password', type='password') }}p>
        <p>登录:{{ login_form.input(type='submit',   value="登录") }}p>
    div>

3,include
include 可以将一个模板导入到指定模板中。
flask——2:flask模板——使用Jinja2_第12张图片
flask——2:flask模板——使用Jinja2_第13张图片

6,set与with

set 与 with 都能在模板中设置变量,前者为全作用域,后者为本标签作用域,这与 DTL 是一样的。

<body>
    {% include "included.html" %}
    {% set massage="人员信息修改:" %}
    <h1>{{ massage }}h1>
    {% import "macros/login_form.html" as login_form %}
    {% with warning="注意保管系统管理员密保卡内容!" %}
    <div class="info">
        <p>用户:{{ login_form.input('username') }}p>
        <p>密码:{{ login_form.input('password', type='password') }}p>
        <p>登录:{{ login_form.input(type='submit',   value="登录") }}p>
    div>
    <div class="warning">
        <span>{{ warning }}span>
    div>
    {% endwith %}
body>

flask——2:flask模板——使用Jinja2_第14张图片

四,在模板中加载静态文件

css 与 JavaScript 的引入,使得网页具有更丰富的内容与交互方式,它们将让用户获得更好的使用体验。

除了直接在模板文件中使用\标签包含静态内容,更推荐的方法是将它们统一放入 static 文件中。项目结构如下:
flask——2:flask模板——使用Jinja2_第15张图片

模板:

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
{#    <script src="{{ url_for('static', filename='js/jquery-3.3.1/jquery-3.3.1.js') }}">script>#}

<script type="text/javascript" src="static/js/jquery-3.3.1/jquery-3.3.1.js">script>
<link rel="stylesheet" href="{{ url_for('static',filename='css/car.css') }}">
head>
<body>
{#测试jquery是否加载#}
<script>
    if(jQuery) {
        alert('jQuery已加载!');
    }
    else {
        alert('jQuery未加载!');
    }
script>
<div class="img">
<img src="{{ url_for('static', filename='images/car.jpg') }}">img>
div>
body>
html>

五,模板继承

前面讲的 include 能将一个模板嵌入到另一个模板,模板继承允许一个模板继承另一个模板并进行一些修改。

父模板中添加 {% block partname %}{% endblock %} 就允许子模板对这块内容进行修改。

子模板使用 {% extends %} 继承父模板,并在 {% block partname %}{% endblock %} 中添加自己的内容。

项目结构如下:
flask——2:flask模板——使用Jinja2_第16张图片
父模板base.html:

<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}title>
head>
<body>
{% block body %}
    这是父模板中的内容
{% endblock %}
body>
html>

子模板index.html:

{% extends "base.html" %}

{% block title %}网站首页{% endblock %}

{% block body %}
    {{ super() }}
    <h4>这是子模板的内容!h4>
{% endblock %}
  • 使用{{ super() }}保留父模板内容

flask——2:flask模板——使用Jinja2_第17张图片

你可能感兴趣的:(Flask,flask)