flask_七、过滤器+测试器归纳、模板&子模板继承、静态文件
一、过滤器+测试器归纳
内置测试器: first、last、length、max、min 自定义过滤器: @app.template_filter() def music(s): return s + Markup("♫") 内置测试器: string、sames 自定义测试器: @app.template_test() def baz(n): if n == "baz": return True return False 模板环境对象: app.jinja_env.variable_start_string = '[[' app.jinja_env.variable_end_string = ']]'
二、模板环境中的全局函数、过滤器和测试器:
print(app.jinja_env.globals) print(app.jinja_env.filters) print(app.jinja_env.tests)
2.1、模板环境中的过滤器
App.py的文件内容
# encoding=utf-8 from flask import Flask, render_template, render_template_string from flask import Markup app = Flask(__name__) # @app.template_filter(name='filterMusical') def musical(s): return str(s) + Markup(' ♫') app.add_template_filter(musical, name='filterMusical') # @app.template_global() def bar(): return 'I am bar.' app.add_template_global(bar, name='barfunc') @app.context_processor def inject_foo(): return dict(my_func=my_func) def my_func(): return "this is my_func~" @app.template_global(name='barfunc') def bar(): return 'I am bar.' @app.route('/index/') def index(): return render_template('index.html') @app.context_processor def inject_foo(): foo = 'I am foo.' return dict(foo=foo) # 等同于return {'foo': foo} @app.route('/watchlist') def watchlist(): return render_template_string('watchlist.html', movies=movies) # return render_template('watchlist.html',user=user,movies = movies) @app.route('/hello') def hello(): return "hello flask" @app.route('/testJinja') def testJinja(): return render_template('testJinja.html', my_list=my_list, my_tuple=my_tuple, my_dict=my_dict, my_func=my_func, my_object=my_object) my_list = [1, 2, 3, 4] my_tuple = ('a', 'b', 'c', 'd') my_dict = {'d1': 'abc', 'd2': 'bcd', 'd3': 'cde'} def my_func(): return "this is my_func~" my_object = "my_object" def smiling(s): return s + ' (:' app.jinja_env.filters['smiling'] = smiling if __name__ == '__main__': app.run(debug=True)
说明:将smiling这个方法加到过滤器字典的smiling key里面了
Index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> </head> <> <!-- <p>hello {{ name }}</p>--> <!-- {% set navigation %}--> <!-- <li><a href="{{ url_for('watchlist') }}">Watchlist</a></li>--> <!-- <li><a href="{{ url_for('hello') }}">Hello</a></li>--> <!-- {% endset %}--> <!-- {{ navigation }}--> <!-- <hr />--> <!-- <p>config: {{ config }}</p>--> <!-- <p>config.DEBUG: {{ config.DEBUG }}</p>--> <!-- <p>request: {{ request }}</p>--> <!-- <p>request.method: {{ request.method }}</p>--> <!-- <p>session: {{ session }}</p>--> <!-- <p>g: {{ g }}</p>--> <!--<hr />--> <!--<p>my_func(): {{ my_func() }}</p>--> <!--<hr />--> <!--{% for i in range(10) %}--> <!--{{ i }}--> <!--{% endfor %}--> <!--<hr />--> <!--<!–随机函数,最小是10个单词数,最大是20单词数,n是2行即为2段,flase的话没有p标签–>--> <!--{{ lipsum(n=2, html=True, min=10, max=20) }}--> <!--<hr />--> <!--{{ dict(a=1,b=2) }}--> <!--<hr />--> <!--<h1>Hello {{ name|d("陌生人")|title }}</h1>--> <!--<h1>max of [1,2,3,4] {{ [1,2,3,4]|max() }}</h1>--> <!--<h1>first of [1,2,4] {{ [1,2,3]|first() }}</h1>--> <!--<hr />--> {% set name='beautiful' %} <h1>Hello, {{ name|title|upper|length|filterMusical }}!</h1> <hr /> {% set age="123" %} {% if age is number %} age*365等于: {{ age * 365 }} {% else %} 无效的数字 {% endif %} <hr /> <p> foo |smiling: {{ foo|smiling }}</p> </body> </html>
运行效果:

