Flask 第三话之Jinja2模板介绍及用法

一、模板的基本使用

1、设置模板文件路径:template_folder='路径'

from flask import Flask,render_template

# template_folder='D:\templates' => 可指定模板路径 默认值为:templates
app = Flask(__name__,template_folder='templates')

1.1:最简单的模板语法

# <p>我是<h1>{{ a }}</h1>参数参数参数参数参数参数</p>
@app.route('/')
def home():
    a = "后台传过来的"
    return render_template('index.html',a=a)

1.2:可以使用**对模板语法进行批量的方式传到前端

"""
<body>

<div>
    <p>{{ name }}</p>
    <p>{{ age }}</p>
    <p>{{ sex }}</p>
</div>
====================
<div>
    {{ dicts.aa }}
    {{ dicts['aa'] }}
</div>
</body>
"""
@app.route('/list/')
def list():
    context = {
        'name':'lee',
        'age':18,
        'sex':'',
        'dicts':{
            'aa':'aa',
            'bb':'bb'
        },
    }
    return render_template('posts/list.html',**context)

 2、对 url_for() 的使用:

语法:{{url_for('视图函数名或别名',arg1=arg1,arg2=arg2,arg3=arg3)}}

注:如果链接中有参数arg则会补位到链接中不会以GET方式携带

# <p><a href="{{ url_for('login',next='/',ref = 77908,uid=15) }}">登陆</a></p>
# =>>> http://127.0.0.1:5000/login/15/?next=%2F&ref=77908
@app.route('/')
def index():
    return render_template('index.html')

@app.route('/login/<uid>/')
def login(uid):
    print(uid)
    return render_template('login.html')

 二、模板的高级使用

语法:变量名 | 过滤器

{{args | filter_func}}

在 jinja2 中,过滤器是可以支持链式调用的,示例如下:

{{ "hello world" | reverse | upper }}

1.内置过滤器

1.1字符串相关

safe :禁用转义

{{ '<em>hello</em>'|safe}} <br>

default:默认值

{{ name | default('默认值',boolean=True) }}

capitalize:首字母大写

{{ 'hello world' | capitalize }}

lower 把所有字母转换为小写

{{ 'HELLO'|lower }}

upper 把所有字母转换成大写

{{ 'hello' | upper }}

title 把值里面的每个单词的首字母大写

{{ 'big big world' | title }}

trim 把值的首尾空格去掉

{{ '   hello      ' |trim }}

reverse :字符串反转

{{ 'hello' | reverse }}

format:格式化输出

{{ "%s is %d" | format("ryang",24) }}

striptags:渲染之前把值中所有的HTML标签都删掉

<p>{{ '<em>hello</em>' | striptags }}</p>

truncate: 字符串截断

<p>{{ 'hello every one' | truncate(9)}}</p>

1.2列表操作

first :取第一个元素

{{ [3,4,5,6,7]|first }}

last:取最后一个元素

{{ [3,4,5,6,7]|last }}

length:获取列表的长度

{{ [1,2,3,4,5,6]|length }}

sum:列表求和

{{ [1,2,3,4,5,6]|sum }}

sort:列表排序

{{ [4,5,6,2,1]|sort }}

语句块过滤:

{% filter upper %}
    this is a Flask Jinja2 introduction
{% endfilter %}

2.自定义过滤器

注:设置TEMPLATES_AUTO_RELOAD = True,将会自动加载模板

# {{ eat | filter_cut }} => ! my eat apple
@app.route('/')
def index():
    context = {
        'eat' : "hello ! my eat apple"
    }
    return render_template('index.html',**context)

# 定义过滤器函数
# 将cut函数注册到过滤器使用名字为filter_cut
@app.template_filter('filter_cut')
def cut(value):
    value = value.replace('hello','')
    return value

 案例:时间过滤器

import datetime

# <p>此信息更新于{{ creat_time | handle_time }}</p>
@app.route('/')
def index():
    context = {
        'creat_time':datetime.datetime(2020,1,20,16,0,0)
    }
    return render_template('index.html',**context)

# 定义过滤器函数
# 将cut函数注册到过滤器使用名字为filter_cut
@app.template_filter('handle_time')
def handle_time(value):
    """
    1分钟以内就显示‘刚刚’
    1小时以内就显示‘**分钟前’
    1天以内就显示‘**小时前’
    1-30天显示‘**天’
    其他显示具体日期
    :param value:
    :return:
    """
    if isinstance(value,datetime.datetime):
        now = datetime.datetime.now()
        timestamp = (now - value).total_seconds()
        if timestamp < 60:
            return '刚刚'
        elif timestamp>=60 and timestamp<=60*60:
            return '{}分钟前'.format(int(timestamp / 60))
        elif timestamp>=60*60 and timestamp<=60*60*24:
            return '{}小时前'.format(int(timestamp / (60*60)))
        elif timestamp>=60*60*24 and timestamp<=60*60*24*30:
            return '{}天前'.format(int(timestamp / (60*60*24)))
        else:
            return value
    else:
        return value

 3.宏用法:类似于创造一个函数,将函数在模板中以变量的方式展示,如下所示

<body>
    {% macro input(name,value="",type="text") %}
        <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
    {% endmacro %}


    <table>
        <tbody>
            <tr>
                <td>用户名:</td>
                <td>{{ input("username") }}</td>
            </tr>
            <tr>
                <td>密码:</td>
                <td>{{ input("pass",type="password") }}</td>
            </tr>
            <tr>
                <td></td>
                <td>{{ input(value="提交",type="submit") }}</td>
            </tr>
        </tbody>
    </table>
</body>

 4.不常用的模板变量

4.1:set

{% set username = "daojiale" %}
<p>{{ username }}</p>

4.2:with

{% with classroom="kebo" %}
{#   with语句只能在代码块中定义和执行   #}
<p>第一次使用:{{ classroom }}</p>
{% endwith %}

<p>第二次使用:{{ classroom }}</p>

 5.使用静态问卷:css、js、image等

<link rel="stylesheet" href="{{ url_for('static',filename="css/index.css") }}">
<img src="{{ url_for('static',filename='img/1.jfif') }}" alt="">
<script src="{{ url_for('static',filename='js/index.js') }}"></script>

 5.模板继承

--- base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">

</head>
<body>

<div>
    <p>固定顶部</p>
</div>

{% block title %}
    <p>我是base.html中的代码块,在其他地方引用就用 self.模块名() </p>
{% endblock %}

{% block body_c %}
我是父模板内容
{% endblock %}

<div>
    <p>固定底部</p>
</div>
</body>
</html>

--- index.html

{% extends 'base/base.html'%}


{% block body_c %}
    <hr>
    {{ self.title() }}

    {{ super() }}
    我是子模板内容:使用super()方法可以将父模板内容和子模板内容同时展示

    <div>
    1.extends 继承哪个模板;
    </div>

    <div>
    2.block 使用继承模板中的具体位置;
    </div>

    <div>
    3.在block代码块中写变化的内容;
    </div>
    <hr>
{% endblock %}
原文地址:https://www.cnblogs.com/lee-xingxing/p/12325328.html