본문 바로가기
Research/Django

[Django] 점프 투 장고 튜토리얼 - 03-3. 템플릿 필터

by RIEM 2021. 11. 16.

Django 점프 투 장고 정리

작성일 : 2021-11-16

문서버전 : 1.0

 

개요

이 문서는 점프 투 장고 사이트의 장고 튜토리얼 학습 내용을 정리한 내용입니다.

레퍼런스

점프 투 장고 https://wikidocs.net/72242

3.3 - 템플릿 필터

템플릿 필터란 템플릿 태그에서 ‘|’ 문자 뒤에 사용하는 필터를 지칭한다. 

{{ form.subject.value|default_if_none:’’}} 의 경우 default_if_none이 템플릿 필터다. 템플릿 필터를 직접 만들어서 사용해보자.

게시물 번호 오류

문제가 생겼다. 아래와 같이 페이지를 이동하더라도 게시글의 index 번호가 항상 1에서 시작되는 것을 알 수 있다.

 

위 오류를 해결하자.

 

게시물 번호

게시글 전체 건수가 12개일 경우 첫번째 페이지는 번호가 12~3까지 역순으로 나타나고, 두번째 페이지에는 2~1이 나타나야 한다. 페이지 별로 게시물의 번호를 역순으로 정렬하기 위해 아래와 같이 공식을 적용해보자.

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

 

시작인덱스 : 페이지당 시작되는 게시글 시작 번호를 지칭한다. 예를 들어 페이지당 게시물을 10건씩 보여줄 경우 1페이지의 시작 인덱스는 1이고, 2페이지 인덱스는 11이다. 

현재인덱스 : 페이지에 보여지는 게시물 개수만큼 0부터 1씩 증가하는 번호다. 전체 게시물 개수가 12개고 페이지당 10건씩 게시물 보여줄 경우 공식에 의해 1페이지의 번호는 ‘12-1-(0~9) + 1’이 되어 12~3까지 표시되고, 2페이지는 ‘12-11-(0~1)+1’이 되어 2~1이 표시된다.

 

템플릿에서 이 공식을 적용하기 위해 빼기 기능이 필요하다. 앞서 더하기 필터(|add:5)를 사용한 것처럼 빼기 필터(|sub:3)가 필요하다. 장고에는 빼기필터가 없으니 직접 만들어보자.

 

‘|add:-3’와 같이 숫자를 직접 입력하면 더하기 필터를 이용해 원하는 값을 뺀 결과를 화면에 보여줄 수는 있다. 하지만 add필터는 인수로 숫자만 올 수 있어서 이 방법은 이곳에서 사용이 어렵다. add필터에는 변수 적용이 불가하기 때문이다. 

 

템플릿 필터 작성

템플릿 필터 작성 전 템플릿 필터 파일 저장할 ‘templatetags’ 디렉터리가 필요하다. 해당 디렉터리는 반드시 ../projects/mysite/pybo인 앱디렉터리 하위에 생성해야 한다. 

그리고 해당 디렉터리 내 아래와 같이 pybo_filter.py 파일을 생성해주자.

> ../projects/mysite/pybo/templatetags/pybo_filter.py

from django import template

register = template.Library()


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

 

@register.filter annotation을 적용해서 템플릿에서 위 함수를 필터로 사용할 수 있게 한다. 위에서 정의된 Sub 필터를 보면 기존 value 값에서 입력으로 받은 arg값을 빼낸 값을 return하는 것을 알 수 있다.

 

템플릿 필터 사용하기

템플릿에서 작성한 sub 필터를 사용해보자.

sub필터 사용을 위해선 템플릿 상단에 {% load pybo_filter %}로 sub필터 저장한 pybo_filter.py을 로드해줘야 한다.

만약 템플릿 상단에 extends 문이 있을 경우 load문은 extends문의 다음 순서에 위치해야 한다.

  • extends문(선)
  • load문(후)


> ../projects/mysite/templates/pybo/question_list.html

{% extends 'base.html' %}

{% load pybo_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 'pybo:detail' question.id %}">{{ question.subject }}</a>

            </td>

            <td>{{ question.create_date }}</td>

        </tr>

(... 생략 ...)

 

{% load pybo_filter %} 문을 상단에 적어준 뒤 번호 부분에는 공식을 적용한 모습이 보인다.



공식 코드
전체건수 question_list.paginator.count
시작인덱스 question_list.start_index
현재인덱스 forloop.counter0

 

 


댓글