블로그에는 점점 게시글이 많아질 것이고, 따라서 한 페이지에 일정한 갯수의 게시글만 보이게끔 페이지를 나눠 출력해야한다.
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도 바꿔보자.