Jinjia2-语法入门

Jinjia2

语法

  1. 控制结构 {% %}
  2. 变量取值 {{ }}
  3. 注释 {# #}

变量

  • 读取变量
    {{ parameter }}
  • 读取字典
    {{ parameter[‘key’] }}
    {{ parameter.key }}
  • 读取数组
    {{ parameter[3] }}
  • 读取对象
    {{ object.something() }}

过滤器

变量可以通过“过滤器”进行修改,过滤器可以理解为是Jinja2里面的内置函数和字符串处理函数。
常用过滤器如下:

  • abs(value):返回一个数值的绝对值。示例:-1|abs
  • default(value,default_value,boolean=false):如果当前变量没有值,则会使用参数中的值来代替。示例:name|default(‘xiaotuo’)——如果name不存在,则会使用xiaotuo来替代。boolean=False默认是在只有这个变量为undefined的时候才会使用default中的值,如果想使用python的形式判断是否为false,则可以传递boolean=true。也可以使用or来替换。
  • escape(value)或e:转义字符,会将<、>等符号转义成HTML中的符号。显例:content|escape或content|e。
  • first(value):返回一个序列的第一个元素。示例:names|first
  • format(value,arags,*kwargs):格式化字符串。比如:{{ “%s” - “%s”|format(‘Hello?’,“Foo!”) }}将输出:Helloo? - Foo!
  • last(value):返回一个序列的最后一个元素。示例:names|last。
  • length(value):返回一个序列或者字典的长度。示例:names|length。
  • join(value,d=u”):将一个序列用d这个参数的值拼接成字符串。
  • safe(value):如果开启了全局转义,那么safe过滤器会将变量关掉转义。示例:content_html|safe。
  • int(value):将值转换为int类型。
  • float(value):将值转换为float类型。
  • lower(value):将字符串转换为小写。
  • upper(value):将字符串转换为小写。
  • replace(value,old,new): 替换将old替换为new的字符串。
  • truncate(value,length=255,killwords=False):截取length长度的字符串。
  • striptags(value):删除字符串中所有的HTML标签,如果出现多个空格,将替换成一个空格。
  • trim:截取字符串前面和后面的空白字符。
  • string(value):将变量转换成字符串。
  • wordcount(s):计算一个长字符串中单词的个数。

示例

    @ 字符串操作
    {# 输出大写 #}
    hello {{ name|upper }}!
      
      
    {# 输出大写,超过3个字符打断,用'...'替代 #}
    <h1>hello {{ name|upper|truncate(3,True) }}</h1>
      
      
    {# 当变量未定义时,显示默认字符串,可以缩写为d #}
    {{ name | default('No name', true) }}
      
       
    {# 单词首字母大写 #}
    {{ 'hello' | capitalize }}
      
       
    {# 单词全小写 #}
    {{ 'XML' | lower }}
      
       
    {# 去除字符串前后的空白字符 #}
    {{ '  hello  ' | trim }}
      
       
    {# 字符串反转,返回"olleh" #}
    {{ 'hello' | reverse }}
      
       
    {# 格式化输出,返回"Number is 2" #}
    {{ '%s is %d' | format("Number", 2) }}
      
       
    {# 关闭HTML自动转义 #}
    {{ '<em>name</em>' | safe }}
      
       
    {% autoescape false %}
    {# HTML转义,即使autoescape关了也转义,可以缩写为e #}
    {{ '<em>name</em>' | escape }}
    {% endautoescape %}
     
     
    @ 数值操作
    {# 四舍五入取整,返回13.0 #}
    {{ 12.8888 | round }}
      
       
    {# 向下截取到小数点后2位,返回12.88 #}
    {{ 12.8888 | round(2, 'floor') }}
      
       
    {# 绝对值,返回12 #}
    {{ -12 | abs }}
     
     
    @ 列表操作
    {# 取第一个元素 #}
    {{ [1,2,3,4,5] | first }}
      
       
    {# 取最后一个元素 #}
    {{ [1,2,3,4,5] | last }}
      
       
    {# 返回列表长度,可以写为count #}
    {{ [1,2,3,4,5] | length }}
      
       
    {# 列表求和 #}
    {{ [1,2,3,4,5] | sum }}
      
       
    {# 列表排序,默认为升序 #}
    {{ [3,2,1,5,4] | sort }}
      
       
    {# 合并为字符串,返回"1 | 2 | 3 | 4 | 5" #}
    {{ [1,2,3,4,5] | join(' | ') }}
      
       
    {# 列表中所有元素都全大写。这里可以用upper,lower,但capitalize无效 #}
    {{ ['tom','bob','ada'] | upper }}
     
     
    @ 字典操作
    {% set users=[{'name':'Tom','gender':'M','age':20},
                  {'name':'John','gender':'M','age':18},
                  {'name':'Mary','gender':'F','age':24},
                  {'name':'Bob','gender':'M','age':31},
                  {'name':'Lisa','gender':'F','age':19}]
    %}
       
       
    {# 按指定字段排序,这里设reverse为true使其按降序排 #}
    <ul>
    {% for user in users | sort(attribute='age', reverse=true) %}
    <li>{{ user.name }}, {{ user.age }}</li>
    {% endfor %}
    </ul>
      
      
      
    {# 列表分组,每组是一个子列表,组名就是分组项的值 #}
    <ul>
    {% for group in users|groupby('gender') %}
    <li>{{ group.grouper }}
    <ul>
        {% for user in group.list %}
    <li>{{ user.name }}</li>
        {% endfor %}</ul>
    </li>
    {% endfor %}
    </ul>
       
      
    {# 取字典中的某一项组成列表,再将其连接起来 #}
    {{ users | map(attribute='name') | join(', ') }}

jinja2的控制结构

jinja2中的if语句类似与Python的if语句,它也具有单分支,多分支等多种结构,不同的是,条件语句不需要使用冒号结尾,而结束控制语句,需要使用endif关键字。

    {% if daxin.safe %}
    daxin is safe.
    {% elif daxin.dead %}
    daxin is dead
    {% else %}
    daxin is okay
    {% endif %}

jinja2的for循环

jinja2中的for循环用于迭代Python的数据类型,包括列表,元组和字典。在jinja2中不存在while循环。

基本语法

  • 迭代列表
    <ul>
    {% for user in users %}
    <li>{{ user.username|title }}</li>
    {% endfor %}
    </ul>
  • 迭代字典
    <dl>
    {% for key, value in my_dict.iteritems() %}
    <dt>{{ key }}</dt>
    <dd>{{ value}}</dd>
    {% endfor %}
    </dl>

for循环中的特殊变量

变量描述
loop.index当前迭代的索引(从1开始)
loop.index0当前迭代的索引(从0开始)
loop.first是否是第一次迭代,返回bool
loop.last是否是最后一次迭代,返回bool
loop.length序列中的项目数量
loop.revindex到循环结束的次数(从1开始)
loop.revindex0到循环结束的次数(从0开始)

宏(类似函数)

宏类似于Python中的函数,我们在宏中定义行为,还可以进行传递参数,就像Python中的函数一样一样儿的。

定义:在宏中定义一个宏的关键字是macro,后面跟其 宏的名称和参数等

    {% macro input(name,age=18) %}   # 参数age的默认值为18
     <input type='text' name="{{ name }}" value="{{ age }}" >
    {% endmacro %}

调用:调用方法也和Python的类似

    <p>{{ input('daxin') }} </p>
    <p>{{ input('daxin',age=20) }} </p>

jinja2的继承和Super函数

jinja2中最强大的部分就是模板继承。模板继承允许我们创建一个基本(骨架)文件,其他文件从该骨架文件继承,然后针对自己需要的地方进行修改。
jinja2的骨架文件中,利用block关键字表示其包涵的内容可以进行修改。

示例:

父:base.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        {% block head %}
        <link rel="stylesheet" href="style.css"/>
        <title>{% block title %}{% endblock %} - My Webpage</title>
        {% endblock %}
    </head>
    <body>
    <div id="content">{% block content %}{% endblock %}</div>
    <div id="footer">
        {% block  footer %}
        <script>This is javascript code </script>
        {% endblock %}
    </div>
    </body>
    </html>

子:
这里定义了四处 block,即:head,title,content,footer。那怎么进行继承和变量替换呢?注意看下面的文件

{% extend "base.html" %}       # 继承base.html文件
 
{% block title %} Dachenzi {% endblock %}   # 定制title部分的内容
 
{% block head %}
    {{  super()  }}        # 用于获取原有的信息
    <style type='text/css'>
    .important { color: #FFFFFF }
    </style>
{% endblock %}

PS: super()函数 表示获取block块中定义的原来的内容。

渲染

jinja2模块中有一个名为Enviroment的类,这个类的实例用于存储配置和全局对象,然后从文件系统或其他位置中加载模板。

基本使用方法

大多数应用都在初始化的时候撞见一个Environment对象,并用它加载模板。Environment支持两种加载方式:

  • PackageLoader:包加载器
  • FileSystemLoader:文件系统加载器

PackageLoader

使用包加载器来加载文档的最简单的方式如下:

    from jinja2 import PackageLoader,Environment
    env = Environment(loader=PackageLoader('python_project','templates'))    # 创建一个包加载器对象
    template = env.get_template('bast.html')    # 获取一个模板文件
    template.render(name='daxin',age=18)   # 渲染

其中:

  • PackageLoader()的两个参数为:python包的名称,以及模板目录名称。
  • get_template():获取模板目录下的某个具体文件。
  • render():接受变量,对模板进行渲染

FileSystemLoader

文件系统加载器,不需要模板文件存在某个Python包下,可以直接访问系统中的文件。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这里提供一个参考实现,使用Java语言实现了金块问题的分治法求解。 ``` public class GoldBlocks { // 块数和金价值对应的数组 private static final int[] blocks = {1, 2, 5, 10, 20, 50, 100, 200, 500, 1000}; private static final int[] values = {1, 3, 7, 15, 30, 70, 150, 300, 700, 1500}; // 计算能组合成value的最小块数 private static int minBlocks(int value) { int idx = Arrays.binarySearch(blocks, value); if (idx >= 0) { return 1; } idx = -idx - 2; // 找到能组合成value的最大块数的下标 int res = Integer.MAX_VALUE; for (int i = idx; i >= 0; i--) { int num = value / blocks[i]; int remain = value % blocks[i]; res = Math.min(res, num + (remain == 0 ? 0 : minBlocks(remain))); } return res; } // 分治法求解金块问题 private static int getMaxValue(int n) { if (n <= 0) { return 0; } if (n <= 1000) { int res = 0; for (int i = 0; i < blocks.length && blocks[i] <= n; i++) { res = Math.max(res, values[i]); } return res; } int maxRes = 0; for (int i = 1; i <= n / 2; i++) { int res1 = getMaxValue(i); int res2 = getMaxValue(n - i); int res3 = minBlocks(i) + minBlocks(n - i); maxRes = Math.max(maxRes, res1 + res2 + res3); } return maxRes; } public static void main(String[] args) { System.out.println(getMaxValue(5000)); // 输出 198 } } ``` 以上代码的关键点: - `minBlocks` 方法计算能组合成 value 的最小块数。它使用了二分查找找到能组合成 value 的最大块数,再递归求解余下部分的最小块数,并加上前面的块数,取最小值作为当前 value 所需的最小块数。 - `getMaxValue` 方法使用分治法将问题拆分成两个子问题,并递归求解。对于小于等于 1000 的情况,直接使用数组进行查找。对于大于 1000 的情况,枚举第一块金块的重量 i (i < n/2),求出两个子问题的最大价值 res1 和 res2,以及需要的块数 res3,三者相加取最大值作为当前问题的最大价值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值