2.2模板环境中的测试器
App.py文件内容
# encoding=utf-8 from flask import Flask, render_template, render_template_string from flask import Markup app = Flask(__name__) # @app.template_filter(name='filterMusical') def musical(s): return str(s) + Markup(' ♫') app.add_template_filter(musical, name='filterMusical') # @app.template_global() def bar(): return 'I am bar.' app.add_template_global(bar, name='barfunc') @app.context_processor def inject_foo(): return dict(my_func=my_func) def my_func(): return "this is my_func~" @app.template_global(name='barfunc') def bar(): return 'I am bar.' @app.route('/index/') def index(): return render_template('index.html') @app.context_processor def inject_foo(): foo = 'I am foo.' return dict(foo=foo) # 等同于return {'foo': foo} @app.route('/watchlist') def watchlist(): return render_template_string('watchlist.html', movies=movies) # return render_template('watchlist.html',user=user,movies = movies) @app.route('/hello') def hello(): return "hello flask" @app.route('/testJinja') def testJinja(): return render_template('testJinja.html', my_list=my_list, my_tuple=my_tuple, my_dict=my_dict, my_func=my_func, my_object=my_object) my_list = [1, 2, 3, 4] my_tuple = ('a', 'b', 'c', 'd') my_dict = {'d1': 'abc', 'd2': 'bcd', 'd3': 'cde'} def my_func(): return "this is my_func~" my_object = "my_object" def smiling(s): return s + ' (:' app.jinja_env.filters['smiling'] = smiling def baz(n): if n == "baz": return True return False app.jinja_env.tests['baz'] = baz if __name__ == '__main__': app.run(debug=True)
Index.html文件内容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> </head> <> <!-- <p>hello {{ name }}</p>--> <!-- {% set navigation %}--> <!-- <li><a href="{{ url_for('watchlist') }}">Watchlist</a></li>--> <!-- <li><a href="{{ url_for('hello') }}">Hello</a></li>--> <!-- {% endset %}--> <!-- {{ navigation }}--> <!-- <hr />--> <!-- <p>config: {{ config }}</p>--> <!-- <p>config.DEBUG: {{ config.DEBUG }}</p>--> <!-- <p>request: {{ request }}</p>--> <!-- <p>request.method: {{ request.method }}</p>--> <!-- <p>session: {{ session }}</p>--> <!-- <p>g: {{ g }}</p>--> <!--<hr />--> <!--<p>my_func(): {{ my_func() }}</p>--> <!--<hr />--> <!--{% for i in range(10) %}--> <!--{{ i }}--> <!--{% endfor %}--> <!--<hr />--> <!--<!–随机函数,最小是10个单词数,最大是20单词数,n是2行即为2段,flase的话没有p标签–>--> <!--{{ lipsum(n=2, html=True, min=10, max=20) }}--> <!--<hr />--> <!--{{ dict(a=1,b=2) }}--> <!--<hr />--> <!--<h1>Hello {{ name|d("陌生人")|title }}</h1>--> <!--<h1>max of [1,2,3,4] {{ [1,2,3,4]|max() }}</h1>--> <!--<h1>first of [1,2,4] {{ [1,2,3]|first() }}</h1>--> <!--<hr />--> {% set name='beautiful' %} <h1>Hello, {{ name|title|upper|length|filterMusical }}!</h1> <hr /> {% set age="123" %} {% if age is number %} age*365等于: {{ age * 365 }} {% else %} 无效的数字 {% endif %} <hr /> <p> foo |smiling: {{ foo|smiling }}</p> <hr /> {% if "baz" is baz() %} baz is baz() {% endif %} </body> </html>
运行效果:

