🥞 BE
home

7. Pagination

Date
2023/04/02
Category
Web
Tag
Django
Detail
Likelion Study
블로그에는 점점 게시글이 많아질 것이고, 따라서 한 페이지에 일정한 갯수의 게시글만 보이게끔 페이지를 나눠 출력해야한다.

view 수정

home.html에서 보이는 글 목록을 페이징 할 것이기 때문에 home 함수를 수정한다.
from django.shortcuts import render, get_object_or_404, redirect from django.utils import timezone from django.core.paginator import Paginator from .models import Blog # Create your views here. def home(request): blogs = Blog.objects # 쿼리셋 # 메소드 # 블로그 모든 글들을 대상으로 blog_list = Blog.objects.all() # 블로그 객체 세 개를 한 페이지로 자르기 paginator = Paginator(blog_list, 3) # request된 페이지를 알아내고 page = request.GET.get('page') # request된 페이지를 얻어온 뒤 return 해주기 posts = paginator.get_page(page) return render(request, 'blog/home.html', {'blogs': blogs, 'posts': posts})
Python
복사
blog\views.py
Paginator(blog_list, 3) 구문을 통해 블로그 객체들을 3개씩 잘라준다. 이제 각 페이지마다 3개의 객체들이 존재하게 된다.
request.GET.get('page')는 ‘page’를 key 값으로 가지는 객체의 value를 가져온다. 이렇게 페이지 값을 얻었으면, posts = paginator.get_page(page)를 통해 원하는 page를 출력한다.

template 수정

{% extends 'base.html' %} {% block content %} <div class="container"> {% for blog in posts %} <div class="card"> <div class="card-body"> <h2 class="card-title">{{blog.title}}</h2> <h6 class="card-subtitle mb-2 text-muted">{{blog.pub_date}}</h6> <p class="card-text">{{blog.summary}}</p> <a href="{% url 'detail' blog.id %}" class="card-link">...more</a> </div> </div> <br> {% endfor %} </div> {% endblock %}
HTML
복사
blog\templates\blog\home.html
이제 서버를 실행해보면 페이지에 글이 3개만 뜨는 것을 확인할 수 있다.
다른 게시물도 볼 수 있게 페이지를 이동시켜야한다. 따라서,
{% extends 'base.html' %} {% block content %} <div class="container"> {% for blog in posts %} <div class="card"> <div class="card-body"> <h2 class="card-title">{{blog.title}}</h2> <h6 class="card-subtitle mb-2 text-muted">{{blog.pub_date}}</h6> <p class="card-text">{{blog.summary}}</p> <a href="{% url 'detail' blog.id %}" class="card-link">...more</a> </div> </div> <br> {% endfor %} {%if posts.has_previous%} <a href="?page=1">First</a> <a href="?page={{posts.previous_page_number}}">Previous</a> {%endif%} <span>{{posts.number}}</span> <span>of</span> <span>{{posts.paginator.num_pages}}</span> {%if posts.has_next%} <a href="?page={{posts.next_page_number}}">Next</a> <a href="?page={{posts.paginator.num_pages}}">Last</a> {%endif%} </div> {% endblock %}
HTML
복사
blog\templates\blog\home.html
다음과 같이 코드를 구성한다.
{%if posts.has_previous%} : 현재 보여지고 있는 페이지가 바로 posts이고, 이 posts에게 이전 페이지가 존재하는지 체크하는 부분이다. 만약 현재 페이지가 1이라면 if로 둘러싸인 부분은 출력되지 않는다.
<a href="?page=1">First</a> : page를 무조건 1로 설정해 첫 페이지로 돌아가게끔 한다.
<a href="?page={{posts.previous_page_number}}">Previous</a> : posts의 바로 이전 페이지를 의미한다.
{{posts.number}} : 현재 페이지 번호를 의미한다.
{{posts.paginator.num_pages}} : posts의 전체 페이지 갯수를 의미한다.
{%if posts.has_next%} : posts에게 다음 페이지가 존재하는지 체크한다. 마지막 페이지라면 if로 둘러싸인 부분은 출력되지 않는다.
{{posts.next_page_number}} : posts의 바로 다음 페이지를 의미한다.
{{posts.paginator.num_pages}} : posts의 전체 페이지 갯수를 의미한다.
?page=값 처럼 작성된 부분이 view함수로 page값을 전달하는 부분.
이렇게 된다. 버튼이 작으니 직접 UI도 바꿔보자.