flask:flask模板——使用Jinja2

    科技2024-09-27  17

    一,模板引擎

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

    1,什么是模板

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

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

    2,什么是Jinja2

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

    3,什么是模板渲染?

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

    4,怎样使用模板

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

    <!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,运行项目

    二,向模板传参

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

    1,传递一个参数

    app.py:

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

    index.html:

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

    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>

    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: ```html @app.route('/<sex>') 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>

    3,for

    语法:

    {% for item in iteratable_object %} do_something {% endfor %}``` app.py: ```html @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>

    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>

    过滤器本质就是一个处理函数,能自定义过滤器:

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

    自定义过滤器如下: 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>

    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>

    2,规范化使用宏 就像C语言中的头文件概念一样,我们最好将宏统一放置: 使用时再导入:

    {% 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可以将一个模板导入到指定模板中。

    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>

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

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

    除了直接在模板文件中使用<script>标签包含静态内容,更推荐的方法是将它们统一放入static文件中。项目结构如下:

    模板:

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> {# <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 %}中添加自己的内容。

    项目结构如下: 父模板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() }}保留父模板内容

    Processed: 0.012, SQL: 8