三、模板结构组织
3.1局部模板
为了和普通模板区分开,局部模板的命名通常以一个下划线开始。
示例:
新建_banner.html局部模板文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>测试局部模板</title> </head> <body> <p>©2022<a href="https://www.cnblogs.com/rychh/" title="博客">博客地址</a> <a href="https://github.com/RenYchh" title="GitHub">GitHub地址</a> <a href="http://helloflask.com" title="Hello Flask project">Learning HelloFalsk</a> </p> </body> </html>
新建macros.html
{% macro qux(amount=1) %} {% if amount == 1 %} I am qux. {% elif amount > 1 %} We are quxs. {% endif %} {% if amount > 1 %} We are quxs again. {% endif %} {% endmacro %} {% macro static_file(type, filename_or_url, local=True) %} {% if local %} {% set filename_or_url = url_for('static', filename=filename_or_url) %} {% endif %} {% if type == 'CSS' %} <link rel="stylesheet" href="{{ filename_or_url }}" type="text/css"> {% elif type == 'js' %} <scirpt type ="text/javascript" src="{{ filename_or_url }}"></scirpt> {% elif type == 'icon' %} <link rel="icon" href="{{ filename_or_url }}"> {% endif %} {% endmacro %}
四、宏(类似于一个方法、函数)
宏(macro)是jinja2提供的一个非常有用的特性,它类似python中的函数。使用宏可以把一部分模板代码封装到宏里,使用传递的参数来构建内容,最后返回构建后的内容。在功能上,它和局部模板类似,都是为了方便代码块的重用。
为了便于管理,可以把宏存储在单独的文件中,这个文件通常命名为macros.html或_macros.html。在创建宏时,使用macro和endmacro标签声明宏的开始和结束。在开始标签中定义宏的名称和接收的参数
Index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> <!-- <p>hello {{ name }}</p>--> <!-- {% set navigation %}--> <!-- <li><a href="{{ url_for('watchlist') }}">Watchlist</a></li>--> <!-- <li><a href="{{ url_for('hello') }}">Hello</a></li>--> <!-- {% endset %}--> <!-- {{ navigation }}--> <!-- <hr />--> <!-- <p>config: {{ config }}</p>--> <!-- <p>config.DEBUG: {{ config.DEBUG }}</p>--> <!-- <p>request: {{ request }}</p>--> <!-- <p>request.method: {{ request.method }}</p>--> <!-- <p>session: {{ session }}</p>--> <!-- <p>g: {{ g }}</p>--> <!--<hr />--> <!--<p>my_func(): {{ my_func() }}</p>--> <!--<hr />--> <!--{% for i in range(10) %}--> <!--{{ i }}--> <!--{% endfor %}--> <!--<hr />--> <!--<!–随机函数,最小是10个单词数,最大是20单词数,n是2行即为2段,flase的话没有p标签–>--> <!--{{ lipsum(n=2, html=True, min=10, max=20) }}--> <!--<hr />--> <!--{{ dict(a=1,b=2) }}--> <!--<hr />--> <!--<h1>Hello {{ name|d("陌生人")|title }}</h1>--> <!--<h1>max of [1,2,3,4] {{ [1,2,3,4]|max() }}</h1>--> <!--<h1>first of [1,2,4] {{ [1,2,3]|first() }}</h1>--> <!--<hr />--> {% set name='beautiful' %} <h1>Hello, {{ name|title|upper|length|filterMusical }}!</h1> <hr /> {% set age="123" %} {% if age is number %} age*365等于: {{ age * 365 }} {% else %} 无效的数字 {% endif %} <hr/> {% set name="beautiful girl" %} <h1>Hello,{{ name|title|upper|length }}</h1> <hr/> {% set age="123" %} {% set foo="123" %} {% if age is sameas foo %} age 等于 foo {% else %} age 不等于 foo {% endif %} {% include "_banner.html" %} {% from "macros.html" import qux with context %} {{ qux(amount=5) }} </body> </html>
运行结果:

若模板语法没有高亮,类似于下面白的

可进行设置(社区办没有,专业版有该选项)

修改下macros.html文件内容
{% macro qux(amount=1) %} {% if amount == 1 %} i am qux {% elif amount > 1 %} we are quex {{ my_func() }} {% endif %} {% endmacro %} {% macro static_file(type, filename_or_url, local=True) %} {% if local %} {% set filename_or_url = url_for('static', filename=filename_or_url) %} {% endif %} {% if type == 'CSS' %} <link rel="stylesheet" href="{{ filename_or_url }}" type="text/css"> {% elif type == 'js' %} <scirpt type ="text/javascript" src="{{ filename_or_url }}"></scirpt> {% elif type == 'icon' %} <link rel="icon" href="{{ filename_or_url }}"> {% endif %} {% endmacro %}

说明:


新建macro.html
{% macro qux(amount=1) %}
{% if amount == 1 %}
i am qux
{% elif amount > 1 %}
we are quex
{{ arg1 }}
{% endif %}
{% endmacro %}
Index.html
{% from "macros.html" import qux with context %}
{{ qux(amount=5) }}
运行效果:


