장고 - Page 기능 학습

함수형 뷰에서 paginator 없이 page 기능 구현

- 경로 : board_project > board > views.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from django.shortcuts import render
import math
def document_list(request):
page = int(request.GET.get('page',1))
# page가 없다면, default값 1로 설정 --> 127.0.0.1:8000/?page=1
paginated_by = 3
# 한 페이지당 갯수 3으로 설정
documents = Document.objects.all()
total_count = len(documents)
total_page = math.ceil(total_count/paginated_by)
page_range = range(1, total_page+1)
start_index = paginated_by * (page-1)
end_index = paginated_by * page
documents = documents[start_index:end_index]

return render(request, 'board/document_list.html',{'object_list':documents, 'total_page':total_page, 'page_range':page_range})

- 경로 : board_project > board > templates > board > document_list.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
{% extends 'base.html' %}

{% block content %}
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>User</th>
<th>Date</th>
</tr>
</thead>
{% for object in object_list %}
<tbody>
<tr>
<td>{{object.id}}</td>
<td><a href="{% url 'board:detail' object.id %}">{{object.title}}</a></td>
<td>{{object.author.username}}</td>
<td>{{object.updated}}</td>
</tr>
</tbody>
{% endfor %}
</table>

<nav aria-label="Page navigation">
<ul class="pagination justify-content-center">
{% for page in page_range %}
<li class="page-item"><a class="page-link" href="{% url 'board:list' %}?page={{page}}">{{page}}</a></li>
{% endfor %}
</ul>
</nav>
{% endblock %}


클래스형 뷰에서 paginator로 page 기능 구현

- 경로 : wps_blog > post > views.py

1
2
3
4
5
6
7
from django.views.generic.list import ListView
class PostList(ListView):
model = Post
# 클래스형 뷰 중, 리스트 뷰를 사용한다면 paginate_by에 숫자 설정하면, Paginator 객체 얻을 수 있다.
paginate_by = 3
paginate_orphans = 0 # 나머지 객체 수
template_name = 'post/post_list.html'

- 경로 : wps_blog > post > templates > post > post_list.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
{% extends 'base.html' %}

{% block content %}
<div class="row mt-3">
<div class="col col-md"></div>
<div class="col-10 col-md-8">
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>title</th>
<th>created</th>
<th>updated</th>
{% if user.is_authenticated %}
<th>update</th>
<th>delete</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for object in object_list %}
<tr>
<td>{{object.id}}</td>
<td><a href="{{object.get_absolute_url}}">{{object.title}}</a></td>
<td>{{object.created}}</td>
<td>{{object.updated}}</td>
{% if user.is_authenticated %}
<th><a href="{% url 'post:post_update' object.id %}">update</a></th>
<th><a href="{% url 'post:post_delete' object.id %}">delete</a></th>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>

{% if is_paginated %}
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center">
<!-- page.has_previous : 이전 페이지 여부 -->
{% if page_obj.has_previous %}
<li class="page-item"><a class="page-link" href="?page={{page_obj.previous_page_number}}">Previous</a>
</li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#">Previous</a></li>
{% endif %}
<!-- paginator.page_range : 페이지 범위 -->
{% for page in paginator.page_range %}
<!-- page 숫자 표시 -->
<li class="page-item"><a class="page-link" href="?page={{page}}">{{page}}</a></li>
{% endfor %}
<!-- page_obj.has_next : 다음 페이지 여부 -->
{% if page_obj.has_next %}
<li class="page-item"><a class="page-link" href="?page={{page_obj.next_page_number}}">Next</a></li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#">Next</a></li>
{% endif %}
</ul>
</nav>
{% endif %}
</div>
<div class="col"></div>
</div>
{% endblock %}


Paginator 학습

Paginator 란?

  • 리스트형 뷰에서 페이징 기능은 필수이다.
  • 직접 페이징 기능 구현은 가능하지만, 쉽게 페이징 기능을 구현해주는 모듈이 Paginator이다.

Paginator 기초

  • 모델 페이징하기

    1
    from django.core.paginator import Paginator
  • 전체 객체 수

    1
    paginator.count
  • 페이지 수

    1
    paginator.num_pages
  • 페이지 범위

    1
    paginator.page_range
  • 원하는 페이지 얻기

    1
    page = paginator.page(1)
  • 페이지에 속한 객체 목록

    1
    page.object_list
  • 다음 페이지 여부

    1
    page.has_next()
  • 이전 페이지 여부

    1
    page.has_previous()
  • 다음 페이지 번호

    1
    page.next_page_number()
  • 이전 페이지 번호

    1
    page.previous_page_number()
  • 다른 페이지 존재 여부

    1
    page.has_other_pages()
  • 해당 페이지 객체 인덱스

    1
    2
    page.start_index()
    page.end_index()
  • 리스트에 페이지 출력

    1
    2
    3
    {% for page_num in paginator.page_range %}
    <a href="?page={{page_num}}">{{page_num}}</a>
    {% endfor %}