본문 바로가기
개인 공부/개발

sfoj 개발 - 문제 조회 템플릿 페이징 구현

by 아메리카노와떡볶이 2021. 8. 31.
728x90
sfoj 개발 - 문제 조회 템플릿 페이징 구현

이번에는 페이징을 구현할 차례이다.

1. 회원가입 구현
https://man-25-1.tistory.com/149?category=1038743

2. 작성자 표시하기
https://man-25-1.tistory.com/150?category=1038743

 

현재 페이지의 모습을 보면 문제개수에 상관없이 그냥 쭉 나열된다. 가독성이 굉장히 떨어지기때문에 한 페이지당 15개의 문제를 표시하도록 페이징을 구현할 것이다.

 

 

1. 테스트를 위한 데이터 생성

현재는 글이 8개 밖에 작성되어있지않은데, 페이징 테스트를 위해 임의로 100개 정도의 글을 생성할 것이다.

하나씩 작성하는 것은 시간이 오래걸리기때문에 장고 셸을 이용하면 많은 데이터도 간편하게 생성할 수 있다.

(mysite) D:\projects\mysite>python manage.py shell
Python 3.9.5 (tags/v3.9.5:0a7dcbd, May  3 2021, 17:27:52) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>

shell 에 접속해서 for 문을 이용해서 데이터를 생성할 것이다.

그 전에 board 모델을 살펴보자.

현재 hit와 suceess_per 속성은 사용하지않기때문에 주석처리 해두었다. 따라서 사용하는 속성은 총 5개이다.

다시 셸로 돌아가서 모델의 속성에 맞게 데이터를 생성해보자.

 

먼저 필요한 모듈을 import 하고 로그인해준다.

 

>>> from sfoj_system.models import Board
>>> from django.utils import timezone
>>> from django.contrib.auth import authenticate
>>> user = authenticate(username='seongyeob',password='*****')
>>> user.username
'seongyeob'

로그인을 하는 이유는, 이전에 글을 작성할때 로그인한 작성자가 표시되도록 구현해두었기때문이다.

 

>>> for i in range(100):
...     q= Board(UserID_id=user.id,Title='테스트 글입니다.[%03d]' % i, Content='test', Reg_date=timezone.now())
...     q.save()
...
>>>

서버를 실행해서 데이터가 잘 생성되었는지 확인해보자.

 

잘 생성된 것을 확인할 수 있다.

 

Paginator 클래스 사용하기.

장고에서 페이징을 위해 사용하는 클래스는 Paginator이다. Paginator 클래스를 사용해서 기존의 list함수를 수정하자.

 

기존

views.py

def list(request):
    board_list = Board.objects.order_by('Reg_date')
    context = {'Board_list': board_list}
    return render(request, 'sfoj_system/Board_list.html', context)

기존에는 Board 모델의 객체를 생성일자로 정렬한 board_list 를 반환했었다.

 

수정 후

views.py

def list(request):
    # parameter
    page = request.GET.get('page', '1')  # 페이지

    # list 조회
    board_list = Board.objects.order_by('-Reg_date')

    # 페이징 처리
    paginator = Paginator(board_list, 15)  # 한 페이지에 15개씩
    page_obj = paginator.get_page(page)

    context = {'board_list': page_obj}
    return render(request, 'sfoj_system/Board_list.html', context)

수정 후에는 한 페이지에 15개의 게시물을 포함하는 page_obj를 board_list로 템플릿에 전달한다.

 

페이징 객체 속성은 유용하게 쓰인다. 알아두자

 

템플릿에 페이징 적용하기

이제 전달받은 페이징 객체 board_list를 가지고 템플릿에서 화면에 출력해보자.

 

수정 전

{% if Board_list %}
        {% for board in Board_list %}
        <tr>
            <!-- 번호/제목/작성일자/작성자  -->
            <td class="board_list_table_td">{{ forloop.counter }}</td>
            <td class="board_list_table_td">
                <a href="{% url 'sfoj_system:detail' board.index %}">{{ board.Title }}</a>
            </td>
            <td class="board_list_table_td">{{ board.Reg_date }}</td>
            <td class="board_list_table_td">{{ board.UserID }}</td>
        </tr>
        {% endfor %}
        {% else %}

 

sfoj_system 앱 하위에 templatetags 디렉토리를 생성하고 sfoj_filter.py 를 생성해서 sub 필터를 만들어주었다.

sub 필터를 사용해서 인덱스까지 페이지별로 표시되도록 수정했다.

 

수정 후

{% if board_list %}
        {% for board in board_list %}
        <tr>
            <td class="board_list_table_td">
                <!-- 번호 = 전체건수 - 시작인덱스 - 현재인덱스 + 1 -->
                <!-- board_list.paginator.count : 전체건수
                     board_list.start_index : 시작 인덱스
                     forloop.counter0 : 현재 인덱스 -->
                {{ board_list.paginator.count|sub:board_list.start_index|sub:forloop.counter0|add:1 }}
            </td>
            <!-- /제목/작성일자/작성자  -->
            <td class="board_list_table_td">
                <a href="{% url 'sfoj_system:detail' board.index %}">{{ board.Title }}</a>
            </td>
            <td class="board_list_table_td">{{ board.Reg_date }}</td>
            <td class="board_list_table_td">{{ board.UserID }}</td>
        </tr>
        {% endfor %}
        {% else %}

 

결과

다음 목표는 문제검색 !

728x90

댓글