728x90
반응형
페이지네이션은 보여주고자 하는 데이터가 많을 때 구현한다. 페이지네이션을 구현하기 위해서 데이터를 많이 생성하고자 한다.
1. 가짜 데이터 만들기
python manage.py shell
데이터가 없으므로 장고 셸을 구동하여 데이터를 만들어주자!
>>> from pybo.models import Question
>>> from django.utils import timezone
질문 데이터를 생성하기 위한 모듈을 임포트한다.
for i in range(300):
... q = Question(subject='테스트 데이터입니다:[%03d]' % i, content='내용무', create_date=timezone.now())
... q.save()
q변수를 선언할 때 shift+enter를 써서 내려쓰기를 해준다. 그리고 탭을 써서 들여쓰기를 해줘야 오류가 나지 않는다. 들여쓰기를 하지 않을 경우 다시 변수선언해주어야 한다.
해당 코드를 다 썼다면 quit()를 써서 셸을 나와 준다.
2. 페이지네이션 구현하기
// pybo\\views.py
from django.core.paginator import Paginator
def index(request):
page = request.GET.get('page', '1') # 페이지
question_list = Question.objects.order_by('-create_date')
paginator = Paginator(question_list, 10) # 페이지당 10개씩 보여주기
page_obj = paginator.get_page(page)
context = {'question_list': page_obj}
return render(request, 'pybo/question_list.html', context)
- 페이징을 위해 사용하는 클래스는 Paginator이다. 그러므로 이를 임포트해준다.
- page = request.GET.get('page', '1') : GET 방식으로 호출된 URL에서 page값을 가져온다. page값 없이 호출되면 default값으로 1을 지정한다.
- paginator = Paginator(question_list, 10) : 첫 번째 파라미터 question_list는 게시물 전체를 의미하는 데이터이고, 두번째 파라미터 10은 페이지당 보여줄 게시물의 개수이다. 질문 테이블에 있는 데이터를 가져와서 페이지당 10개 보여주고자 한다.
- page_obj = paginator.get_page(page) : paginator를 이용하여 요청된 페이지(page)에 해당되는 페이징 객체(page_obj)를 생성한다.
3. 템플릿에 페이징 적용하기
전달한 데이터를 템플릿에 적용한다. 페이지네이션을 ul, li태그를 이용하여 구현하고자 한다. question_list.html에 적용한다.
1) 이전
<li
class="page-item{% if not question_list.has_previous %} disabled{% endif %}"
>
{% if question_list.has_previous %}
<a class="page-link" href="?page={{ question_list.previous_page_number }}"
>이전</a
>
{% else %}
<span class="page-link" tabindex="-1" aria-disabled="true">이전</span>
{% endif %}
</li>
2) 다음
<li
class="page-item{% if not question_list.has_next %} disabled{% endif %}"
>
{% if question_list.has_next %}
<a class="page-link" href="?page={{ question_list.next_page_number }}"
>다음</a
>
{% else %}
<span class="page-link" tabindex="-1" aria-disabled="true">다음</span>
{% endif %}
</li>
3) range를 적용하여 범위 페이지 보여주기
// pybo/views.py
def index(request):
page = request.GET.get('page', '1') # 페이지
question_list = Question.objects.order_by('-create_date')
paginator = Paginator(question_list, 10) # 페이지당 10개씩 보여주기
page_obj = paginator.get_page(page)
leftIndex = (int(page) - 2)
if leftIndex <1:
leftIndex =1
rightIndex = (int(page) + 2)
if rightIndex > paginator.num_pages:
rightIndex = paginator.num_pages
custom_range = range(leftIndex, rightIndex+1)
context = {'question_list': page_obj, 'custom_range':custom_range}
return render(request, 'pybo/question_list.html', context)
- 현재 페이지를 기준으로 왼쪽과 오른쪽에 보여줄 페이지 갯수를 지정하고자 한다.
- leftIndex : 최소 1 페이지는 되어야 하기에 1페이지보다 작아지면 1페이지가 되도록 지정해준다.
- rightIndex : 페이지가 생성된 갯수보다는 넘기지 않아야 되므로 이를 넘으면 이로 지정되게끔 해주었다.
- custom_range : range로 지정하여 넘겨주고자 하였다. range는 마지막인덱스 +1을 해주어야 한다.
// templates/pybo/question_list.html
{% for page_number in custom_range %}
<li
class="page-item{% if page_number == question_list.number %} active{% endif %}"
>
<a class="page-link" href="?page={{ page_number }}">{{ page_number }}</a>
</li>
{% endfor %}
views.py에서 넘겨준 custom_range를 for문으로 돌려 페이지리스트를 보여주게 하였다. 그리고 현재 페이지의 경우에는 li태그가 active가 되게 하였다.
4) 처음
<li class="page-item">
<a class="page-link" href="?page=1">처음</a>
</li>
5) 끝
// pybo/views.py
max_index = len(paginator.page_range)
- 마지막 페이지를 구현하기 위해 page_range의 길이를 구하면 끝 페이지의 수가 나온다. 이를 템플릿으로 넘겨주어 구현한다.
<li class="page-item">
<a class="page-link" href="?page={{max_index}}">끝</a>
</li>
👇🏻 참고 사이트
https://yeko90.tistory.com/entry/django-기초-페이징-처리pagination-마스터-하기
728x90
반응형