How do I add multiple arguments to my custom template filter in a django template?

前端 未结 9 466
时光说笑
时光说笑 2020-11-27 12:20

Here\'s my custom filter:

from django import template

register = template.Library()

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


        
相关标签:
9条回答
  • 2020-11-27 12:37

    <my-site>/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)
    

    In the template:

    {{ "saniel"|search:"s"|replace:"d" }}
    
    0 讨论(0)
  • 2020-11-27 12:38

    Not possible according to this section of the docs:

    Custom filters are just Python functions that take one or two arguments:

    • The value of the variable (input) -- not necessarily a string.
    • The value of the argument -- this can have a default value, or be left out altogether.
    0 讨论(0)
  • 2020-11-27 12:39

    Instead of a filter, register your tag as a simple tag. Those can take multiple arguments. The syntax for invoking it will be a little bit different, but that's just syntactic sugar changing.

    0 讨论(0)
  • 2020-11-27 12:40

    It is more simple than you think

    You can use simple_tag for this.

    @register.simple_tag
    def multiple_args_tag(a, b, c, d):
       #do your stuff
       return 
    

    In Template:

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

    NOTE: Don't forget to re-run the server.

    0 讨论(0)
  • 2020-11-27 12:53

    It is possible and fairly simple.

    Django only allows one argument to your filter, but there's no reason you can't put all your arguments into a single string using a comma to separate them.

    So for example, if you want a filter that checks if variable X is in the list [1,2,3,4] you will want a template filter that looks like this:

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

    Now we can create your templatetag like this:

    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)
    

    The line that creates arg_list is a generator expression that splits the args string on all the commas and calls .strip() to remove any leading and trailing spaces.

    If, for example, the 3rd argument is an int then just do:

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

    Or if all of them are ints do:

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

    EDIT: now to specifically answer your question by using key,value pairs as parameters, you can use the same class Django uses to parse query strings out of URL's, which then also has the benefit of handling character encoding properly according to your settings.py.

    So, as with query strings, each parameter is separated by '&':

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

    Then your replace function will now look like this:

    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
    

    You could speed this up some at the risk of doing some incorrect replacements:

    qs = QueryDict(args)
    return value.replace(qs.get('cherche',''), qs.get('remplacement',''))
    
    0 讨论(0)
  • 2020-11-27 12:54

    This feature has been marked as WONTFIX in 2013 Django's Trac: http://code.djangoproject.com/ticket/1199

    0 讨论(0)
提交回复
热议问题