五、基模板和子模板
5.1新建base.html文件(基模板相关)
<!DOCTYPE html> <html lang="en"> <head> {% block head %} <meta charset = "utf-8"> <head>{% block title %}Template - HelloFlask {% endblock %} {% block styles %}{% endblock %} {% endblock %} </head> <body> <nav> <ul><li><a href="{{ url for('index')}}">Home</a></li></ul> </nav> <main> {% block content %} {% endblock %} </main> <footer> {% block footer %} {% endblock %} </footer> {% block script %}{% endblock %} </body> </html>
新建index.html
{% extends 'base.html' %} {% from 'macros.html' import qux %} {% block content %} {% set name = 'baz' %} <h1> Template </h1> <ul> <li><a href= '{{ url for('watchlist')}}'>Watchlist</a></li>li> <li>Filter:{{ foo|musical }}</li> <li>Global:{{ barfunc() }}</li> <li>Test:{% if name is baz %}I am baz.{ % endif %}</li> <li>Macro:{{ qux(amount=5) }}</li> </ul> {% endblock %}
六、编写子模板
因为基模板中定义了HTML的基本结构,而且包含了页脚等固定信息,在子模板中我们不再需要定义这些内容,只需要对特定的块进行修改。这时我们可以修改前面创建的电影清单模板watchlist.html和主页模板index.html,将这些子模板的通用部分合并到基模板中,并在子模板中定义块来组织内容,以便在渲染时将块中的内容插入到基模板的对应位置。
以index.html为例,修改后的index.html子模板如下
index.html:
{% extends "base.html" %} {% from "macros.html" import qux with context%} {% block content %} {% set name="baz" %} {% set foo="foo" %} <h1>Template</h1> <ul> <li><a href="{{ url_for("watchlist") }}">Watchlist</a></li> <li>Filter:{{ foo|musical }}</li> <li>Global:{{ barfunc() }}</li> <li>Test:{% if name is baz %} I am baz. {% endif %}</li> <li>Macro: {{ qux(amount=5) }}</li> </ul> {% endblock %}
base.html
<!DOCTYPE html> <html lang="en"> <head> {% block head %} <meta charset = "utf-8"> <head>{% block title %}Template - HelloFlask {% endblock %} {% block styles %}{% endblock %} {% endblock %} </head> <body> <nav> <ul><li><a href="{{ url_for('index')}}">Home</a></li></ul> </nav> <main> {% block content %} {% endblock %} </main> <footer> {% block footer %} {% endblock %} </footer> {% block script %}{% endblock %} </body> </html>
Macros.html
{% macro qux(amount=1) %} {% if amount == 1 %} i am qux {% elif amount > 1 %} we are quex {{ arg1 }} {% endif %} {% endmacro %} {% macro static_file(type, filename_or_url, local=True) %} {% if local %} {% set filename_or_url = url_for('static', filename=filename_or_url) %} {% endif %} {% if type == 'CSS' %} <link rel="stylesheet" href="{{ filename_or_url }}" type="text/css"> {% elif type == 'js' %} <scirpt type ="text/javascript" src="{{ filename_or_url }}"></scirpt> {% elif type == 'icon' %} <link rel="icon" href="{{ filename_or_url }}"> {% endif %} {% endmacro %}
App.py
#encoding=utf-8 from flask import Flask,render_template,session from flask import Markup, flash, redirect, url_for,render_template_string import os app = Flask(__name__) @app.route("/baidu") def baidu(): return redirect("https://www.sogou.com") @app.route('/index/') def index(): #flash('I am flash, who is looking for me?') return render_template('index.html',arg1="hello") @app.context_processor def inject_foo(): return dict(my_func=my_func) def my_func(): return "this is my_func" @app.template_filter() def musical(s): return s + Markup('♫') @app.template_test() def baz(n): if n == "baz": return True return False @app.route("/watchlist") def watchlist(): return render_template_string( '''{% for movie in movies %} <li>{{ movie.name }} - {{ movie.year }}</li> % endfor %}''', movies=movies) user = { "username" : "huhongqiang", "bio" : "读书和运动必须有一个在路上" } movies = [ {"name":"huanghuang","year":"2018"}, {"name":"kongsuhong","year":"2019"}, {"name":"weixingguang","year":"2019"} ] @app.template_global(name="barfunc") def bar(): return "I am bar" if __name__ == '__main__': app.run(debug=True)
访问index.html



