zoukankan      html  css  js  c++  java
  • 模板-过滤器&标签

    模板值过滤器


    对一个 Python开发者来说,写一个自己的模板语言就象是某种“成人礼”一样! 如果你还没有完成一个自己的 模板语言,好好考虑写一个,这是一个非常有趣的锻炼。
     
     
    模板过滤器是在变量被显示前修改它的值的一个简单方法。 过滤器使用管道字符,如下所示:
     
    {{ name|lower }}
    过滤管道可以被* 套接* ,既是说,一个过滤器管道的输出又可以作为下一个管道的输入,如此下去。 下面的例子实现查找列表的第一个元素并将其转化为大写。
    {{ my_list|first|upper }}
    有些过滤器有参数。 过滤器的参数跟随冒号之后并且总是以双引号包含。
    {{ bio|truncatewords:"30" }}
    语法: {{obj|filter__name:param}}
    Default 如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值。例如: {{ value|default:"nothing" }}
    Length
    返回值的长度。它对字符串和列表都起作用。例如:
    {{ value|length }}
    如果 value 是 ['a', 'b', 'c', 'd'],那么输出是 4。
    Filesizeformat
    将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。例如:
    {{ value|filesizeformat }}
    如果 value 是 123456789,输出将会是 117.7 MB。
    Date 如果 value=datetime.datetime.now(){{ value|date:"Y-m-d" }}
    Slice
    如果 value="hello world"
    {{ value|slice:"2:-1" }}
    Truncatechars
    如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。
    参数:要截断的字符数
    例如:
    {{ value|truncatechars:9 }}
    Safe
    Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。比如:
    value="<a href="">点击</a>"
    {{ value|safe}}
    addslashes : 添加反斜杠到任何反斜杠、单引号或者双引号前面。 这在处理包含JavaScript的文本时是非常有用的。
     
    这里简单介绍一些常用的模板的过滤器,更多详见

     

    模板语法之标签


     
    标签看起来像是这样的: {% tag %}。标签比变量更加复杂:一些在输出中创建文本,一些通过循环或逻辑来控制流程,一些加载其后的变量将使用到的额外信息到模版中。一些标签需要开始和结束标签 (例如{% tag %} ...标签 内容 ... {% endtag %})。

    for标签

    遍历每一个元素:
    {% for person in person_list %}
       <p>{{ person.name }}</p>
    {% endfor %}
    给标签增加一个 reversed 使得该列表被反向迭代:
    {% for athlete in athlete_list reversed %}
    ...
    {% endfor %}
    遍历一个字典:
    {% for key,val in dic.items %}
       <p>{{ key }}:{{ val }}</p>
    {% endfor %}
     
    可以嵌套使用 {% for %} 标签
     
     

    for ... empty

    在执行循环之前先检测列表的大小是一个通常的做法, 因为这种做法十分常见,所以`` for`` 标签支持一个可选的`` {% empty %}`` 分句,通过它我们可以定义当列表为空时的输出内容

    for?标签带有一个可选的{%?empty?%}?从句,以便在给出的组是空的或者没有被找到时,可以有所操作。
    {% for person in person_list %}
       <p>{{ person.name }}</p>
    {% empty %}
       <p>sorry,no person here</p>
    {% endfor %}
     

    `` forloop`` 模板变量

    forloop.counter 总是一个表示当前循环的执行次数的整数计数器。 这个计数器是从1开始的,所以在第一次循环时 forloop.counter 将会被设置为1。
    {% for item in todo_list %}
        <p>{{ forloop.counter }}: {{ item }}</p>
    {% endfor %}
    forloop.counter0 类似于 forloop.counter ,但是它是从0计数的。 第一次执行循环时这个变量会被设置为0。
     
    forloop.revcounter 是表示循环中剩余项的整型变量。 在循环初次执行时 forloop.revcounter 将被设置为序列中项的总数。 最后一次循环执行中,这个变量将被置1。
     
    forloop.revcounter0 类似于 forloop.revcounter ,但它以0做为结束索引。 在第一次执行循环时,该变量会被置为序列的项的个数减1。
     
    forloop.first 是一个布尔值,如果该迭代是第一次执行,那么它被置为```` 在下面的情形中这个变量是很有用的:
    {% for object in objects %}
        {% if forloop.first %}<li class="first">{% else %}<li>{% endif %}
        {{ object }}
        </li>
    {% endfor %}
    forloop.last 是一个布尔值;在最后一次执行循环时被置为True。 一个常见的用法是在一系列的链接之间放置管道符(|)
    {% for link in links %}{{ link }}{% if not forloop.last %} | {% endif %}{% endfor %}
    上面的模板可能会产生如下的结果:
    Link1 | Link2 | Link3 | Link4
    另一个常见的用途是为列表的每个单词的加上逗号。
    Favorite places:
    {% for p in places %}{{ p }}{% if not forloop.last %}, {% endif %}{% endfor %}
    forloop.parentloop 是一个指向当前循环的上一级循环的 forloop 对象的引用(在嵌套循环的情况下)。 例子在此:
    {% for country in countries %}
        <table>
        {% for city in country.city_list %}
            <tr>
            <td>Country #{{ forloop.parentloop.counter }}</td>
            <td>City #{{ forloop.counter }}</td>
            <td>{{ city }}</td>
            </tr>
        {% endfor %}
        </table>
    {% endfor %}
    forloop 变量仅仅能够在循环中使用。 在模板解析器碰到{% endfor %}标签后,forloop就不可访问了。

    ifequal/ifnotequal

    {% ifequal %} 标签比较两个值,当他们相等时,显示在 {% ifequal %} 和 {% endifequal %} 之中所有的值。
    下面的例子比较两个模板变量 user 和 currentuser :
    {% ifequal user currentuser %}
        <h1>Welcome!</h1>
    {% endifequal %}
    参数可以是硬编码的字符串,随便用单引号或者双引号引起来
    {% ifequal section 'sitenews' %}
        <h1>Site News</h1>
    {% endifequal %}
    
    {% ifequal section "community" %}
        <h1>Community</h1>
    {% endifequal %}

    和 {% if %} 类似, {% ifequal %} 支持可选的 {% else%} 标签

    {% ifequal section 'sitenews' %}
        <h1>Site News</h1>
    {% else %}
        <h1>No News Here</h1>
    {% endifequal %}

    只有模板变量,字符串,整数和小数可以作为 {% ifequal %} 标签的参数

    if/else

    {% if %} 标签检查(evaluate)一个变量,如果这个变量为真(即,变量存在,非空,不是布尔值假),系统会显示在 {% if %} 和 {% endif %} 之间的任何内容,例如
    
    {% if today_is_weekend %}
        <p>Welcome to the weekend!</p>
    {% endif %}
    {% else %} 标签是可选的:
    {% if today_is_weekend %}
        <p>Welcome to the weekend!</p>
    {% else %}
        <p>Get back to work.</p>
    {% endif %}
     
    {% if %}会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。
    {% if num > 100 or num < 0 %}
       <p>无效</p>
    {% elif num > 80 and num < 100 %}
       <p>优秀</p>
    {% else %}
       <p>凑活吧</p>
    {% endif %}
     
    Python 的“真值”
    在Python和Django模板系统中,以下这些对象相当于布尔值的False
    空列表([] )  ,空元组(() ) , 空字典({} ) ,空字符串('' ), 零值(0 ), 特殊对象None, 对象False(很明显)
    提示:你也可以在自定义的对象里定义他们的布尔值属性(这个是python的高级用法)。
    除以上几点以外的所有东西都视为`` True``
     

    {% if %} 标签接受 and , or 或者 not 关键字来对多个变量做判断 ,或者对变量取反( not )

    {% if %} 标签不允许在同一个标签中同时使用 and 和 or ,因为逻辑上可能模糊的,例如,如下示例是错误的: 比如这样的代码是不合法的:
    {% if athlete_list and coach_list or cheerleader_list %}
    系统不支持用圆括号来组合比较操作。 如果你确实需要用到圆括号来组合表达你的逻辑式,考虑将它移到模板之外处理,然后以模板变量的形式传入结果吧。 或者,仅仅用嵌套的{% if %}标签替换吧,就像这样:
    {% if athlete_list %}
        {% if coach_list or cheerleader_list %}
            We have athletes, and either coaches or cheerleaders!
        {% endif %}
    {% endif %}
    多次使用同一个逻辑操作符是没有问题的,但是我们不能把不同的操作符组合起来
     
    并没有 {% elif %} 标签, 请使用嵌套的`` {% if %}`` 标签来达成同样的效果:
     
    一定要用 {% endif %} 关闭每一个 {% if %} 标签。
     

    With

    使用一个简单地名字缓存一个复杂的变量,当你需要使用一个“昂贵的”方法(比如访问数据库)很多次的时候是非常有用的
    例如:
    {% with total=business.employees.count %}
       {{ total }} employee{{ total|pluralize }}
    {% endwith %

    csrf_token

     
    这个标签用于跨站请求伪造保护
    不想让别人随意给这个服务器发送post请求
    可以在form标签内部加上  {{csrf_token}}
    rander将{{csrf_token}}标签渲染为一个type=hidden的input标签,在点击post提交请求时,会多提交一个键值对,Django的中间件会根据这个键值对来确定访问的安全性

    自定义标签与过滤器

    1、在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag.
    2、在app中创建templatetags模块(模块名只能是templatetags)
    3、创建任意 .py 文件,如:my_tags.py
    from django import template
    from django.utils.safestring import mark_safe
     
    register = template.Library()?? #register的名字是固定的,不可改变
    @register.filter
    def filter_multi(v1,v2):
        return? v1 * v2
    @register.simple_tag
    def simple_tag_multi(v1,v2):
        return? v1 * v2
     
     
    @register.simple_tag
    def my_input(id,arg):
        result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
        return mark_safe(result)
     
     
    from django import template
    from django.utils.safestring import mark_safe
    register = template.Library()?? #register的名字是固定的,不可改变
    @register.filter
    def filter_multi(v1,v2):
       return? v1 * v2
     
     
    @register.simple_tag
    def simple_tag_multi(v1,v2):
        return? v1 * v2
     
     
    @register.simple_tag
    def my_input(id,arg):
        result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
        return mark_safe(result)
     
     
    自定义的过滤器只能传两个参数,而标签可以传多个
    4、在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py
    {% load my_tags %}
    5、使用simple_tag和filter(如何调用)
    -------------------------------.html
    {% load xxx %}??
    ??????
    # num=12
    {{ num|filter_multi:2 }} #24
    {{ num|filter_multi:"[22,333,4444]" }}
    {% simple_tag_multi 2 5 %}? 参数不限,但不能放在if for语句中
    {% simple_tag_multi num 5 %}
    注意:filter可以用在if等语句后,simple_tag不可以
    {% if num|filter_multi:30 > 100 %}
        {{ num|filter_multi:30 }}
    {% endif %}
     
     

    注释

    注释使用 {# #}, 用这种语法的注释不能跨越多行。 这个限制是为了提高模板解析的性能 :
    {# This is a comment #}
     
    如果要实现多行注释,可以使用`` {% comment %}`` 模板标签,就像这样:
    {% comment %}
    This is a
    multi-line comment.
    {% endcomment %}
     
     
     
  • 相关阅读:
    《七哥说道》第五章:入职惨做苦力,画饼一望无际
    《七哥说道》第四章:理想在远方,现实在流浪
    《七哥说道》第三章:志远淋雨怒辞职,误入保险黄老萍
    《七哥说道》第二章:初出茅庐之拜师学艺
    (十)redis源码解读
    (三十二)线上调优
    (三)栈
    (一)设计模式之代理模式
    Linux whereis、find和locate命令区别以及应用场景
    使用自定义注解和AOP管理shiro权限
  • 原文地址:https://www.cnblogs.com/leiyiming/p/12342272.html
Copyright © 2011-2022 走看看