Django 프론트& 백엔드 개발

Django 페이지네이션 구조 이해하기: View와 HTML 템플릿의 역할 분리

Data Jun 2026. 1. 17. 10:16

게시글 목록이 많아질수록 한 화면에 모두 보여주는 것은 비효율적이다.
Django의 Paginator는 조회 결과를 페이지 단위로 나누고,
쿼리 스트링을 통해 어떤 페이지를 볼지 결정하는 구조를 제공한다.


이번 글에서는 페이지네이션이 어떻게 동작하는지 흐름 중심으로 정리한다.

 

1. 페이지네이션의 핵심 구조

페이지네이션은 다음 두 단계로 동작한다.

 

1️⃣ 서버(View)

  • 전체 데이터를 페이지 단위로 분리
  • 현재 페이지 번호에 해당하는 데이터만 전달

2️⃣ 클라이언트(Template)

  • ?page=숫자 형태의 링크로
  • 다음 / 이전 페이지 요청

즉, 같은 리소스를 다른 조건으로 조회하는 구조다.

 

2. View에서의 역할 (Paginator)

from django.shortcuts import render, redirect, get_object_or_404
from .models import Post
from django.core.paginator import Paginator


# Create your views here.
def post_list(request):
    posts = Post.objects.all()
    paginator = Paginator(posts, 6)
    curr_page_number = request.GET.get('page') # 쿼리 스트링 데이터 Key 값으로 접근 
    if curr_page_number is None: # 첫번쩨 페이지일 경우
        curr_page_number = 1
    page = paginator.page(curr_page_number) # 해당 페이지의 데이터 가져오기
    return render(request, 'posts/post_list.html', {'page': page})
  • Paginator(posts, 6)
    → 한 페이지에 게시글 6개
  • request.GET.get('page')
    → 쿼리 스트링으로 페이지 번호 전달
  • paginator.page(n)
    → n번째 페이지 데이터만 추출

DB 상태는 변경되지 않고 조회만 수행한다.

 

3. Template에서의 역할 

1️⃣ 페이지네이션에서 HTML 템플릿의 역할

 

HTML 템플릿은 페이지네이션에서 다음 두 가지를 담당한다.

  • 현재 페이지의 데이터 렌더링
  • 다음 / 이전 페이지로 이동할 링크 제공

즉,

View가 “무슨 데이터를 줄지” 결정한다면
Template은 “어떻게 보여주고 이동할지”를 결정한다.

 

2️⃣ 페이지 이동 영역(paginator)의 기본 구조

<div class="paginator">
    {% if page.has_previous %}
        <a href="?page=1">first</a>
        <a href="?page={{ page.previous_page_number }}">prev</a>
    {% endif %}

    <span>
        {{ page.number }} of {{ page.paginator.num_pages }}
    </span>

    {% if page.has_next %}
        <a href="?page={{ page.next_page_number }}">next</a>
        <a href="?page={{ page.paginator.num_pages }}">last</a>
    {% endif %}
</div>

 

3️⃣ 각 요소의 의미 정리

(1) page.has_previous, page.has_next

  • 이전 / 다음 페이지 존재 여부
  • 잘못된 페이지 이동 방지용 조건문

없는 페이지로 이동하는 링크를 막는 역할

 

(2) ?page=숫자 링크

<a href="?page=2">
  • 현재 경로 기준 상대 경로
  • 경로는 유지
  • 쿼리 스트링만 교체

/posts/?page=1 → /posts/?page=2

(3) 현재 페이지 정보 표시
{{ page.number }} of {{ page.paginator.num_pages }}​
  • 현재 페이지 번호
  • 전체 페이지 개수

사용자에게 현재 위치를 명확히 보여줌

 

4️⃣ HTML 템플릿 기준 페이지네이션 흐름 요약

 

(1) 사용자가 ?page=2 클릭

(2) 브라우저가 GET 요청 전송

(3) View에서 해당 페이지 데이터 생성

(4) Template에서:

  • page.object_list 렌더링
  • has_next / has_previous로 이동 링크 생성

View와 Template이 역할을 분리한 구조

 

4. 정리하면

Django 페이지네이션은
GET 요청과 쿼리 스트링을 이용해
같은 리소스를 페이지 단위로 나누어 조회하는 구조다.