设置颜色格式
Index.html
{% extends "base.html" %} {% from "macros.html" import qux with context%} {% block content %} {% set name="baz" %} {% set foo="foo" %} <h1>Template</h1> <ul> <li><a href="{{ url_for("watchlist") }}">Watchlist</a></li> <li>Filter:{{ foo|musical }}</li> <li>Global:{{ barfunc() }}</li> <li>Test:{% if name is baz %} I am baz. {% endif %}</li> <li>Macro: {{ qux(amount=5) }}</li> </ul> {% block styles %} {{ super() }} <style> foo{ color :red; } </style> {% endblock %} {% endblock %}
Base.html
<!DOCTYPE html> <html lang="en"> <head> {% block head %} <meta charset = "utf-8"> <head>{% block title %}Template - HelloFlask {% endblock %} {% block styles %}sssssssssss{% endblock %} {% endblock %} </head> <body> <nav> <ul><li><a href="{{ url_for('index')}}">Home</a></li></ul> </nav> <main> {% block content %} {% endblock %} </main> <footer> {% block footer %} {% endblock %} </footer> {% block script %}{% endblock %} </body> </html>
运行结果:

仅仅修改index.html(注释掉super方法的调用)
{% extends "base.html" %} {% from "macros.html" import qux with context%} {% block content %} {% set name="baz" %} {% set foo="foo" %} <h1>Template</h1> <ul> <li><a href="{{ url_for("watchlist") }}">Watchlist</a></li> <li>Filter:{{ foo|musical }}</li> <li>Global:{{ barfunc() }}</li> <li>Test:{% if name is baz %} I am baz. {% endif %}</li> <li>Macro: {{ qux(amount=5) }}</li> </ul> {% block styles %} <!--{{ super() }}--> <style> foo{ color :red; } </style> {% endblock %} {% endblock %}
运行结果:

6.1子模板生效
修改index文件内容
取消super()的注释——super()含义:定义、追加(子模板的内容追加到积模板后面)
{% extends "base.html" %} {% from "macros.html" import qux with context%} {% block content %} {% set name="baz" %} {% set foo="foo" %} <h1>Template</h1> <ul> <li><a href="{{ url_for("watchlist") }}">Watchlist</a></li> <li>Filter:{{ foo|musical }}</li> <li>Global:{{ barfunc() }}</li> <li>Test:{% if name is baz %} I am baz. {% endif %}</li> <li>Macro: {{ qux(amount=5) }}</li> </ul> {% block styles %} {{ super() }} <style> foo{ color :red; } </style> {% endblock %} {% endblock %}
运行效果:

子模板生效
修改base.html文件——基模板
<!DOCTYPE html> <html lang="en"> <head> {% block head %} <meta charset = "utf-8"> <head>{% block title %}Template - HelloFlask {% endblock %} {% block styles %}sssssssssss{% endblock %} {% endblock %} </head> <body> <nav> <ul><li><a href="{{ url_for('index')}}">Home</a></li></ul> </nav> <main> {% block content %} something {% endblock %} </main> <footer> {% block footer %} {% endblock %} </footer> {% block script %}{% endblock %} </body> </html>
修改index.html——子模板
{% extends "base.html" %} {% from "macros.html" import qux with context%} {% set foo="foo" %} <h1>Template</h1> <ul> <li><a href="{{ url_for("watchlist") }}">Watchlist</a></li> <li>Filter:{{ foo|musical }}</li> <li>Global:{{ barfunc() }}</li> <li>Test:{% if name is baz %} I am baz. {% endif %}</li> <li>Macro: {{ qux(amount=5) }}</li> </ul> {% block styles %} {{ super() }} <style> foo{ color :red; } </style> {% endblock %} {% block content %} {{ super() }} sdsdssffsdadadaddadda {% endblock %}
运行结果:

去掉index.html中的super()的效果

