欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

FLASK学习杂记(三)Flask模板

程序员文章站 2022-07-06 15:34:13
FLASK学习杂记(三)Flask模板一、Flask模板使用1.render_template()2.静态文件3.修改模板位置二、模板传参1.关键字传参2.封装字典传参3.**字典传参4.列表、元组、字典取用三、模板基础1.Jinja分隔符配置2.模板过滤器内置过滤器自定义过滤器3.结构控制for循环条件语句宏块一、Flask模板使用函数返回一段前端代码,会被flask自动解析,在前端中展示。@app.route('/index')def index(): return '
...

一、Flask模板使用

函数返回一段前端代码,会被flask自动解析,在前端中展示。

@app.route('/index')
def index():
    return '<h6>请输入:</h6><input name="inp">'

FLASK学习杂记(三)Flask模板
但直接返回html代码,不利于前后端分离,flask为此提供了Jinja2模板引擎,可以通过render_template()方法渲染模板,再返回给前端。

1.render_template()

写一个简单的html文件

<!DOCTYPE html>
<html lang="en">
	<head>
	    <meta charset="UTF-8">
	    <title>index</title>
	</head>
	<body>
		<h6>请输入:</h6>
		<input name="inp">
	</body>
</html>

用render_template()渲染,flask会在templates文件夹内找到要渲染的html文件。

from flask import render_template

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

FLASK学习杂记(三)Flask模板

FLASK学习杂记(三)Flask模板

2.静态文件

在前端开发过程中,也需要css、js 静态文件,flask提供了一个static的文件夹,用于存储相关静态文件。
在static问价夹下新建一个css文件夹用于存储css文件,同理也可在此新建一个js文件夹,用于存储js文件。
FLASK学习杂记(三)Flask模板
这里可以用到url_for()来获取文件地址

<!DOCTYPE html>
<html lang="en">
	<head>
	    <meta charset="UTF-8">
	    <title>index</title>
	    <link rel="stylesheet" href="{{ url_for('static',filename='css/index.css') }}">
	</head>
	<body>
		<h6>请输入:</h6>
		<input name="inp">
	</body>
</html>

css修改h6标签颜色

h6{
    color: aquamarine;
}

FLASK学习杂记(三)Flask模板
如果想修改静态文件默认位置,可以在flask初始化时候设置static_folder

from flask import Flask
app = Flask(__name__,static_folder='staticfiles')

3.修改模板位置

如果想要自定义模板存放位置,可以在初始化flask的时候,设置template_folder

from flask import Flask
app = Flask(__name__,template_folder='./static/templates')

二、模板传参

render_template(template_name_or_list,**context) 中第一个参数为要渲染的模板或带有模板名称的迭代器,但指挥渲染第一个,第二个参数即为要传给前端的参数。

1.关键字传参

@app.route('/')
def hello_world():
    return render_template('index.html',username='Tom',password='123456')

对于username等,前端可以通过{{ username }}的形式直接使用。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
        <h1>{{ username }}</h1>
        <h2>{{ password }}</h2>
    </body>
</html>

FLASK学习杂记(三)Flask模板

2.封装字典传参

@app.route('/')
def hello_world():
    dic = {
        'username':'Tony',
        'password':'123456z'
    }
    return render_template('index.html',dic = dic)

将所有要穿的参数封装成一个字典传dic给前端,前端可以通过{{dic.username}}或{{dic[‘username’]}}的形式取到

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
        <h1>{{ dic.username }}</h1>
        <h2>{{ dic['password'] }}</h2>
    </body>
</html>

FLASK学习杂记(三)Flask模板

3.**字典传参

首先将所有变量封装成字典,然后通过**传递。

@app.route('/')
def hello_world():
    context = {
        'username':'Tony',
        'password':'123456z',
        'score':{
            'Chinese':89,
            'math':96,
            'PE':70
    	}
    }
    return render_template('index.html',**context)

