Как добавить несколько аргументов в собственный фильтр шаблонов в шаблоне django?

Здесь мой пользовательский фильтр:

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 docs и book но только нашел пример, используя один аргумент... возможно ли это?

Ответ 1

Это возможно и довольно просто.

Django разрешает только один аргумент вашему фильтру, но нет причин, по которым вы не можете поместить все свои аргументы в одну строку, используя запятую, чтобы отделить их.

Так, например, если вы хотите, чтобы фильтр, проверяющий, есть ли переменная X в списке [1,2,3,4], вам понадобится фильтр шаблонов, который выглядит следующим образом:

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

Теперь мы можем создать ваш templatetag следующим образом:

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])

Или, если все из них являются ints:

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

EDIT: теперь, чтобы конкретно ответить на ваш вопрос, используя пары "ключ", "значение" в качестве параметров, вы можете использовать тот же класс, который использует Django для синтаксического анализа строк запроса из URL-адреса, что также имеет смысл правильно обрабатывать кодировку символов в соответствии с вашими settings.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',''))

Ответ 2

Невозможно в соответствии с в этом разделе документов:

Пользовательские фильтры - это просто функции Python, которые принимают один или два аргумента:

  • Значение переменной (ввода) - не обязательно строка.
  • Значение аргумента - это может иметь значение по умолчанию или полностью исключено.

Ответ 3

Вместо фильтра зарегистрируйте свой тег как простой тег. Они могут принимать несколько аргументов. Синтаксис для его вызова будет немного другим, но это просто синтаксический сахар меняется.

Ответ 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 }}

Ответ 6

< мой сайт > /globaltags/replace.py

from django.template import Library

import re

register = Library()

def search(value, search):
    return re.sub(search, '#[email protected]', value)

def replace(value, replace):
    return re.sub('#[email protected]', replace, value)

register.filter(search)
register.filter(replace)

В шаблоне:

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

Ответ 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)