0
0
0
share
#django#pagination
0 Komentar
Melakukan Pagination dengan Django
Diterjemahkan dari How to Paginate with Django karya Vitor Freitas.
Level menengah. Pembaca diasumsikan sudah pernah membuat aplikasi web dengan Django.
Pagination menjadi menjadi proses yang sering dilakukan oleh situs-situs yang menampilkan banyak data. Dengan melakukan pagination, kita bisa membagi banyak data menjadi beberapa halaman terpisah. Tutorial ini akan menunjukkan bagaimana melakukan pagination menggunakan function based views maupuan class-based views (ListView).
Membangun Aplikasi Mini HRD dengan Django (6): Menambahkan Pagination
Kelas Paginator
Kelas paginator ada di django.core.paginator
. Kita akan sering menggunakan kelas Paginator
dan Page
.
Anggap tabel auth.User
memiliki 53 user instances.
from django.contrib.auth.models import User
from django.core.paginator import Paginator
user_list = User.objects.all()
paginator = Paginator(user_list, 10)
Pada contoh di atas, penulis memberitahu Paginator
untuk melakukan pagination terhadap QuerySet user_list
yang terdiri dari 10 user per halaman. Perintah di atas akan menghasilkan 6 halaman. Ke 5 halaman yang pertama berisi 10 User sedangkan halaman terakhir berisi 3 User.
Debugging Objek Paginator
Input | Output | Type |
---|---|---|
paginator.count | 53 | <type 'int'> |
paginator.num_pages | 6 | <type 'int'> |
paginator.page_range | xrange(1, 7) | <type 'xrange'> |
paginator.page(2) | <Page 2 of 6> | <class 'django.core.paginator.Page'> |
Method Paginator.page()
akan mengembalikan halaman berdasarkan hasil pagination yang dilakukan dan menjadi objek bertipe Page
. Objek itulah yang akan kita kirim ke template.
users = paginator.page(2)
Debugging Objek Page
Input | Output | Type |
---|---|---|
users | <Page 2 of 6> | <class 'django.core.paginator.Page'> |
users.has_next() | True | <type 'bool'> |
users.has_previous() | True | <type 'bool'> |
users.has_other_pages() | True | <type 'bool'> |
users.next_page_number() | 3 | <type 'int'> |
users.previous_page_number() | 1 | <type 'int'> |
users.start_index() | 11 | <type 'int'> |
users.end_index() | 20 | <type 'int'> |
Method Page.next_page_number()
dan Page.previous_page_number()
dapat memanggil InvalidPage
jika halaman next/previous tidak ada.
Method Page.start_index()
dan Page.end_index()
relatif terhadap nomor halaman.
>>> users = paginator.page(6) # last page
<Page 6 of 6>
>>> users.start_index()
51
>>> users.end_index()
53
Proses ini terjadi dengan melakukan kueri ke database lalu mengirimkan QuerySet ke Paginator, mengambil sebuah objek Page dari Paginator dan mengirim objek Page ke template.
Mari lihat bagaimana penggunaannya praktisnya.
Pagination dengan Function-Based Views
views.py
from django.contrib.auth.models import User
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
def index(request):
user_list = User.objects.all()
page = request.GET.get('page', 1)
paginator = Paginator(user_list, 10)
try:
users = paginator.page(page)
except PageNotAnInteger:
users = paginator.page(1)
except EmptyPage:
users = paginator.page(paginator.num_pages)
return render(request, 'core/user_list.html', { 'users': users })
user_list.html
<table class="table table-bordered">
<thead>
<tr>
<th>Username</th>
<th>First name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user.username }}</td>
<td>{{ user.first_name }}</td>
<td>{{ user.email }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if users.has_other_pages %}
<ul class="pagination">
{% if users.has_previous %}
<li><a href="?page={{ users.previous_page_number }}">«</a></li>
{% else %}
<li class="disabled"><span>«</span></li>
{% endif %}
{% for i in users.paginator.page_range %}
{% if users.number == i %}
<li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
{% else %}
<li><a href="?page={{ i }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% if users.has_next %}
<li><a href="?page={{ users.next_page_number }}">»</a></li>
{% else %}
<li class="disabled"><span>»</span></li>
{% endif %}
</ul>
{% endif %}
Akan menghasilkan sesuatu seperti ini:
Contoh di atas menggunakan Bootstrap 3.
Pagination dengan Class-Based Views
views.py
class UserListView(ListView):
model = User
template_name = 'core/user_list.html' # Default: <app_label>/<model_name>_list.html
context_object_name = 'users' # Default: object_list
paginate_by = 10
queryset = User.objects.all() # Default: Model.objects.all()
user_list.html
<table class="table table-bordered">
<thead>
<tr>
<th>Username</th>
<th>First name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user.username }}</td>
<td>{{ user.first_name }}</td>
<td>{{ user.email }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if is_paginated %}
<ul class="pagination">
{% if page_obj.has_previous %}
<li><a href="?page={{ page_obj.previous_page_number }}">«</a></li>
{% else %}
<li class="disabled"><span>«</span></li>
{% endif %}
{% for i in paginator.page_range %}
{% if page_obj.number == i %}
<li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
{% else %}
<li><a href="?page={{ i }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li><a href="?page={{ page_obj.next_page_number }}">»</a></li>
{% else %}
<li class="disabled"><span>»</span></li>
{% endif %}
</ul>
{% endif %}
0
0
0
share