空白控制
Index.html内容
{{ super() -}}在后面:——可去掉语句后面的空白;在前面:——去掉语句前面的空白
如果想再渲染时自动去掉空行,可以在定界符内侧添加减号。比如{%-endfor%}会移除该语句前的空白,同理,在右边的定界符内侧添加减号将移除该语句后的空白:
示例:
在watchlist.html中添加一段代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{{ user.username }}'s Watchlist</title> <styles> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename= 'style.css' ) }}"> </styles> </head> <body> <a href = "{{ url_for('index') }}">← Return</a> <h2><img src="{{ url_for('static', filename='qq.jpg') }}" width="50">{{ user.username }}</h2> {% if user.bio %} <i>{{ user.bio }}</i> {% else %} <i>This user has not provided a bio.</i> {% endif %} {% set age = 23 %} {% if age > 10 %} <i>{{ user.username }} can play the game</i> {% endif %} {% if age >20 %} <i>{{ user.username }}can paly the game only 10 minutes! </i> {% endif %} {# 下面是电影清单(这是注释) #} <h5>{{ user.username }}'s Watchlist ({{ movies|length }}):</h5> <ul> {% for movie in movies %} <li>{{ movie.name }} - {{ movie.year }}</li> {% endfor %} </ul> </body> </html>
App.py
@app.route("/watchlist") def watchlist(): return render_template("watchlist.html", user=user,movies=movies) user = { "username" : "huhongqiang", "bio" : "读书和运动必须有一个在路上" } movies = [ {"name":"huanghuang","year":"2018"}, {"name":"kongsuhong","year":"2019"}, {"name":"weixingguang","year":"2019"} ]
访问效果:

