지금이야 게시글 개수가 몇개 없지만, 늘어난다면 어떻게 될까?
장고 쉘을 이용해서 게시글 개수를 늘려보자.
>>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()
페이징을 하지 않았으므로 스크롤이 굉장히 길어진다. 이제 페이징을 통해 화면을 개선해보자.
from django.core.paginator import Paginator
...
...
def index(request):
'''
pybo 목록 출력
'''
page = request.GET.get('page',1) # 페이지 / GET방식으로 page를 파라미터로 가져올 때 사용, 파라미터 없이 들어올 때 dafault값을 1로 줌.
# 조회
question_list = Question.objects.order_by('-create_date') # -로 역순
# 페이징
paginator = Paginator(question_list,10) # 한 페이지당 개수
page_obj = paginator.get_page(page)
context = {'question_list':page_obj}
# return HttpResponse('Hi pybo') # Hi pybo를 response해라
return render(request,'pybo/question_list.html',context)
장고에서 지원하는 페이지네이터를 불러오고 request.GET.get( )을 이용해서 get 으로 전달되는 파라미터를 통해 보여줄 페이지를 결정하자.
url은 localhost:8000/pybo/?page=1 이렇게 기본값을 줄 수 있다.
paginator를 통해서 question_list를 10개로 자르고, url에서 받아온 page를 통해서 해당 페이지의 객체를 반환한다.
이제 보기 좋게 10개씩 끊어진 데이터를 볼 수 있다.
이제 페이지 이동기능을 추가하자.
책에선 여러 단계로 진행했지만, 한번에 진행하자.
...
</table>
<!-- 페이징 시작-->
<ul class="pagination justify-content-center">
<!-- 이전 페이지-->
{% if question_list.has_previous %}
<li class="page-item">
<a class="page-link"
href="?page=1">
처음
</a>
</li>
<li class="page-item">
<a class="page-link"
href="?page={{ question_list.previous_page_number }}">
이전
</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" tabindex="-1" aria-disabled="true" href="#">
이전
</a>
</li>
{% endif %}
<!-- 페이지 리스트-->
{% for page_number in question_list.paginator.page_range %}
{% if page_number >= question_list.number|add:-5 and page_number <= question_list.number|add:5 %}
{% if page_number == question_list.number %}
<li class="page-item active" aria-current="page">
<a class="page-link" href="?page={{ page_number }}">
{{ page_number }}
</a>
</li>
{% else %}
<li class="page-item">
<a class="page-link" href="?page={{ page_number }}">
{{ page_number }}
</a>
</li>
{% endif %}
{% endif %}
{% endfor %}
<!-- 다음 페이지-->
{% if question_list.has_next %}
<li class="page-item">
<a class="page-link"
href="?page={{ question_list.next_page_number }}">
다음
</a>
</li>
<li class="page-item">
<a class="page-link"
href="?page={{ question_list.paginator.num_pages }}">
마지막
</a>
</li>
{% else %}
<li class="page0item disabled">
<a class="page-link" tabindex="-1" aria-disabled="true" href="#">
다음
</a>
</li>
{% endif %}
</ul>
<!-- 페이징 끝-->
<a href="{% url 'pybo:question_create' %}" class="btn btn-primary">
질문 등록
</a>
</div>
{% endblock %}
추가한게 굉장히 많다.
question_list가 views.py에서 전달된 페이지된 결과 객체이다.
즉, question_list.previous_page_number 는 페이지화되어 입력받은 페이지에서 이전 페이지와 같은 의미이다.
쉽게 풀어 설명하자면, question_list가 이전에 300여개의 리스트였다면,
views.py에서 paginator를 통해서 10개 묶음으로 자른 다음, pybo에서 GET으로 page인자를 전달받고,
page 숫자에 해당하는 묶음을 html로 전달한다.
paginator는 previous_page_number 처럼 이전 페이지를 반환할 수 있다.
즉 이전 페이지가 있다면, 이전 링크와 처음 링크를 활성화 시키고 이동할 수 있게 한다.
다음 버튼과 마지막 버튼도 마찬가지이다.
이제 한번에 보여지는 페이지 개수를 줄이는 단계이다.
{% for page_number in question_list.paginator.page_range %}
{% if page_number >= question_list.number|add:-5 and page_number <= question_list.number|add:5 %}
{% if page_number == question_list.number %}
<li class="page-item active" aria-current="page">
<a class="page-link" href="?page={{ page_number }}">
{{ page_number }}
</a>
</li>
{% else %}
<li class="page-item">
<a class="page-link" href="?page={{ page_number }}">
{{ page_number }}
</a>
</li>
{% endif %}
{% endif %}
{% endfor %}
이 구문을 보면,
paginator.page_range 를 for문을 통해서 반복하는데,
여기서 할당되는 page_number가 question_list.number ( = 현재 페이지 번호 ) 보다 5작거나 같은 경우,
그리고 5보다 큰 범위 일때만 출력하게한다.
|add:-5는 -5만큼 더하라, 즉 5만큼 빼라는 의미이고, 동일하게 |add:5는 5만큼 더하라는 의미이다.
자 이제 페이징기능이 끝났다.
'python > Django' 카테고리의 다른 글
[Django] 클라이언트에서 파일을 다운로드 해보자. (0) | 2022.05.25 |
---|---|
[Django] 11. 네비게이션 기능 추가 (0) | 2021.12.29 |
[Django] 10 . 표준 HTML으로 만들기 (0) | 2021.12.28 |
[Django] 9. 부트스트랩을 적용시키자. (0) | 2021.12.27 |
[Django] 8. 답변기능 구현 (0) | 2021.12.23 |