Membangun Aplikasi Mini HRD dengan Django (6): Menambahkan Pagination

Ridwan Fajar 21 Juni 2016

Membangun Aplikasi Mini HRD dengan Django (6): Menambahkan Pagination

Akhirnya sampai juga di bagian ke enam dari 8 tulisan yang akan membahas garis besar web framework Django ini. Jika di tutorial sebelumnya kita telah membahas cara menambahkan sebuah chart atau grafik untuk menampilkan suatu rangkuman data berupa data kehadiran. Sekarang kita akan mengenal bagaimana cara membuat sebuah pagination di Django.

Pagination adalah sebuah cara menampilkan kumpulan data tanpa sekaligus menampilkannya. Bila hasil sebuah query ke database mengatakan ada 10.000 data yang dapat ditampilkan, maka untuk keperluan tertentu Anda dapat melakukan pembagian data tersebut menjadi halaman - halaman yang dapat mengefektifkan halaman tersebut. Agak kurang logis juga bila kita harus melihat sebuah data karyawan dengan jumlah sekitar 10.000 baris dalam suatu halaman. Selain respon halaman web menjadi lambat, juga tidak semua data kita perlukan.

Oleh karena itu dengan menggunakan suatu pagination kita dapat melihat banyaknya data dengan jumlah yang lebih kecil dan kita dapat berpindah ke halaman berikutnya untuk melihat data lainnya. Django sendiri sudah memiliki sebuah modul yang dapat digunakan untuk pagination. Sehingga Anda tidak perlu lagi memasang modul tambahan untuk melakukan hal tersebut.

Menambahkan kode pagination ke views daftar_izin

Sederhana saja, ketika Anda ingin menggunakan sebuah pagination di Django. Pastikan Anda sudah meng-import terlebih dahulu modul yang akan digunakan. Modul tersebut dapat di-import dengan kode seperti berikut:
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
Tambahkan kode diatas ke file kehadiran/views.py di bagian paling atas bersama kode import modul lainnya. Sekarang mari kita ubah views daftar_izin dengan penambahan kode yang berhubungan dengan pagination seperti berikut: ```python @login_required(login_url=settings.LOGIN_URL) def daftar_izin(request): daftar_izin = Izin.objects.filter(karyawan__id=request.session['karyawan_id']).order_by('-waktu_mulai')
paginator = Paginator(daftar_izin, 5)
page = request.GET.get('page')
try:
    daftar_izin = paginator.page(page)
except PageNotAnInteger:
    daftar_izin = paginator.page(1)
except EmptyPage:
    daftar_izin = paginator.page(paginator.num_pages)

return render(request, 'new/daftar_izin.html', {'daftar_izin':daftar_izin})

Pada kode diatas Anda melakukan <em>query</em> terlebih dahulu untuk mendapatkan semua daftar izin yang telah Anda buat. Kemudian kita mulai melakukan pemotongan data dengan menggunakan <em>class</em> <strong>Paginator</strong>. Kita lakukan <em>paging</em> terhadap hasil <em>query</em> yang disimpan pada variabel <strong>daftar_izin</strong> sebanyak 5 baris per halaman. Kemudian kita tangkap <em>query string</em> <strong>page</strong> jika ada di URL untuk menentukan ada di <em>page</em> keberapakah kita berada. Kemdian di dalam ekspresi <strong>try .. except ..</strong> kita akan mencoba untuk memotong data untuk ditampilkan di halaman yang diinginkan. Jika data tidak dapat ditampilkan pada halaman yang diminta, maka akan ditampilkan halaman pertama. Jika halaman pertama pun tidak ada maka akan ditampilkan halaman kosong.

Kemudian daftar izin yang dipotong pun akan ditampilkan di <em>template</em> <strong>new/daftar_izin.html</strong>. Di bagian berikutnya kita akan mengubah <em>file template</em> tersebut untuk dapat menampilkan <em>pagination</em>.
<h2>Membuat template tags untuk membantu proses pagination</h2>
Sebelum kita mengubah <em>template</em> <strong>kehadiran/new/daftar_izin.html</strong> agar dapat menampilkan <em>pagination</em>, kita akan membuat terlebih dahulu sebuah <em>template tags</em> yang akan diperlukan untuk membantu <em>pagination</em> kita lebih baik. <em>Template tags</em> ini dapat kita anggap juga sebagai sebuah <em>helper</em> saat kita hendak menampilkan informasi di <em>template</em> Django. Karena tidak semua <em>template tags</em> disediakan oleh Django, sehingga kita harus menyediakannya sendiri bila sangat membutuhkan suatu operasi terhadap <em>string</em> yang akan diproses.

Pertama, silahkan buat sebuah <em>folder</em> dengan nama <strong>templatetags</strong> di dalam <em>folder</em> <strong>kehadiran</strong>, kemudian di dalam <strong>kehadiran/templatetags</strong> bersi sebuah <em>file</em> kosong dengan nama
```python
__init__.py