模板中添加减号
{%- if age > 10 %} <i>{{ user.username }} can play the game</i> {% endif %} {%- if age >20 %} <i>{{ user.username }}can paly the game only 10 minutes! </i> {% endif %}
除了在模板中使用减号来控制空白,也可以使用模板环境对象提供的trim_blocks和lstrip_blocks属性设置,前者用来删除jinja2语句后的第一个空行,后者则用来删除jinja2语句所在行之前的空格和制表符(tab):
app.jinja_env.trim_blocks = True
app.jinja_env.lstrip_blocks = True
trim_blocks中的block指的是使用{% … %}定界符的代码块,与模板继承中的块无关
app.py中加入
app = Flask(__name__) app.jinja_env.trim_blocks = True app.jinja_env.lstrip_blocks = True
七、加载静态文件
一个Web项目不仅需要HTML模板,还需要许多静态文件,比如CSS、JavaScript文件、图片和声音声。在flask程序中,默认需要将静态文件存储在与主脚本(包含程序实例的脚本)同级目录的static文件夹中。
为了在HTML文件中引用静态文件,我们需要使用url_for()函数获取静态文件的URL。
flask内置了用于获取静态文件的视图函数,端点值为static,它的默认URL规则为/static/<path: filename>,URL变量filename是相对于文件夹根目录的文件路径。
如果需要使用其他文件夹来存储静态文件,可以在实例化flask类时使用static_folder参数指定,静态文件的URL路径中的static也会自动跟随文件夹名称变化。
在实例化flask类时用static_url_path参数可以自定义静态文件的URL路径。
如:app = Flask(__name__, static_folder='static2',static_url_path='/static3')
用static_folder参数指定静态资源的路径,修改了这个参数之后,url规则默认会自动修改为文件夹名称
用static_url_path指定内置的获取静态文件的视图函数的url规则
在虚拟环境中看下flask routes:
不修改static_folde和static_url_path参数时,静态文件路径和url规则默认为static
在程序的static目录下存一张图片,例如qq.jpg,我们可以通过url_for(‘static’, filename=’qq.jpg’)获取这个文件的URL,这个函数调用生成的url为/static/qq.jpg,在浏览器中输入127.0.0.1:5000/qq.jpg即可访问这个图片。
修改了static_folde和static_url_path参数再次访问
app = Flask(__name__,static_folder="static2",static_url_path="/static3")
八、消息闪现(未生效,先忽略)
flash函数——闪现,用户消息
App.py内容
#encoding=utf-8 from flask import Flask, render_template, session from flask import Markup, flash, redirect, url_for import os app = Flask(__name__) app.secret_key = os.getenv('SECRET_KEY', 'secret string') @app.route('/flash') def just_flash(): flash('I am flash, who is looking for me?') return redirect(url_for('index')) @app.template_test() def baz(n): if n == 'baz': return True return False @app.template_filter() def musical(s): return str(s) + Markup(' ♫') @app.template_global() def bar(): return 'I am bar.' @app.context_processor def inject_foo(): return dict(my_func=my_func) def my_func(): return "this is my_func~" @app.template_global(name='barfunc') def bar(): return 'I am bar.' @app.route('/index/') def index(): flash('I am flash, who is looking for me?') return render_template('index.html', arg1='hello') @app.context_processor def inject_foo(): foo = 'I am foo.' return dict(foo=foo) # 等同于return {'foo': foo} @app.route('/watchlist') def watchlist(): return render_template('watchlist.html', user=user, movies=movies) @app.route('/hello') def hello(): return "hello flask" user = { 'username': 'xiaxiaoxu', 'bio': 'A man who loves 看电影.' } movies = [ {'name': 'My Neighbor Totoro', 'year': '1988'}, {'name': 'Three Colours trilogy', 'year': '1993'}, {'name': 'Forrest Gump', 'year': '1994'}, {'name': 'Perfect Blue', 'year': '1997'}, {'name': 'The Matrix', 'year': '1999'}, {'name': 'Memento', 'year': '2000'}, {'name': 'The Bucket list', 'year': '2007'}, {'name': 'Black Swan', 'year': '2010'}, {'name': 'Gone Girl', 'year': '2014'}, {'name': 'CoCo', 'year': '2017'}] @app.route('/testJinja') def testJinja(): return render_template('testJinja.html', my_list=my_list, my_tuple=my_tuple, my_dict=my_dict, my_func=my_func, my_object=my_object) my_list = [1, 2, 3, 4] my_tuple = ('a', 'b', 'c', 'd') my_dict = {'d1': 'abc', 'd2': 'bcd', 'd3': 'cde'} my_object = "my_object" if __name__ == '__main__': app.run(debug=True)
Watchlist.html内容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{{ user.username }}'s Watchlist</title> <styles> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename= 'style.css' ) }}"> </styles> </head> <body> <a href = "{{ url_for('index') }}">← Return</a> <h2><img src="{{ url_for('static', filename='qq.jpg') }}" width="50">{{ user.username }}</h2> {% if user.bio %} <i>{{ user.bio }}</i> {% else %} <i>This user has not provided a bio.</i> {% endif %} {# 下面是电影清单(这是注释) #} <h5>{{ user.username }}'s Watchlist ({{ movies|length }}):</h5> <ul> {% for movie in movies %} <li>{{ movie.name }} - {{ movie.year }}</li> {% endfor %} </ul> </body> </html>
Base.html内容
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> {% block head %} <title>{% block title %}Template - HelloFlask{% endblock %}</title> <link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='favicon.ico') }}"> {% block styles %} <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css' ) }}"> {% endblock %} {% endblock %} </head> <body> <nav> <ul><li><a href="{{ url_for('index') }}">Home</a></li></ul> </nav> <main> {% for message in get_flashed_messages() %} <div class="alert">{{ message }}</div> {% endfor %} {% block content %}{% endblock %} </main> <footer> {% block footer %} <small> © 2019 <a href="https://www.cnblogs.com/xiaxiaoxu/" title="xiaxiaoxu's blog">任永成的博客</a> / <a href="https://github.com/xiaxiaoxu/hybridDrivenTestFramework" title="Contact me on GitHub">GitHub</a> / <a href="http://helloflask.com" title="A HelloFlask project">Learning from GreyLi's HelloFlask</a> </small> {% endblock %} </footer> {% block scripts %}{% endblock %} </body> </html>
Index.html文件内容(未有更新)
{% extends 'base.html' %} {% from 'macros.html' import qux %} {% block content %} {% set name='baz' %} <h1>Template</h1> <ul> <li><a href="{{ url_for('watchlist') }}">Watchlist</a></li> <li><a href="{{ url_for('hello') }}">Hello Flask</a></li> <li>Filter: {{ foo|musical }}</li> <li>Global: {{ bar() }}</li> <li>Test: {% if name is baz %}I am baz.{% endif %}</li> <li>Macro: {{ qux(amount=1) }}</li> <li><a href="{{ url_for('just_flash') }}">Flash something</a></li> </ul> {% endblock %} macros.html {% macro qux(amount=1) %} {% if amount == 1 %} I am qux. {% elif amount > 1 %} We are quxs. {% endif %} {% if amount > 1 %} We are quxs again. {% endif %} {% endmacro %} {% macro static_file(type, filename_or_url, local=True) %} {% if local %} {% set filename_or_url = url_for('static', filename=filename_or_url) %} {% endif %} {% if type == 'CSS' %} <link rel="stylesheet" href="{{ filename_or_url }}" type="text/css"> {% elif type == 'js' %} <scirpt type ="text/javascript" src="{{ filename_or_url }}"></scirpt> {% elif type == 'icon' %} <link rel="icon" href="{{ filename_or_url }}"> {% endif %} {% endmacro %}
运行效果


浙公网安备 33010602011771号