Django 템플릿의 사용자 지정 템플릿 필터에 여러 인수를 추가하려면 어떻게해야합니까?


90

내 사용자 지정 필터는 다음과 같습니다.

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의 문서책을 살펴 보았지만 단일 인수를 사용하는 예제 만 찾았습니다 ... 가능합니까?

답변:


108

가능하고 상당히 간단합니다.

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

또는 모두 int이면 다음을 수행하십시오.

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

편집 : 이제 매개 변수로 키, 값 쌍을 사용하여 질문에 구체적으로 대답하려면 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',''))

1
이것들의 값이 변수에 있다면 이것을 구현하는 방법 ...?
ANTO

2
이것은 도움이되는 것처럼 보였지만 전달되는 변수와 함께 작동하지 못했습니다. 이를 위해 여러 변수, 심지어 명명 된 변수까지 전달할 수 있는 tag또는 simple_tag-를 사용했습니다.
Furbeenator 2015 년

18

문서 의이 섹션 에 따르면 불가능합니다 .

사용자 지정 필터는 하나 또는 두 개의 인수를 사용하는 Python 함수입니다.

  • 변수 값 (입력)-반드시 문자열 일 필요는 없습니다.
  • 인수의 값-기본값을 갖거나 모두 생략 할 수 있습니다.

Van Gale의 접근 방식은 하드 코딩 된 문자열을 사용하는 경우 작동합니다. Django 티켓 [ code.djangoproject.com/ticket/1199] 은 사용자 정의 필터에서 여러 인수를 지원하며 패치가 승인되었습니다.
Jeff Bauer 2011 년

17

이렇게 쉽습니다.

@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
Filip Dobrovolný

1
이것은 정답이어야합니다! 아름다운 파이썬 솔루션입니다 (최고의 장고 솔루션이 아닐 수도 있습니다. @dragonroot 답변 참조)
Antoine Draune

15

필터 대신 태그를 간단한 태그로 등록하십시오. 이들은 여러 인수를 취할 수 있습니다. 그것을 호출하는 구문은 약간 다를 것이지만 그것은 단지 구문적인 설탕 변경 일뿐입니다.


2
이것은 내 문제에 대한 정답이었습니다. 이 함수에 템플릿 변수를 전달하려면 simple_tag.
Furbeenator 2015 년

1
이것은 좋은 해결책입니다. 다음과 같은 간단한 태그에 대한 django 문서를 확인하는 것이 좋습니다
Gunther

6

생각보다 간단 합니다. simple_tag

사용할 수 있습니다 .

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

템플릿에서 :

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

참고 : 서버를 다시 실행하는 것을 잊지 마십시오.



3

<내 사이트> /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조금 설명 해주시면 좋을까요?
Dan Abramov

1
자리 표시 자로 사용되는 임의의 문자열입니다. 이 문자열은 입력 문자열의 일부가 아니라고 믿었 기 때문에 선택했습니다. 예를 들어 '# f4x @ SgXXmS'대신 "{}"를 사용했다면 {{ "use {} instead off []"| search : "off"| replace : "of"}}는 다음을 반환합니다. "use of [] "대신 예상 된 결과가 아님 :"[] 대신 {} 사용 "
theosp

6
오, 말이 되네요. 그것을 SUBSTRING_THAT_NEVER_OCCURS생각 으로 선언하는 것이 좋을 것 입니다.
Dan Abramov

-1

다음과 같이 간단히 할 수 있습니다.

{% assign find_total_issued = dailysalesreport | find: "TotalIssued":"13" %}

public static List<object> Find(object collection, string column, string value)

그리고 함수의 추상화가이므로 목적지에 도달 할 것입니다 sjare.


-2

여기에 나쁜 생각이 있지만 작동합니다.

{{ 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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.