Web/Django

장고(Django) 템플릿 필터 생성 및 적용하기

daeunnniii 2021. 8. 4. 01:05
728x90
반응형

1. 템플릿 필터

템플릿 필터란 템플릿 태그에서 | 문자 뒤에 사용하는 필터를 말한다. 예를 들어 아래 default_if_none은 템플릿 필터이다.

{{ form.subject.value|default_if_none:'' }}

 

2. 게시물 번호

이전 게시물에서 구현했던 '페이징' 기능에는 아직 문제점이 하나 있다. 모든 페이지에서 게시물 번호가 항상 1부터 시작된다는 점이다. 이제 템플릿 필터를 활용하여 이 문제를 해결해볼 것이다.

 

먼저, 최근 게시물이 먼저 보여야하므로 게시물의 번호를 역순으로 정렬해야하고, 페이지별 게시물의 번호를 역순으로 정렬하려면 아래와 같은 공식을 적용해야한다.

번호 = 전체건수 - 시작인덱스 - 현재인덱스 + 1

시작 인덱스: 페이지 당 시작되는 게시물의 시작 번호

현재 인덱스: 페이지에 보여지는 게시물 개수만큼 0부터 1씩 증가되는 번호

따라서 전체 게시물 개수가 12개이고, 페이지당 10건씩 게시물을 보여준다면 1페이지의 번호는 12-1-(0~9 반복)+1이 되어 12~3까지 표시되고, 2페이지의 경우에는 12-11-(0~1 반복)+1이 되어 2~1이 표시될 것이다.

위 공식을 템플릿에서 구현하려면 빼기 기능이 필요하다. 하지만, 장고에는 빼기 필터가 없으므로 직접 만들어야한다. |add:-3 과 같이 숫자를 직접 입력하면 빼기 필터와 동일한 효과를 낼 수 있지만, add 필터에는 변수를 적용할 수 없고, add 필터는 인수로 숫자만 가능하다.

 

 

3. 템플릿 필터 작성하기

notes 디렉터리 내부에 템플릿 필터 파일을 저장할 templatetags 디렉터리를 생성한다.

그리고 templatetags에 notes_filter.py 파일을 생성하고 아래와 같이 작성한다.

from django import template

register = template.Library()

@register.filter
def sub(value, arg):
    return value - arg

위처럼 sub 함수에 @register.filter 애너테이션을 적용하면 템플릿에서 해당 함수를 필터로 사용할 수 있게 된다. sub 필터는 기존 값 value에서 입력으로 받은 값 arg를 빼서 리턴한다.

 

4. 템플릿 필터 적용하기

sub 필터를 템플릿에서 사용하기 위해서는 템플릿 상단에 {% load notes_filter %}로 해당 필터를 저장하고 있는 파일을 로드해주어야한다. 이제 question_list 을 아래와 같이 변경한다.

{% extends 'base.html' %}
{% load notes_filter %}
{% block content %}
<div class="container my-3">
    <table class="table">
        <thead>
        <tr class="thead-dark">
            <th>번호</th>
            <th>제목</th>
            <th>작성일시</th>
        </tr>
        </thead>
        <tbody>
        {% if question_list %}
        {% for question in question_list %}
        <tr>
            <td>
                <!-- 번호 = 전체건수 - 시작인덱스 - 현재인덱스 + 1 -->
                {{ question_list.paginator.count|sub:question_list.start_index|sub:forloop.counter0|add:1 }}
            </td>
            <td>
                <a href="{% url 'notes:detail' question.id %}">{{ question.subject }}</a>
            </td>
            <td>{{ question.create_date }}</td>
        </tr>
(... 생략 ...)

 

이제 다시 서버를 실행시켜보면 게시물 페이지 번호 문제가 해결된 것을 확인할 수 있다.

 

 

 

참고: https://wikidocs.net/71313

728x90
반응형