반응형
[Django] Custom template tags and filters
사용자 정의 템플릿 태그
-장고에는 수많은 태그와 필터(built-in tags and filter)를 제공하지만, 그럼에도 불구하고 기본적으로 제공하는 태그와 필터가 아닌 자신만의 기능적인 태그나 필터가 필요할 때가 있다. 템플릿 엔진을 파이썬으로 된 커스텀 태그와 필터(Custom tags and filters)를 정의하여 확장이 가능하다.
Code Layout 코드 레이아웃
사용자 정의 태그와 필터를 지정하는 가장 일반적인 장소는 장고 앱 내부이다. 만약, 그것들이 현존하는 앱과 연관되어있다면, 그곳에 번들로 묶는 것이 좋다. 그렇지 않으면, 새로운 앱에 그것들을 추가할 수 있다. 장고 앱을 INSTALLED_APPS에 추가하면 아래 설명된 기존 위치에서 정의한 태그가 템플릿 내에서 로드 할 수 있게 된다.
이 앱은 models.py, views.py등과 같은 레벨에 templatetags 폴더를 포함해야 한다. 만약, 존재하지 않는다면, templatetags 폴더를 생성한다. : 해당 폴더가 파이썬 패키지로 인식되도록 __init__.py파일을 잊지 마라.
*개발 서버가 자동으로 재시작되지 않는다.
templatetags모듈을 추가한 후에는 템플릿에서 태그 또는 필터를 사용하기 전에 서버를 재시작해야 한다.
사용자 지정 태그 및 필터는 templatetags 디렉토리 내부의 모듈에 저장됩니다. 모듈 파일 이름은 나중에 태그를 로드하는데 사용하는 이름이기 떄문에, 다른 앱의 사용자 정의 태그와 필터들과 이름이 충돌되지 않도록 선언하도록 조심해야 한다.
예를 들어, 만약 사용자 정의 태그/필터들을 정의한 파일 명이 poll_extras.py인 경우, 앱 레이아웃은 다음과 같아 보일 수 있다.
그리고 템플릿에서 다음과 같은 것을 사용할 것이다.
{% load poll_extras %}
커스텀 태그가 포함된 앱은 {% load %} 태그가 작동하려면 INSTALLED_APPS(settings.py)에 있어야 한다. 템플릿 태그 패키지에 모듈 개수 제한이 없다. {% load %} 문이 앱 이름이 아닌 지정된 파이썬 모듈 이름에 대한 태그/필터를 로드한다는 것을 명심해라. 보안 기능 : 장고를 설치할 때마다 액세스 할 필요없이 단일 컴퓨터에서 많은 템플릿 라이브러리에 대한 파이썬 코드를 호스트 할 수 있도록 한다.
유효한 태그 라이브러리가 되려면, 모듈에 template의 인스턴스인 register라는 모듈 수준 변수(a module-level variable)가 포함되어야 한다. Library 인스턴스에 모든 태그와 필터가 등록된다. 따라서 모듈 상단에 다음과 같이 넣어라.
from django import template register = template.Library()
대안으로, 템플릿 태그 모듈을 “libraries"을 통해 DjangoTemplates에 등록할 수 있다. 템플릿 태그를 로드할 때 템플릿 태그 모듈 이름과 다른 레이블을 사용하려면 이 옵션이 유용하다. 또한 응용프로그램을 설치하지 않고 태그를 등록할 수도 있다.
*장고의 이미 선언된(기본) 필터와 태그들은 “django/template/defaultfilters.py”와 “Django/template/defaulttags.py”에 있다.
Writing custom template filters 사용자 정의 템플릿 필터 작성
사용자 정의 필터들은 1개 또는 2개의 인수를 취하는 파이썬 함수이다.
-변수 값(입력값)은 필수적으로 문자열이 아니다.
-인수 값 - 기본 값을 가질 수도 있고 모두 생략할 수도 있다.
예를 들어, `{{ var|foo:”bar”}}`에서 필터 foo는 변수 var와 인수 “bar”를 전달한다.
템플릿 언어는 예외 처리를 제공하지 않기 때문에, 템플릿 필터에서 발생되는 예외는 서버 에러로 나타난다. 따라서, 필터 함수는 반환할 합리적인(reasonable) 대체값이 있는 경우 예외를 발생하지 않아야 한다. 템플릿의 명확한 버그를 나타내는 입력의 경우, 예외를 발생시키는 것이 버그를 숨기는 실패(silent failure which hides the bug)보다 더 좋을 수 있다.
여기 필터 정의 예제이다.
def cut(value, arg): """Removes all values of arg from the given string""" return value.replace(arg, '')
그리고 필터를 사용하는 방법에 대한 예제이다.
{{ somevariable|cut:"0" }}
대부분의 필터는 인수를 갖지 않는다. 이 경우, 인수를 함수에서 제외한다. 예를 들어 :
def lower(value): # Only one argument. """Converts a string into all lowercase""" return value.lower()
Registering custom filters 사용자 정의 필터 등록
`django.template.Library.filter()`
필터를 정의했다면, 장고의 템플릿 언어에서 사용할 수 있도록 Library인스턴스에 필터를 등록해야 한다.
register.filter('cut', cut) register.filter('lower', lower)
Library.filter() 메소드는 두개의 인자를 갖는다.
1. The name of the filter 필터의 이름 - 문자열(string)
2. The compilation function 컴파일 함수 - 파이썬 함수 ( 문자열로된 함수 이름이 아님. )
데코레이터 대신 register.filter()를 사용할 수 있다 :
@register.filter(name='cut') def cut(value, arg): return value.replace(arg, '') @register.filter def lower(value): return value.lower()
만약 위의 두번째 예제에서 처럼 name 인자를 사용하지 않으면, 장고는 함수의 이름을 필터 이름으로 사용한다.
마지막으로, register.filter()는 또한 세 가지 키워드 인자인 is_safe, needs_autoscape 그리고 expects_localtime를 허용한다. 이러한 인자들은 filters and auto-escaping과 filters and time zones에 설명되어 있다.
반응형
'Python > Django' 카테고리의 다른 글
[Django] 데이터베이스에 초기(initial) 데이터 입력방법 (0) | 2019.01.22 |
---|---|
[Django] Performing raw SQL queries : SQL 쿼리 맵핑 (0) | 2019.01.21 |
[Django] context_processors 콘텍스트 프로세서 (0) | 2019.01.16 |
[Python][Django] HttpRequest 객체 정보 (0) | 2019.01.12 |
[Python][Django] 모델 (0) | 2019.01.11 |