【问题标题】:How do I add multiple arguments to my custom template filter in a django template?如何在 django 模板中向我的自定义模板过滤器添加多个参数?
【发布时间】:2010-09-30 01:26:33
【问题描述】:

这是我的自定义过滤器:

from django import template

register = template.Library()

@register.filter
def replace(value, cherche, remplacement):
    return value.replace(cherche, remplacement)

以下是我在模板文件中尝试使用它导致错误的方法:

{{ attr.name|replace:"_"," " }}
{{ attr.name|replace:"_" " " }}
{{ attr.name|replace:"_":" " }}
{{ attr.name|replace:"cherche='_', remplacement=' '" }}

我查看了django's docsbook,但只找到了使用单个参数的示例...这可能吗?

【问题讨论】:

    标签: django django-templates


    【解决方案1】:

    比你想象的要简单

    您可以为此使用 simple_tag

    from django import template
    register = template.Library()
    
    @register.simple_tag
    def multiple_args_tag(a, b, c, d):
       #do your stuff
       return 
    

    在模板中

    {% multiple_args_tag 'arg1' 'arg2' 'arg3' 'arg4' %}
    

    注意:不要忘记重新运行服务器。

    【讨论】:

      【解决方案2】:

      你可以这样做:

      {% assign find_total_issued = dailysalesreport | find: "TotalIssued":"13" %}
      
      public static List<object> Find(object collection, string column, string value)
      

      它会到达目的地,因为函数的抽象是sjare

      【讨论】:

        【解决方案3】:

        此功能已在 2013 年 Django 的 Trac 中标记为 WONTFIX:http://code.djangoproject.com/ticket/1199

        【讨论】:

        • 那张票在去年(2013 年)被关闭为 WONTFIX,如果需要多个参数,他们的开发人员建议使用自定义标签。
        【解决方案4】:

        就这么简单。

        @register.filter(name='one_more')
        def one_more(_1, _2):
            return _1, _2
        
        def your_filter(_1_2, _3)
            _1, _2 = _1_2
            print "now you have three arguments, enjoy"
        
        {{ _1|one_more:_2|your_filter:_3 }}
        

        【讨论】:

        • 非常感谢您提供此解决方案。我已经对其进行了一些升级,因此您可以链接不同长度的参数。 gist.github.com/BrnoPCmaniak/e9552294b3059461f940a47143f58811
        • 这应该是正确答案!这是一个漂亮的 python 解决方案(也许不是最好的 django 解决方案,请参阅@dragonroot 答案)
        【解决方案5】:

        将您的标签注册为简单标签,而不是过滤器。这些可以采用多个参数。调用它的语法会有些不同,但这只是语法糖的变化。

        【讨论】:

        • 这是我的问题的正确答案。为了将模板变量传递给这个函数,我必须使用simple_tag
        • 这是一个很好的解决方案。绝对值得查看简单标签的 django 文档:docs.djangoproject.com/en/1.8/howto/custom-template-tags/…
        • 这对我来说是最有意义的。标签比过滤器更强大、更复杂,因此,如果您的问题更复杂,似乎比尝试将方形钉插入圆孔更好。
        【解决方案6】:

        /globaltags/replace.py

        from django.template import Library
        
        import re
        
        register = Library()
        
        def search(value, search):
            return re.sub(search, '#f4x@SgXXmS', value)
        
        def replace(value, replace):
            return re.sub('#f4x@SgXXmS', replace, value)
        
        register.filter(search)
        register.filter(replace)
        

        在模板中:

        {{ "saniel"|search:"s"|replace:"d" }}
        

        【讨论】:

        • 如果你解释一下#f4x@SgXXmS位会很好吗?
        • 只是一个用作占位符的随机字符串。我选择了这个字符串,因为我相信它不会成为输入字符串的一部分。例如,如果我使用 "{}" 而不是 '#f4x@SgXXmS' {{ "use {} instead off []"|search:"off"|replace:"of" }} 将返回:"use of而不是 []” 而不是预期的结果:“使用 {} 而不是 []”
        • 哦,有道理。将其声明为SUBSTRING_THAT_NEVER_OCCURS 可能会很好。
        【解决方案7】:

        这是一个坏主意,但有效:

        {{ xml|input_by_xpath:"{'type':'radio','xpath':'//result/value'}" }}
        

        @register.filter
        def input_by_xpath(device, args): 
            args = eval(args)
            ...
            result = "<input type=\"%s\" value=\"%s\" name=\"%s\"/>"%(args['type'],value,args['xpath'])
            return mark_safe(result)
        

        【讨论】:

          【解决方案8】:

          这是可能的,而且相当简单。

          Django 只允许您的过滤器使用一个参数,但没有理由不能将所有参数放入一个字符串中,使用逗号分隔它们。

          例如,如果您想要一个过滤器来检查变量 X 是否在列表 [1,2,3,4] 中,您将需要一个看起来像这样的模板过滤器:

          {% if X|is_in:"1,2,3,4" %}
          

          现在我们可以像这样创建你的模板标签:

          from django.template import Library
          
          register = Library()
          
          def is_in(var, args):
              if args is None:
                  return False
              arg_list = [arg.strip() for arg in args.split(',')]
              return var in arg_list
          
          register.filter(is_in)
          

          创建 arg_list 的行是一个生成器表达式,它在所有逗号上拆分 args 字符串并调用 .strip() 删除任何前导和尾随空格。

          例如,如果第三个参数是一个 int,那么就这样做:

          arg_list[2] = int(arg_list[2])
          

          或者如果它们都是整数,那么:

          arg_list = [int(arg) for arg in args.split(',')]
          

          编辑:现在通过使用键值对作为参数来专门回答您的问题,您可以使用 Django 用来解析 URL 中的查询字符串的同一个类,这也有利于根据您的正确处理字符编码设置.py。

          因此,与查询字符串一样,每个参数都由 '&' 分隔:

          {{ attr.name|replace:"cherche=_&remplacement= " }}
          

          那么你的替换函数现在看起来像这样:

          from django import template
          from django.http import QueryDict
          
          register = template.Library()
          
          @register.filter
          def replace(value, args):
              qs = QueryDict(args)
              if qs.has_key('cherche') and qs.has_key('remplacement'):
                  return value.replace(qs['cherche'], qs['remplacement'])
              else:
                  return value
          

          您可以加快速度,但可能会出现一些不正确的替换:

          qs = QueryDict(args)
          return value.replace(qs.get('cherche',''), qs.get('remplacement',''))
          

          【讨论】:

          • 如果这些值在变量中如何实现...?
          • 这似乎很有帮助,但我无法让它与正在传递的变量一起工作。为此,我使用了 tagsimple_tag - 它允许传递多个变量,甚至是命名变量。
          • 我远离未来,但在我看来,标签会比在过滤器中编写解析器更好。
          【解决方案9】:

          根据文档的this section 不可能:

          自定义过滤器只是接受一两个参数的 Python 函数:

          • 变量的值(输入)-- 不一定是字符串。
          • 参数的值——这可以有一个 默认值,或完全省略。

          【讨论】:

          • 如果您使用硬编码的字符串,Van Gale 的方法将有效。 Django 票证 [code.djangoproject.com/ticket/1199] 支持自定义过滤器中的多个参数,并且已接受补丁。
          猜你喜欢
          • 2015-02-27
          • 1970-01-01
          • 2021-09-21
          • 2017-02-10
          • 2017-10-03
          • 2011-05-28
          • 2013-03-26
          • 2014-02-13
          • 1970-01-01
          相关资源
          最近更新 更多