zoukankan      html  css  js  c++  java
  • Flask07 Jinja2模板测试器、控制语句IF/FOR、变量/块 赋值、作用域、块级作用域

    1 测试器及其使用

      在模板中的 {{}} 可以书写测试器,格式如下

        {{ 变量 is 测试器名称  }}

      1.1 在python中导入 Jinja2 的模板

        from jinja2 import tests

          注意:其实这一步是不需要的,导入的目的是为了查看那些测试器的源代码

    # -*- coding: utf-8 -*-
    """
        jinja2.tests
        ~~~~~~~~~~~~
    
        Jinja test functions. Used with the "is" operator.
    
        :copyright: (c) 2017 by the Jinja Team.
        :license: BSD, see LICENSE for more details.
    """
    import re
    from collections import Mapping
    from jinja2.runtime import Undefined
    from jinja2._compat import text_type, string_types, integer_types
    import decimal
    
    number_re = re.compile(r'^-?d+(.d+)?$')
    regex_type = type(number_re)
    
    
    test_callable = callable
    
    
    def test_odd(value):
        """Return true if the variable is odd."""
        return value % 2 == 1
    
    
    def test_even(value):
        """Return true if the variable is even."""
        return value % 2 == 0
    
    
    def test_divisibleby(value, num):
        """Check if a variable is divisible by a number."""
        return value % num == 0
    
    
    def test_defined(value):
        """Return true if the variable is defined:
    
        .. sourcecode:: jinja
    
            {% if variable is defined %}
                value of variable: {{ variable }}
            {% else %}
                variable is not defined
            {% endif %}
    
        See the :func:`default` filter for a simple way to set undefined
        variables.
        """
        return not isinstance(value, Undefined)
    
    
    def test_undefined(value):
        """Like :func:`defined` but the other way round."""
        return isinstance(value, Undefined)
    
    
    def test_none(value):
        """Return true if the variable is none."""
        return value is None
    
    
    def test_lower(value):
        """Return true if the variable is lowercased."""
        return text_type(value).islower()
    
    
    def test_upper(value):
        """Return true if the variable is uppercased."""
        return text_type(value).isupper()
    
    
    def test_string(value):
        """Return true if the object is a string."""
        return isinstance(value, string_types)
    
    
    def test_mapping(value):
        """Return true if the object is a mapping (dict etc.).
    
        .. versionadded:: 2.6
        """
        return isinstance(value, Mapping)
    
    
    def test_number(value):
        """Return true if the variable is a number."""
        return isinstance(value, integer_types + (float, complex, decimal.Decimal))
    
    
    def test_sequence(value):
        """Return true if the variable is a sequence. Sequences are variables
        that are iterable.
        """
        try:
            len(value)
            value.__getitem__
        except:
            return False
        return True
    
    
    def test_equalto(value, other):
        """Check if an object has the same value as another object:
    
        .. sourcecode:: jinja
    
            {% if foo.expression is equalto 42 %}
                the foo attribute evaluates to the constant 42
            {% endif %}
    
        This appears to be a useless test as it does exactly the same as the
        ``==`` operator, but it can be useful when used together with the
        `selectattr` function:
    
        .. sourcecode:: jinja
    
            {{ users|selectattr("email", "equalto", "foo@bar.invalid") }}
    
        .. versionadded:: 2.8
        """
        return value == other
    
    
    def test_sameas(value, other):
        """Check if an object points to the same memory address than another
        object:
    
        .. sourcecode:: jinja
    
            {% if foo.attribute is sameas false %}
                the foo attribute really is the `False` singleton
            {% endif %}
        """
        return value is other
    
    
    def test_iterable(value):
        """Check if it's possible to iterate over an object."""
        try:
            iter(value)
        except TypeError:
            return False
        return True
    
    
    def test_escaped(value):
        """Check if the value is escaped."""
        return hasattr(value, '__html__')
    
    
    def test_greaterthan(value, other):
        """Check if value is greater than other."""
        return value > other
    
    
    def test_lessthan(value, other):
        """Check if value is less than other."""
        return value < other
    
    
    TESTS = {
        'odd':              test_odd,
        'even':             test_even,
        'divisibleby':      test_divisibleby,
        'defined':          test_defined,
        'undefined':        test_undefined,
        'none':             test_none,
        'lower':            test_lower,
        'upper':            test_upper,
        'string':           test_string,
        'mapping':          test_mapping,
        'number':           test_number,
        'sequence':         test_sequence,
        'iterable':         test_iterable,
        'callable':         test_callable,
        'sameas':           test_sameas,
        'equalto':          test_equalto,
        'escaped':          test_escaped,
        'greaterthan':      test_greaterthan,
        'lessthan':         test_lessthan
    }
    所有测试器的源代码

        

      1.2 直接在模板的 {{}} 中书写书写对应的测试器即可    

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>demo01</title>
    </head>
    <body>
        <h2>测试器</h2>
        <hr />
    
        <h3>测试odd/even</h3>
        <p>{{ 3 is odd }}</p>
        <p>{{ 4 is even }}</p>
        <p>
            {% if (var01 is even) %}
                var01是偶数
            {% else %}
                var01不是偶数
            {% endif %}
        </p>
        <hr />
    
        <h3>测试test_divisibleby</h3>
        <p>
            {{ 4 is divisibleby 2 }}
            <br />
            {% if (var02 is divisibleby 2) %}
                var02能被2整除
            {% endif %}
        </p>
        <hr />
    
        <h3>测试test_defined/test_undefined</h3>
        <p>
            {{ var03 is defined }}
            <br />
            {% if var03 is defined %}
                var03已经被定义
            {% endif %}
            <br />
            {{ var04 is undefined }}
            <br />
            {% if var04 is undefined %}
                var04没有被定义
            {% endif %}
        </p>
        <hr />
    
        <h3>测试test_none</h3>
        <p>
            {{ var05 is none }}
            <br />
            {% if var05 is none %}
                var05的值是None
            {% endif %}
        </p>
        <hr />
    
        <h3>测试test_lower/test_upper</h3>
        <p>
            {{ var06 is lower }}
            <br />
            {% if var06 is lower %}
                var06的值全是小写
            {% endif %}
            <br />
            {{ var07 is upper }}
            <br />
            {% if var07 is upper %}
                var07的值全是大写
            {% endif %}
        </p>
        <hr />
    
        <h3>测试test_string</h3>
        <p>
            {{ var08 is string }}
            <br />
            {% if var08 is string %}
                var08的值是一个字符串
                {% else %}
                var08的值不是一个字符串
            {% endif %}
        </p>
        <hr />
    
        <h3>测试test_mapping</h3>
        <p>
            {{ var09 is mapping }}
            <br />
        </p>
        <hr />
    
        <h3>测试test_number</h3>
        <p>
            {{ var10 is number }}
            <br />
        </p>
        <hr />
    
        <h3>测试test_sequence</h3>
        <p>
            {{ var11 is sequence }}
            <br />
        </p>
        <hr />
    
        <h3>测试test_equalto</h3>
        <p>
            {{ var12 is equalto 'zeus' }}
            <br />
            {% if var12 is equalto 'zeus' %}
                var12的值是zeus
            {% endif %}
        </p>
        <hr />
    
        <h3>测试test_sameas</h3>
        <p>
            {{ var13 is sameas false }}
        </p>
        <hr />
    
        <h3>测试test_iterable</h3>
        <p>
            {{ var14 is iterable }}
        </p>
        <hr />
    
        <h3>测试test_escaped</h3>
        <p>
            {{ var15 is escaped }}
        </p>
        <hr />
    
        <h3>测试test_greaterthan</h3>
        <p>
            {{ 3 is greaterthan 2 }}
        </p>
        <hr />
    
        <h3>测试test_lessthan</h3>
        <p>
            {{ 3 is lessthan 4 }}
        </p>
    
    
    
    {#    <h3>notes</h3>#}
        <p>
    {#        {{ loop.length }}   循环总次数#}
    {#        {{ loop.index }}  当前次数,下标从1开始#}
    {#        {{ loop.index0 }} 当前次数,下标从0开始#}
    {#        {{ loop.reindex }} 当前次数反向#}
    {#        {{ loop.cycle('a','b','c') }}  循环自动返回元素  #}
    {#        {{ loop.first }} 首次迭代时返回true#}
    {#        {{ loop.last }} 首次迭代是返回false#}
        </p>
    </body>
    </html>
    html模板代码
    from flask import Blueprint
    from flask import render_template
    # from jinja2 import tests
    
    bp_test = Blueprint('test', __name__)
    
    @bp_test.route('/test/')
    def test():
        content = {
            'name':'warrior',
            'var01': 3,
            'var02': 4,
            'var03': 5,
            'var05': None,
            'var06': 'warrior',
            'var07': 'WARRIOR',
            'var08': 234,
            'var09': {
                'name':"fury"
            },
            'var10': 14,
            'var11': 1324,
            'var12': 'zeus',
            'var13': False,
            'var14': 'warrior',
            'var15': 'good'
        }
        resp = render_template('demo01.html', **content)
        return resp
    蓝图代码
    from flask import Flask
    from flask import render_template
    from jinja2 import tests
    
    from demo01 import bp_test
    
    app = Flask(__name__)
    
    app.register_blueprint(bp_test)
    
    # @app.route('/')
    # def hello_world():
    #     resp = render_template('index.html', info='warrior')
    #     return resp
    
    print(app.url_map)
    
    if __name__ == '__main__':
        app.run(debug=True)
    python代码

    2 控制语句

      在控制语句上的表达式不用写在 {{ }} 中;但是在控制语句中的表达式必须写在 {{ }} 中

      

      2.1 IF控制语句

    {% if var01 < 5 %}
                条件1成立
                {% elif var01 < 10 %}
                条件2成立
                {% else %}
                条件1和2都不成立
    {% endif %}

      2.2 FOR控制语句

    % for foo in ['warrior', 'fury', 'zeus'] %}
                {{ foo }} <br />
    {% endfor %}

      注意:在python代码中 for 和 else 搭配是循环完毕后执行else后面的语句;但是在Jinja2模板中却只有0次迭代(即:不进行迭代)时执行else后面的语句

    {% for foo in var02 if foo == 'mother' %}
                {{ foo }} <br />
                {% else %}
                在var02中没有满足条件的元素
    {% endfor %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Controller</title>
    </head>
    <body>
        <h2>测试流程控制语句</h2>
        <hr />
    
        <h4>测试IF语句</h4>
        <p>
            {% if var01 < 5 %}
                条件1成立
                {% elif var01 < 10 %}
                条件2成立
                {% else %}
                条件1和2都不成立
            {% endif %}
        </p>
        <hr />
    
        <h4>测试FOR语句</h4>
        <p>
            {% for foo in ['warrior', 'fury', 'zeus'] %}
                {{ foo }} <br />
            {% endfor %}
            <hr />
            {% for foo in var02 if foo == 'mother' %}
                {{ foo }} <br />
                {% else %}
                在var02中没有满足条件的元素
            {% endfor %}
        </p>
    </body>
    </html>
    html模板
    from flask import Blueprint
    from flask import render_template
    
    bp_controller = Blueprint('controller', __name__)
    
    @bp_controller.route('/controller/')
    def control():
        content = {
            'var01': 199,
            'var02': ['good', 'boy']
        }
        resp = render_template('controller.html', **content)
        return resp;
    蓝图代码
    from flask import Flask
    from flask import render_template
    from jinja2 import tests
    
    # from testor import bp_test
    from controller import bp_controller
    
    app = Flask(__name__)
    
    # app.register_blueprint(bp_test)
    app.register_blueprint(bp_controller)
    
    # @app.route('/')
    # def hello_world():
    #     resp = render_template('index.html', info='warrior')
    #     return resp
    
    print(app.url_map)
    
    if __name__ == '__main__':
        app.run(debug=True)
    python代码

         2.2.1 FOR循环的补充

        <p>
    {#        {{ loop.length }}   循环总次数#}
    {#        {{ loop.index }}  当前次数,下标从1开始#}
    {#        {{ loop.index0 }} 当前次数,下标从0开始#}
    {#        {{ loop.reindex }} 当前次数反向#}
    {#        {{ loop.cycle('a','b','c') }}  循环自动返回元素  #}
    {#        {{ loop.first }} 首次迭代时返回true#}
    {#        {{ loop.last }} 首次迭代是返回false#}
        </p>
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>测试模板</title>
    </head>
    <body>
        <h2>这里是测试模板的内容</h2>
        {% for foo in range(10) %}
    {#        <li>当前次数(从1开始):{{ loop.index }} --> 内容:{{ foo }}</li>#}
            <li>当前次数(从0开始):{{ loop.index0 }} --> 内容:{{ foo }}</li>
    {#        <h2>{{ loop.length }}</h2>#}
    {#        {{ loop.first }} #}
    {#        {{ loop.last }}#}
        {% endfor %}
    
    </body>
    </html>
    html模板
    from flask import Blueprint
    from flask import render_template
    
    bp_test = Blueprint('test', __name__, url_prefix='/test')
    
    @bp_test.route('/test/')
    def test():
        return render_template('test.html')
    蓝图代码
    from flask import Flask
    from flask import url_for
    
    # from bp_include import bp_test
    # from bp_extends import bp_extends
    from bp_test import bp_test
    
    app = Flask(__name__)
    
    # app.register_blueprint(bp_test)
    # app.register_blueprint(bp_extends)
    app.register_blueprint(bp_test)
    
    
    @app.route('/')
    def hello_world():
        return 'Hello World!'
    
    print(app.url_map)
    
    if __name__ == '__main__':
        app.run(debug=True)
    python代码

    3 赋值

      3.1 变量赋值

        {% set 变量名 =  值 %}

    <h4>变量赋值</h4>
        <p>
            {% set student = 'warrior' %}
            学生姓名:{{ student }}
            <hr />
            {% set students = ['fury','zeus','warrior'] %}
            <p>
                {% for student in students %}
                    {{ student }} <br />
                {% endfor %}
    
            </p>
        </p>

      3.2 块赋值

    <h4>块赋值</h4>
        <p>
            {% set xxx %}
                <li>Hello Boy</li>
                <li>Hello World</li>
            {% endset %}
            {{ xxx }}
        </p>

    4 作用域

      IF语句没有作用域,FOR语句有作用域;其它的{% %}通常产生作用域

      4.1 测试IF语句没有作用域

        

      4.2 设置IF语句的作用域

        利用块级作用域来设置IF语句的作用域

        

      4.3 测试FOR语句有作用域

        

      

    5 块级作用域

    {% with %}
        块级作用域中的内容
    {% endwith %}

      5.1 不要在with上这样写

          

          会出现以下的报错信息

            

              原因:造成了变量污染

      5.2 解决办法

        

     1 流程控制:
     2     if
     3         测试
     4             测试器(一个函数) from jinja2 import tests
     5             is 后面跟的必须是个测试器
     6 
     7     for
     8         和else搭配 不是表示正常迭代完
     9         而是表示 0次迭代,或全部被 if 过滤  {% for i in xxx if ... %}
    10 
    11 
    12 赋值:
    13     变量赋值
    14     块赋值
    15 
    16     好处:
    17         1.中间变量
    18         2.方便测试
    19 
    20 作用域:
    21     if不产生作用域
    22     for 产生作用域
    23     其他的{% %}通常产生作用域
    24 
    25 构造局部作用域
    26     with
    27         不要在 with 写这种 :  {% with name=[1,2], xx=name[1] %}
    28 
    29 
    30         应该要
    31             {% with name=[1,2]
    32                 {% set xx=name[1] %}
    33             {% endwith %}
    34         
    35         好处: 防止变量污染
    36 
    37 
    38 注意! 所有的语句标签,都必须要 {% xx %} {% endxx %}
    39 
    40 
    41 
    42 
    43 小练习:
    44 1. 把所有的测试器,都测试一遍
    45 2. 把上次的按个导航条,改进以下,如果render_template('xx.html', user=user)
    46     那么就通过if判断,如果有这个user那么就显示用域名
    47     如果没有user,或者user是个None就 显示登陆注册
    48     logo左浮动   右边写 login-group,右浮动
    49 3. 传一个老列表,在模板里面用for迭代渲染li标签
    思维笔记

    6 模拟登录

      要求:如果用户名和密码都正确就显示  欢迎 XXX,否则就显示  登录和注册

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>登录</title>
        <style>
            #head {
                background-color: skyblue;
                border: 1px solid red;
            }
            li {
                list-style-type: none;
            }
            .group-item {
                float: left;
                padding:0 10px;
            }
            .login-item {
                float: right;
                padding:0 10px;
            }
            .clear {
                clear: both;
            }
            a {
                text-decoration: none;
            }
            li:hover {
                background-color: blue
            }
            a:hover {
                color: yellow;
            }
        </style>
    </head>
    <body>
        <div id="head">
            <ul>
                <li class="group-item"><a href="#">首页</a></li>
                <li class="group-item"><a href="#">python</a></li>
                <li class="group-item"><a href="#">java</a></li>
                <li class="group-item"><a href="#">angular</a></li>
                {% if (name is equalto "warrior") and (pwd is equalto "123321") %}
                    <li class="login-item"><span>欢迎&nbsp;{{ name }}</span></li>
                {% else %}
                    <li class="login-item"><a href="#">登录</a></li>
                    <li class="login-item"><a href="#">注册</a></li>
                {% endif %}
                <div class="clear"></div>
            </ul>
        </div>
    </body>
    </html>
    htmo模板代码
    from flask import Blueprint
    from flask import render_template
    
    bp_login = Blueprint("login", __name__)
    
    @bp_login.route('/login/')
    def toLogin():
        content = {
            'name': 'warrior',
            'pwd': '123321'
        }
        resp = render_template('login.html', **content)
        return resp
    蓝图代码
     1 from flask import Flask
     2 from flask import render_template
     3 from jinja2 import tests
     4 
     5 # from testor import bp_test
     6 # from controller import bp_controller
     7 from login import bp_login
     8 
     9 app = Flask(__name__)
    10 
    11 # app.register_blueprint(bp_test)
    12 # app.register_blueprint(bp_controller)
    13 app.register_blueprint(bp_login)
    14 
    15 # @app.route('/')
    16 # def hello_world():
    17 #     resp = render_template('index.html', info='warrior')
    18 #     return resp
    19 
    20 print(app.url_map)
    21 
    22 if __name__ == '__main__':
    23     app.run(debug=True)
    python代码

  • 相关阅读:
    附加数据库报错:无法打开物理文件 XXX.mdf",操作系统错误 5:"5(拒绝访问。)"
    Java(TM) SE Development Kit 6 卸载不掉怎么办
    (转)WCF入门教程(一)简介
    (转)SQL Server 2008怎样编辑200行以上的数据
    远程桌面下如何打开任务管理器
    在 sys.servers 中找不到服务器的解决办法,自己解决的
    MySQL 8小时问题
    Spring 事件机制
    MapReduce架构
    HDFS架构
  • 原文地址:https://www.cnblogs.com/NeverCtrl-C/p/7554680.html
Copyright © 2011-2022 走看看