Как добавить несколько аргументов в мой собственный фильтр шаблонов в шаблоне django?
-
05-07-2019 - |
Вопрос
Вот мой собственный фильтр:
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 допускает только один аргумент для вашего фильтра, но нет никаких причин, по которым вы не можете поместить все свои аргументы в одну строку, используя их запятую для разделения.
Так, например, если вам нужен фильтр, который проверяет, есть ли переменная 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 (), чтобы удалить все начальные и конечные пробелы.
Если, например, 3-й аргумент является int, просто выполните:
arg_list[2] = int(arg_list[2])
Или, если все они целочисленные, то это так.
arg_list = [int(arg) for arg in args.split(',')]
РЕДАКТИРОВАТЬ: теперь, чтобы конкретно ответить на ваш вопрос, используя пары ключ-значение в качестве параметров, вы можете использовать тот же класс, который Django использует для анализа строк запроса из URL-адресов, что также дает преимущество в правильной обработке кодировки символов в соответствии с вашими требованиями. settings.py.
Таким образом, как и в случае строк запроса, каждый параметр отделяется символом & amp; ':
{{ 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',''))
Другие советы
Невозможно согласно эта секция из документов:
Пользовательские фильтры — это просто функции Python, которые принимают один или два аргумента:
- Значение переменной (вход) - не обязательно строка.
- Значение аргумента - это может иметь значение по умолчанию или быть вообще оставленным.
Вместо фильтра зарегистрируйте свой тег как простой тег. Те могут принять несколько аргументов. Синтаксис для его вызова будет немного другим, но это просто изменение синтаксического сахара.
Это так просто.
@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 }}
Эта функция была помечена как WONTFIX в Trac 2013 года Джанго: http://code.djangoproject.com / билет / 1199
<мой-сайт>/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" }}
Вы можете просто сделать это:
{% assign find_total_issued = dailysalesreport | find: "TotalIssued":"13" %}
public static List<object> Find(object collection, string column, string value)
И он достигнет пункта назначения, поскольку абстракция функции sjare
.
Вот плохая идея, но работает:
{{ 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)