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 />-->
<!--&lt;!&ndash;随机函数,最小是10个单词数,最大是20单词数,n是2行即为2段,flase的话没有p标签&ndash;&gt;-->
    <!--{{ 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(' &#9835;')


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 />-->
<!--&lt;!&ndash;随机函数,最小是10个单词数,最大是20单词数,n是2行即为2段,flase的话没有p标签&ndash;&gt;-->
    <!--{{ 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>&copy;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。在创建宏时,使用macroendmacro标签声明宏的开始和结束。在开始标签中定义宏的名称和接收的参数

 

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 />-->
<!--&lt;!&ndash;随机函数,最小是10个单词数,最大是20单词数,n是2行即为2段,flase的话没有p标签&ndash;&gt;-->
    <!--{{ 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('&#9835;')

@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') }}">&larr; 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_blockslstrip_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(' &#9835;')


@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') }}">&larr; 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> &copy; 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 %}

 

运行效果

 

posted @ 2022-04-25 00:45  翻滚的小强  阅读(99)  评论(0)    收藏  举报