zoukankan      html  css  js  c++  java
  • django模板,自定义标签和filter

    django模板,自定义标签和filter - yanng - 博客园

    django模板,自定义标签和filter

    注:这悲催的缩进,真是对不起观众了,有时间过来修改。

    自定义标签大致分为三类:

    1、非封闭标签如{% current_time  "%Y-%m-%d %I:%M %p"  %}

    2、封闭标签如{%upper%}{%endupper%}

    3、inclusion标签 比如{% books_for_author author %}

    定义一个标签需要做两方面工作:1、定义编译函数 2、定义node。

    编译函数的作用是将自定义node中的render所需要的参数计算出来,以备使用。比如将自定义tag中的参数等分离出来,或是将封闭标签中的nodelist算出来。自定义node的目的是提供该标签的render函数,将结果返回,或者存放在context中

    非封闭标签

    以定义{% current_time "%Y-%m-%d %I:%M %p" %}为例

    1)定义编译函数:

    复制代码
    from django import template
    register = template.Library()
    
    @register.tag(name="current_time")
    def do_current_time(parser, token):
      try:
        # split_contents() knows not to split quoted strings.
        tag_name, format_string = token.split_contents()
      except ValueError:
        msg = '%r tag requires a single argument' % token.split_contents()[0]
        raise template.TemplateSyntaxError(msg)
      return CurrentTimeNode(format_string[1:-1])
    复制代码

    2)定义node

    复制代码
    import datetime
    
    class CurrentTimeNode(template.Node):
      def __init__(self, format_string):
        self.format_string = str(format_string)
    
      def render(self, context):
        now = datetime.datetime.now()
        return now.strftime(self.format_string)
    
    import re
    
    class CurrentTimeNode3(template.Node):
      def __init__(self, format_string, var_name):
        self.format_string = str(format_string)
        self.var_name = var_name
    
      def render(self, context):
        now = datetime.datetime.now()
        context[self.var_name] = now.strftime(self.format_string)
        return ''
    复制代码

    另外一个非封闭标签中比较常用、比较复杂的一个例子

    自定义tag:{% get_current_time "%Y-%M-%d %I:%M %p" as my_current_time %}

    复制代码
    def do_current_time(parser, token):
    # This version uses a regular expression to parse tag contents.
      try:
    # Splitting by None == splitting by spaces.
        tag_name, arg = token.contents.split(None, 1)
      except ValueError:
        msg = '%r tag requires arguments' % token.contents[0]
        raise template.TemplateSyntaxError(msg)
    
      m = re.search(r'(.*?) as (\w+)', arg)
      if m:
        fmt, var_name = m.groups()
      else:
        msg = '%r tag had invalid arguments' % tag_name
        raise template.TemplateSyntaxError(msg)
    
      if not (fmt[0] == fmt[-1] and fmt[0] in ('"', "'")):
        msg = "%r tag's argument should be in quotes" % tag_name
        raise template.TemplateSyntaxError(msg)
    
      return CurrentTimeNode3(fmt[1:-1], var_name)
    复制代码

    封闭标签,

     以{%upper%}{%endupper%}为例

    复制代码
    def do_upper(parser, token):
    """
    将两个标签之间的node保存到nodelist,然后传入UpperNode类供处理
    """
      nodelist = parser.parse(('endupper',))
      parser.delete_first_token()
      return UpperNode(nodelist)
    
    class UpperNode(template.Node):
      def __init__(self, nodelist):
      self.nodelist = nodelist
    """
    调用nodelist中node的render()方法,然后将返回的内容保存在output中,最后对output做大写操作
    """
      def render(self, context):
        output = self.nodelist.render(context)
        return output.upper()
    复制代码

    inclusion 标签

    inclusion tag,该tag需要一个模板配合它。比如{% books_for_author author %}
    只需要两方面工作,一是定义一个函数,以自定义标签的参数(本例中的author)函数的形参,返回值作为模板文件的输入参数(本例中的{'books': books})。二是定义一个模板
    tag文件

    @register.inclusion_tag('book_snippet.html')
    def books_for_author(author):
      books = Book.objects.filter(authors__id=author.id)
      return {'books': books}

    模板文件:

    book_snippet.html
    <ul>
    {% for book in books %}
    <li>{{ book.title }}</li>
    {% endfor %}
    </ul>

    自定义filter

    from django import template
    register = template.Library()
    
    @register.filter(name='cut')
    def cut(value, arg):
      return value.replace(arg, '')

    使用方法: {{ somevariable|cut:" " }}

    这里的somevariable便是cut中的value,“ ”便是arg,整个filter的作用是将somevariable中的“ ”(空格)替换成'',也即去掉somevariable中的空格

  • 相关阅读:
    仿照京东做的一个鼠标移上去的图片文字说明效果
    js 之 复制一段代码
    自己练习了一个弹出框
    用jq 做了一个排序
    做了一个类似天猫鼠标经过icon的动画,记录一下
    一行代码写一个轮播,想了好久,感觉这样可以。
    一个小例子,全选复选框
    仿照淘宝首页做的一个高度伪对齐demo
    《挑战程序设计竞赛》2.2 贪心法-区间 POJ2376 POJ1328 POJ3190
    《挑战程序设计竞赛》2.1 穷竭搜索 POJ2718 POJ3187 POJ3050 AOJ0525
  • 原文地址:https://www.cnblogs.com/lexus/p/2474797.html
Copyright © 2011-2022 走看看