与封装成字典传参不同的是,**context传参前端可以直接通过所需参数名获取

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
        <h1>{{ username }}</h1>
        <h2>{{ password }}</h2>
        <h3>{{ score.Chinese }}</h3>
        <h3>{{ score.math }}</h3>
        <h3>{{ score['PE'] }}</h3>
    </body>
</html>

FLASK学习杂记(三)Flask模板

4.列表、元组、字典取用

@app.route('/')
def hello_world():
    dic = {
        'username':'Tony',
        'password':'123456z'
    }
    li = ['Jack','Tom']
    tup =(1,3,5)
    return render_template('index.html',li = li,tup=tup,dic = dic)
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
        <h1>{{ li.0 }}</h1>
        <h1>{{ li[1] }}</h1>
        <h2>{{ tup.0 }}</h2>
        <h2>{{ tup[2] }}</h2>
        <h3>{{ dic.username }}</h3>
        <h3>{{ dic['password'] }}</h3>
    </body>
</html>

FLASK学习杂记(三)Flask模板

三、模板基础

Flask采用Jinja2模板引擎,Jinja模板语法受Django和Python启发,有Python和Django基础更容易理解。

1.Jinja分隔符配置

  • {% … %}用于声明,如:{% for i in sep -%}
  • {{ … }} 用于打印,如:{{ i }}
  • {# … #} 用于注释,类似<!-- 这是注释 -->
  • # … ## 行语句
@app.route('/')
def hello_world():
    li = ['Jack','Tom','Kitty']
    return render_template('index.html',li = li)
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
        <h1>
            {% for item in li%}
                {# 这里是注释的内容 #}
                {{ item }}
            {% endfor %}
        </h1>
    </body>
</html>

FLASK学习杂记(三)Flask模板

2.模板过滤器

内置过滤器

abs绝对值

@app.route('/')
def hello_world():
    li = [1,-2,3,-4]
    return render_template('index.html',li = li)
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
        <h2>
            {% for item in li %}
                {{ item|abs }}
            {% endfor %}
         </h2>
    </body>
</html>

FLASK学习杂记(三)Flask模板
capitalize首字母大写

@app.route('/')
def hello_world():
    li = ['tom','kitty','sindy','jack']
    return render_template('index.html',li = li)
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
        <h2>
            {% for item in li %}
                {{ item|capitalize }}
            {% endfor %}
        </h2>
    </body>
</html>

FLASK学习杂记(三)Flask模板
default
如果传入的变量为空,会打印定义好的文字,如果不为空要打印变量,需要设置boolean=true。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
        <h2>
            {{ is_null|default('this varity is not defined') }}
            <br>
            {{ "--"|default('this varity is not defined',boolean=true) }}
        </h2>
    </body>
</html>

FLASK学习杂记(三)Flask模板
dictsirt字典排序
dictsort可以按键或值对字典进行排序,用关键字by来控制,用reverse=true来控制升序,默认false,降序。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
        <h2>
            原数据:
            <br>
            {{ mydict }}
            <br>
            按键排序:
            <br>
            {% for item in mydict|dictsort(by ='key') %}
                {{ item }}
            {%  endfor %}
            <br>
            按值排序 降序:
            <br>
            {% for item in mydict|dictsort(by ='value') %}
                {{ item }}
            {%  endfor %}
            <br>
            按值排序 升序:
            <br>
            {% for item in mydict|dictsort(by ='value',reverse=true) %}
                {{ item }}
            {%  endfor %}
            <br>
            {{ mydict }}

        </h2>
    </body>
</html>

FLASK学习杂记(三)Flask模板
可以看到dictsort排序不会对原数据进行修改。

escape转义
在字符串中,如果存在&,<,>等,需要转义成普通字符,才能避免被渲染成html元素,然在flask中会自动将这些字符转义成普通字符。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
        <h3>
            {{ '<h1>你好!;&nbsp北京。</h1>' }}
        </h3>
        <h2>
            {{ '<h1>你好!;&nbsp北京。</h1>'|e }}
        </h2>
        <h1>
            {{ '<h1>你好!;&nbsp北京。</h1>'|escape }}
        </h1>
    </body>
</html>

FLASK学习杂记(三)Flask模板
first、last、length
first返回元素第一项目,last返回最后一个元素,length返回元素长度

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
        <h3>
            {{ 'hello'|first }}
        </h3>
        <h2>
            {{ 'hello'|last }}
        </h2>
        <h1>
            {{ 'hello'|length }}
        </h1>
    </body>
</html>

FLASK学习杂记(三)Flask模板
join
将序列中的元素串联成字符串,默认串联符为空格。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
        <h3>
            {{ [1,2,3,4,5]|join }}
        </h3>
        <h2>
            {{ [1,2,3,4,5]|join(',') }}
        </h2>
        <h1>
            {{ [1,2,3,4,5]|join('->') }}
        </h1>
    </body>
</html>

FLASK学习杂记(三)Flask模板
replace
替换元素中字符为另一个字符

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
        <h3>
            {{ 'everyday,everynight'|replace('every','no') }}
        </h3>
    </body>
</html>

FLASK学习杂记(三)Flask模板
其他过滤器
其他过滤器在此不做详细阐述,可以参考jinja官网上内置过滤器列表查看所有jinja过滤器。

自定义过滤器

通过装饰器template_filter()可以在后端自定义过滤器。

@app.template_filter('my_replace')
def rep(value):
    return value.replace('.','!')
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
        <h3>
            {{ 'everyday,everynight.' }}
        </h3>
        <h3>
            {{ 'everyday,everynight.'|my_replace }}
        </h3>

    </body>
</html>

FLASK学习杂记(三)Flask模板

3.结构控制

结构控制包括for循环、if/elif/else条件语句、宏以及块,用{% …%}来控制,每个控制语句要有对应的{% end… %}来结束。

for循环

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
        <h3>
            {% for item in ['Tom','Jack','Tony'] %}
                {{ item }}
            {% endfor %}
        </h3>
    </body>
</html>

FLASK学习杂记(三)Flask模板

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
        <h3>
            {% for item in [] %}
                {{ item }}
            {%  else %}
                did not iterate
            {% endfor %}
        </h3>
    </body>
</html>

FLASK学习杂记(三)Flask模板

如上,用{% endfor %} 来结束循环。

for-loop特殊变量访问
loop.index

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
        <h3>
            {% for item in ['Tom','Jack','Tony'] %}
                {# 从1开始的迭代 #}
                {{ loop.index }}:{{ item }}
                <br>
            {% endfor %}
        </h3>
    </body>
</html>

FLASK学习杂记(三)Flask模板
loop.index0

<h3>
    {% for item in ['Tom','Jack','Tony'] %}
        {# 从0开始的迭代 #}
        {{ loop.index0 }}:{{ item }}
        <br>
    {% endfor %}
</h3>

FLASK学习杂记(三)Flask模板
loop.revindex

<h3>
    {% for item in ['Tom','Jack','Tony'] %}
        {# 从item.length到1的迭代 #}
        {{ loop.revindex }}:{{ item }}
        <br>
    {% endfor %}
</h3>

FLASK学习杂记(三)Flask模板
loop.revindex0

<h3>
    {% for item in ['Tom','Jack','Tony'] %}
        {# 从item.length-1到0的迭代 #}
        {{ loop.revindex0 }}:{{ item }}
        <br>
    {% endfor %}
</h3>

FLASK学习杂记(三)Flask模板
loop.first

<h3>
    {% for item in ['Tom','Jack','Tony'] %}
        {# 是否为第一次迭代,返回布尔值 #}
        {{ loop.first }}:{{ item }}
        <br>
    {% endfor %}
</h3>

FLASK学习杂记(三)Flask模板

loop.last

<h3>
    {% for item in ['Tom','Jack','Tony'] %}
        {# 是否为最后一次迭代,返回布尔值 #}
        {{ loop.last }}:{{ item }}
        <br>
    {% endfor %}
</h3>

FLASK学习杂记(三)Flask模板
loop.length

<h3>
    {% for item in ['Tom','Jack','Tony'] %}
        {# 返回元素数目 #}
        {{ loop.length }}:{{ item }}
        <br>
    {% endfor %}
</h3>

FLASK学习杂记(三)Flask模板
loop.cycle

<h3>
    {% for item in ['Tom','Jack','Tony'] %}
        {# 在指定元素中循环产生索引 #}
        {{ loop.cycle('a','b') }}:{{ item }}
        {{ loop.cycle('a','b','c','d') }}:{{ item }}
        <br>
    {% endfor %}
</h3>

FLASK学习杂记(三)Flask模板
loop.depth、loop.depth0

<h3>
    {% for item in ['Tom','Jack','Tony'] %}
        {# 迭代深度,从1开始 #}
        {{ loop.depth }}:{{ item }}
         <br>
        {# 迭代深度,从0开始 #}
        {{ loop.depth0 }}:{{ item }}
        <br>
    {% endfor %}
</h3>

FLASK学习杂记(三)Flask模板

loop.previtem

<h3>
    {% for item in ['Tom','Jack','Tony'] %}
        {# 查看元素的前一个元素 #}
        {{ loop.previtem }}:{{ item }}
        <br>
    {% endfor %}
</h3>

FLASK学习杂记(三)Flask模板
loop.nextitem

<h3>
    {% for item in ['Tom','Jack','Tony'] %}
        {# 查看元素的后一个元素 #}
        {{ loop.nextitem }}:{{ item }}
        <br>
    {% endfor %}
</h3>

FLASK学习杂记(三)Flask模板

条件语句

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
        <h3>
            {% for item in ['about','boy','kill'] %}
                {{ item }}
                {% if item|first =='a' %}
                    该字母以a开头
                {%  elif item|first == 'b' %}
                    该字母以b开头
                {%  else %}
                    该字母不以a、b开头
                {%  endif %}
                <br>
            {% endfor %}
        </h3>
    </body>
</html>

FLASK学习杂记(三)Flask模板

可以将宏理解为函数,复用功能,以避免代码重复,可以传参但没有返回值。
用{% macro name(parameter1,parameter2,…) %}的形式来定义宏,parameter为参数,可以设置默认值。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
    {% macro input(name,value='',type='text',size=20) %}
        <input type="{{ type }}" name="{{ name }}",value="{{ value|e }}",size="{{ size }}">
    {% endmacro %}

    <p>用户名:{{ input('username') }}</p>
    <p>&nbsp;&nbsp;&nbsp;码:{{ input('password',type='password') }}</p>
    <p>{{ input('提交',type='submit') }}</p>
    </body>
</html>

FLASK学习杂记(三)Flask模板
import宏
在世纪开发中,会把宏放入一个单独的html文件中,在使用的时候需要导入
macro.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>macro</title>
</head>
<body>
{% macro input(name,value='',type='text',size=20) %}
        <input type="{{ type }}" name="{{ name }}",value="{{ value|e }}",size="{{ size }}">
{% endmacro %}
</body>
</html>

index.html
import

{% import 'macro.html' as marco %}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
    <p>用户名:{{ marco.input('username') }}</p>
    <p>&nbsp;&nbsp;&nbsp;码:{{ marco.input('password',type='password') }}</p>
    <p>{{ marco.input('提交',type='submit') }}</p>
    </body>
</html>

from … import …

{% from 'macro.html' import input  %}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
    <p>用户名:{{ input('username') }}</p>
    <p>&nbsp;&nbsp;&nbsp;码:{{ input('password',type='password') }}</p>
    <p>{{ input('提交',type='submit') }}</p>
    </body>
</html>

FLASK学习杂记(三)Flask模板

块和模板继承

块的存在为jinjia模板继承提供了很大的便利,用{% block name %}来定义,每个块结束都由对应的{% endblock %} 来控制,也可用{% endblock name %} 来结束以增加可读性。

*{
    margin: 0;
    padding: 0;
}

.bg{
    width: 1500px;
    height: 50px;
    background-color: #e7b434;
}

#top{
     background-color: antiquewhite;
}

#footer{
    background-color: #6d6a6a;
}

父模板

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>
        {%  block title%}
        base
        {%  endblock %}
    </title>
    <link rel="stylesheet" href="{{ url_for('static',filename='css/base.css') }}">
</head>
<body>

<div id="top" class="bg">
</div>
<div class="bg">
    {% block center %}
    <h1>这里是要被继承的父模块</h1>
    {% endblock %}
</div>
<div id="footer" class="bg"></div>
</body>
</html>
@app.route('/block/')
def block():
    return render_template('base.html')

FLASK学习杂记(三)Flask模板

子模块

{% extends 'base.html' %}

{% block title %}
extend
{% endblock %}

{% block center %}
<h2>这是继承了父模板的子模板</h2>
{% endblock %}
@app.route('/extendblock/')
def extendblock():
    return render_template('extend.html')

FLASK学习杂记(三)Flask模板
可以看到子模块中只需要修改被block包裹的部分即可。
用super()调用父块结果:

{% extends 'base.html' %}

{% block title %}
extend
{% endblock %}

{% block center %}
<h2>这是继承了父模板的子模板</h2>
    {{ super() }}
{% endblock %}

FLASK学习杂记(三)Flask模板
可以看到父块的结果被返回。
嵌套扩展

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

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

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

parent

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>
        {% block title %}
        Parent
        {% endblock %}
    </title>
</head>
<body>
body: {% block body %}This is from parent.{% endblock %}
</body>
</html>

child

{% extends 'parent.html' %}
{% block title %}Child
{% endblock%}

{% block body %} This is Child. {{ super() }}
{% endblock %}

grandchild

{% extends 'child.html' %}
{% block title %} Grandchild{% endblock %}
{% block body %}This is grandchild.
{{ super.super() }}
{% endblock %}

parent
FLASK学习杂记(三)Flask模板
child
FLASK学习杂记(三)Flask模板
grandchild
用super.super()可以引用parent。
FLASK学习杂记(三)Flask模板

set

可以理解成定义变量并赋值,有作用域限制,在块内设置的变量无法现实在块外,循环中设置的也无法显示在循环外。如下,在循环内外set一个相同的item,

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>set</title>
</head>
<body>
{% set item = 0 %}
{% for i in [1,2,3] %}
    i = {{ i }}
    {% set item = i %}
    item = {{ item }}
    <br>
{% endfor %}
{% if item == 0%} item {% endif %}
</body>
</html>

FLASK学习杂记(三)Flask模板
如果想实现跨作用域传播,可以通过namespace的方法。
如下,通过namespace() set n.flage = false,n.s=1

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>set</title>
</head>
<body>
{% set n = namespace(flage=false,s=1) %}
{% for item in [1,2,3,4] %}
    {{ item }}
    {% if item > 3%}
        {% set n.flage = true %}
        {% set n.s = item %}
    {% endif %}
    <br>
{% endfor %}
n.flage:{{ n.flage }},n.s:{{ n.s }}
</body>
</html>

FLASK学习杂记(三)Flask模板

4.Jinjia表达式

Jinjia表达式与python非常相似,有python基础的更好理解,这里只稍微列举,详细请见Jinjia官网

  • 元组:(’a’,‘b’,‘c’);
  • 列表:[1,2,3] ;
  • 字典:{“user”:“Tom”,“password”:123456}
  • 数学运算 : +(加)、-(减)、*(乘)、%(除)、**(幂)…
  • 比较:== 、!=、>、<、<=、>=
  • 逻辑:and 、 or 、not 、expr
  • 其他:in 、is…

本文地址:https://blog.****.net/m0_46221758/article/details/112309593

相关标签: flask python