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

StackOverflow https://stackoverflow.com/questions/420703

  •  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)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top