Kemudian buat juga sebuah file yang bernama kehadiran_helper.py di dalam folder templatetags tersebut. Lalu buatlah kode berikut di dalam kehadiran_helper.py

from django import template register = template.Library() ROW_PER_PAGE = 5 @register.filter def get_table_number(value, arg): return value + ( (arg - 1) * ROW_PER_PAGE)

Pada kode diatas kita memanggil modul template dari Django, kemudian membuat sebuah variabel yang berisi sebuah objek template.Library(). Kemudian kita panggil decorator @register.filter untuk menandai function get_table_number sebagai function yang dapat dipanggil di suatu template. Di dalam function tersebut terdapat sebuah rumus yang akan menghitung penomoran di setiap halaman yang telah di beri pagination. Parameter value adalah baris data yang akan diproses, kemudian arg adalah halaman dimana Anda berada saat ini. Anda dapat melihat contoh perhitungan berikut:

#jangan disalin, hanya contoh perhitungan value = 1 arg = 2 nomor_baru = 1 + ( (2 - 1) * 5 ) maka nomor_baru adalah 6 value = 3 arg = 1 nomor_baru = 3 + ( (1 - 1) * 5 ) maka nomor_baru adalah 3 value = 3 arg = 4 nomor_baru = 3 + ( (3 - 1) * 5 ) maka nomor_baru adalah 13

Mengubah template daftar_izin.html

Sekarang saatnya kita ubah template kehadiran/new/daftar_izin.html. Pertama kita harus menyertakan lebih dahulu templatetags yang ada di file kehadiran_helper.py. Ubah kode di bagian atas file daftar_izin.html menjadi seperti berikut: ```python {% extends "layout/base.html" %} {% load kehadiran_helper %} {% block content %}

Daftar Izin


Lalu kita ubah juga kode HTML yang ada di dalam <strong>div</strong> dengan <em>class</em> <strong>panel-body</strong> menjadi seperti berikut:
```python

<div class="panel-body">
    <div class="row">
        <div class="col-lg-12">
            <div class="table-responsive">
                <table class="table table-bordered table-hover table-striped">
                    <thead>
                        <tr>
                            <th>#</th>
                            <td>Jenis Izin</td>
                            <td>Waktu Mulai</td>
                            <td>Waktu Berhenti</td>
                            <td>Alasan</td>
                            <td>Disetujui</td>
                        </tr>
                    </thead>
                    <tbody>
                        {% for izin in daftar_izin %}
                        <tr>
                            <td>{{ forloop.counter|get_table_number:daftar_izin.number }}</td>
                            <td>{{ izin.jenis_kehadiran }}</td>
                            <td>{{ izin.waktu_mulai }}</td>
                            <td>{{ izin.waktu_berhenti }}</td>
                            <td>{{ izin.alasan }}</td>
                            <td>
                                {% if izin.disetujui %}
                                <span class="label label-success">Sudah</span>
                                {% else %}
                                <span class="label label-danger">Belum</span>
                                {% endif %}
                            </td>
                        </tr>
                        {% endfor %}
                    </tbody>
                </table>
            </div>
            <!-- /.table-responsive -->

            <ul class="pager">
                {% if daftar_izin.has_previous %}
                <li class="previous">
                    <a href="?page={{ daftar_izin.previous_page_number }}">previous</a>
                </li>
                {% endif %}

                <li class="current">
                    Page {{ daftar_izin.number }} of {{ daftar_izin.paginator.num_pages }}.
                </li>

                {% if daftar_izin.has_next %}
                <li class="next">
                    <a href="?page={{ daftar_izin.next_page_number }}">next</a>
                </li>
                {% endif %}
            </ul>
        </div>
        <!-- /.col-lg-4 (nested) -->
    </div>
    <!-- /.row -->
</div>

Pada kode diatas, kita gunakan templatetags get_table_number() pada saat mengeluarkan nomor baris data di tabel, kemudian kita juga membuat sebuah elemen unordered list dengan class pager yang berisi tombol - tombol untuk menampilkan navigasi pindah halaman. Didalam elemen tersebut terdapat kondisi untuk menampilkan tombol previous dan tombol next.

Sekarang mari kita lihat hasil penambahan pagination di halaman daftar izin:

Halaman awal setelah di beri pagination
Halaman akhir setelah di pagination

Penutup

Dengan menggunakan pagination Anda dapat dengan cermat menampilkan baris data tanpa harus menampilkan semuanya. Hal ini dapat membuat user lebih nyaman untuk melihat data. Karena selain tidak perlu melihat data semuanya dalam sekali waktu, user pun tidak akan menunggu lama karena harus melakukan penampilan semua data pada suatu halaman. Di tutorial berikutnya, Anda akan mengenal cara membuat sebuah laporan kehadiran dengan tipe file PDF di Django.

(rfs/djangoproject)