IT/Linux

[Python] django 게시판 게시글 번호 처리하기 - 템플릿 필터

액트 2022. 10. 12. 17:20

아래 사진과 같이 글 페이지 번호가 바뀌어도 게시글의 번호가 1부터 시작하는 오류를 해결하고자 합니다.

1번 페이지의 가장 맨 위에 있는 게시글의 번호는 전체 게시물 건수에 마지막 번호입니다.

즉 12개의 게스글이 있다면 1페이지에 가장 위에 있는 게시글의 번호는 12입니다.

페이지당 10개 단위로 보여지기 때문에 12부터 시작하면 12, 11, 10, 9, 8, 7, 6, 5, 4, 3 보여지게 될 것입니다.

12 ~ 3까지 총 10개 입니다.

두 번째 페이지에서는 2, 1 까지 보여져야 합니다.

이렇게 페이지별로 게시물의 번호를 역순으로 정렬하려면 게시글 번호에 다음과 같은 공식을 적용해야 합니다.

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

  • 시작 인덱스: 페이지당 시작되는 게시물의 시작 번호
    • 예를 들어, 페이지당 게시물을 10개씩 보여준다면 1페이지의 시작 인덱스는 1 입니다.  2페이지의 시작 인덱스는 11이 됩니다.
  • 현재 인덱스: 페이지에 보여지는 게시물 개수만큼 0부터 1씩 증가되는 번호

전체 게시물 수가 12개이고 페이지당 10개씩 게시물을 보여 준다면 공식에 의해 1페이지의 가장 위에 있는 게시물의 번호는 공식의 의해

12 - 1 - 0 + 1 = 12

가 됩니다. 주의해야할 점은 현재 인덱스는 0부터 시작한다는 것입니다.

가장 위에 있는 게시물의 번호가 12이므로 다음 두 번째 게시물의 번호는 공식의 의해

12 - 1 - 1 + 1 = 11

이 됩니다. 이렇게 반복되어 12- 1 - (0~9 순차적으로) + 1이 되어 12 ~ 3 까지 표시되고 2페이지의 경우에는 12 - 11 - (0, 1 순차적으로) +1 이 되어 2~1이 표시될 것입니다.

이제 이 공식을 코드로 작성해 보겠습니다.

게시글의 번호는 템플릿에서 공식에 의해 변환되어야 하는 값(변수)입니다.

장고에서는 템플릿 변수값의 변환을 위한 함수가 존재합니다.

바로 템플릿 필터입니다. 

템플릿 태그에서 | 문자 뒤에 사용하는 필터로써 변수를 처리합니다.

템플릿 필터를 사용하기 위해서는 템플릿 필터 파일들을 저장할 templatetags 디렉토리를 생성합니다.

경로는 mysite\pybo 하위에 위치해야 합니다.

그리고 templatetags 디렉토리에 pybo_filter.py 파일을 생성하고 다음과 같이 작성합니다.

from django import template

register = template.Library()

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

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

이제 작성한 sub 필터 함수를 템플릿에서 적용해 봅시다.

sub필터를 사용하기 위해서는 템플릿 상단에 다음처럼 {% load pybo_filter %} 로 sub 필터를 저장한 파일(pybo_filter.py)를 먼저 로드 해야 합니다.

아래와 같이 question_list.html 파일을 수정합니다.

{% extends 'base.html' %}
{% load pybo_filter %}    <!-- 템플릿 필터 함수를 사용하기 위한 파일 로드 -->
{% block content %}
<div class="container my-3">
    <table class="table">
        <thead>
        <tr class="table-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>{{ forloop.counter }}</td>
            ...(생략)
  • question_list.paginator.count: 전체 건수
  • question_list.start_index: 시작인덱스
  • forloop.counter(): 현재인덱스

위와 같이 수정하고 저장 후에 서버를 재시작합니다.

http://localhost/pybo 페이지를 새로고침하여 확인하시면 아래와 같이 정상적인 게시글의 모습을 확인하실 수 있습니다.

기존에 아래와 같이 5개의 게시글이 있는 상태에서 300개의 테스트 데이터를 추가했기 때문에 위와 같이 305부터 시작하는 것입니다.