Membangun Aplikasi Mini HRD dengan Django (8 - END): Menambahkan Fitur Ubah Pas Foto

Ridwan Fajar 29 Juni 2016

Membangun Aplikasi Mini HRD dengan Django (8 - END): Menambahkan Fitur Ubah Pas Foto

Tak lengkap rasanya bila membuat sebuah aplikasi yang berhubungan dengan sebuah profil tidak dilengkapi dengan fitur ganti foto. Karyawan memerlukan fitur ganti foto untuk mengekspresikan dirinya melalui foto resmi ataupun foto santai agar lebih percaya diri ketika orang lain melihat profilnya. Kali ini kita akan membuat sebuah fitur untuk mengganti pas foto yang terdapat di halaman profil karyawan. Sehingga karyawan akan lebih leluasa untuk mengganti fotonya bila foto yang digunakan sebelumnya kurang kece.

Untuk itu mari kita ikuti tutorial terakhir dari seri membuat aplikasi mini HRD dengan Django ini.

Pengaturan upload file di Django

Sebelum memulai coding, kita harus mengatur terlebih dahulu path yang akan digunakan untuk menyimpan foto yang sudah di-upload. Buatlah sebuah folder bernama upload di dalam folder assets. Kemudian tambahkan konfigurasi berikut di mini_hrd/settings.py:
MEDIA_URL = '/media/'

MEDIA_ROOT = os.path.join(BASE_DIR,"assets/")

Pengaturan diatas akan digunakan untuk mengakses file foto melalui URL "/media/". Kemudian pengaturan diatas menunjukkan bahwa folder upload berada di folder assets. Sekarang silahkan tambahkan MEDIA_URL ke urlpatterns yang adai di file mini_hrd/urls.py:

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^$', karyawan_views.profil),
    url(r'^ganti_foto/', karyawan_views.ganti_foto),
    url(r'^login/', homepage_views.login_view),
    url(r'^logout/', homepage_views.logout_view),
    url(r'^daftar_hadir/$', kehadiran_views.daftar_hadir),
    url(r'^pengajuan_izin/', kehadiran_views.pengajuan_izin),
    url(r'^daftar_izin/', kehadiran_views.daftar_izin),
    url(r'^daftar_hadir/grafik/(?P\d+)/(?P\d+)$', kehadiran_views.tampil_grafik),
    url(r'^daftar_hadir/cetak/(?P\d+)/(?P\d+)$', kehadiran_views.cetak_daftar_hadir),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Kita tambahkan URL yang dihasilkan otomatis oleh Django untuk media yang akan di-upload. Anda tidak perlu membuat URL sendiri untuk mengakses file yang telah di-upload.

Mengubah models Karyawan

Setelah selesai menambahkan konfigurasi URL dan direktori di settings.py. Sekarang kita harus menambahkan sebuah field yang akan menangani masalah upload. Kita namai field tersebut bernama foto dengan tipe field ImageField. Tambahkan field tersebut di model Karyawan seperti pada source code berikut:
..............................................

class Karyawan (models.Model): JENIS_KELAMIN_CHOICES = ( ('pria', 'Pria'), ('wanita', 'Wanita'), )

JENIS_KARYAWAN_CHOICES = (
    ('magang', 'Magang'),
    ('kontrak', 'Kontrak'),
    ('tetap', 'Tetap'),
)

nama = models.CharField(max_length=100)
alamat = models.TextField(blank=True)
jenis_kelamin = models.CharField(max_length=10, choices=JENIS_KELAMIN_CHOICES)
jenis_karyawan = models.CharField(max_length=10, choices=JENIS_KARYAWAN_CHOICES)
no_telepon = models.CharField(max_length=30, blank=True)
email = models.CharField(max_length=100, blank=True)
no_rekening = models.CharField(max_length=100)
pemilik_rekening = models.CharField(max_length=100)
divisi = models.ForeignKey(Divisi)
jabatan = models.ForeignKey(Jabatan)
foto = models.ImageField(upload_to=os.path.join(settings.MEDIA_ROOT,"upload"), blank=True)

def __unicode__(self):
    return self.nama

..............................................

Field foto merupakan sebuah ImageField. Anda harus menentukan kemana file foto tersebut akan di-upload. Dalam tutorial ini, kita akan menggunakan folder assets/upload untuk menempatkan foto yang sudah di-upload. Selain itu, kita buat field tersebut agar dapat dikosongkan. Barangkali ada karyawan yang tidak ingin kegantengannya terekspos kepada karyawan lain.

Bila sudah yakin tidak ada yang salah dengan penambahan field tersebut, sekarang mari kita migrasikan database agar field foto bertambah. Jalankan perintah seperti pada potongan output berikut:

$ python manage.py makemigrations
Migrations for 'karyawan':
  0002_karyawan_foto.py:
    - Add field foto to karyawan
$ python manage.py migrate
Operations to perform:
  Apply all migrations: kehadiran, sessions, admin, karyawan, contenttypes, auth
Running migrations:
  Rendering model states... DONE
  Applying karyawan.0002_karyawan_foto... OK

Sekarang Anda dapat melihat halaman admin Django untuk melihat perubahan database tersebut seperti pada gambar berikut:

Field foto berhasil ditambahkan ke model Karyawan

Mengubah template profil.html

Selain mengubah model dan views, kita harus sedikit berkeringat untuk mengubah template karyawan/new/profil.html untuk menyesuaikan dengan proses ganti foto. Rencananya, kita akan tambahkan sebuah tombol "Ganti Foto" ketika pointer mouse sedang berada diatas foto kemudian tombol tersebut hilang secara fade out ketika pointer tidak diatas foto. Sekarang mari kita tambahkan sebuah button yang dibungkus di dalam div bersama img yang menampilkan foto profil karyawan. Silahkan ubah bagian foto menjadi seperti berikut (tanda titik - titik di dalam tag table menandakan bahwa ada kode yang tidak ditampilkan, jadi jangan diedit): ```python
                    <div class="panel-heading">
                        <i class="fa fa-bar-chart-o fa-fw"></i> Hi, {{ request.session.username }}
                    </div>
                    <!-- /.panel-heading -->
                    <div class="panel-body">
                        <div class="row">
                            <div class="col-lg-12">
                                <div id="foto-karyawan" style="width:200px; height:200px;  margin-bottom:50px;margin-top:20px; margin-left: auto; margin-right: auto;overflow-y:hidden;">
                                    <img src="/media/upload/{{ karyawan.foto|get_filename }}" style="width:200px; "/>
                                    <button id="ganti-foto-button" class="btn btn-primary btn-xm" style="position:absolute;top:23px;margin-left:3px;display:none;" data-toggle="modal" data-target="#gantiFotoModal"><i class="fa fa-photo"></i> Ganti</button>
                                </div>

                                <div class="table-responsive">
                                    <table class="table table-bordered table-hover table-striped">
                                        .....
                                    </table>
                                </div>
                                <!-- /.table-responsive -->
                            </div>
                            <!-- /.col-lg-4 (nested) -->
                        </div>
                        <!-- /.row -->
                    </div>
                    <!-- /.panel-body -->
Sekarang tambahkan juga <em>modal</em> yang akan muncul ketika kita tekan tombol "Ganti". Modal tersebut dapat Anda simpan di luar <strong>div</strong> dengan <em>class</em> <strong>row</strong>. <em>Field</em> hanya mempunyai satu <em>field</em> saja yang berupa tipe <em>input</em>, kemudian ada tombol "Upload" di bagian paling bawah <em>modal</em>. Modal tersebut mempunyai <em>id</em> dengan <strong>gantiFotoModal</strong> yang merupakan penunjuk bagi tombol "Ganti". Kemudian jika <em>user</em> menekan tombol <em>upload</em> maka halaman akan diarahkan ke URL "/ganti_foto/". Silahkan tambahkan modal berikut diluar <strong>div</strong> dengan <em>class</em> <strong>row</strong>:
```python

            <!-- /.row -->
            <div class="row">
                <div class="col-lg-12">
                    ......
                </div>
                <!-- /.col-lg-8 -->
            </div>
            <!-- /.row -->

            <!-- Modal -->
            <div class="modal fade" id="gantiFotoModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
                <div class="modal-dialog">
                    <form action="/ganti_foto/" method="POST" enctype="multipart/form-data">
                        {% csrf_token %}
                        <div class="modal-content">
                            <div class="modal-header">
                                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
                                <h4 class="modal-title" id="myModalLabel">Ganti Foto</h4>
                            </div>
                            <div class="modal-body">
                                <p>Pilih foto yang Anda sukai..</p>
                                <input type="file" name="files" />
                            </div>
                            <div class="modal-footer">
                                <button type="button" class="btn btn-default" data-dismiss="modal">Batal</button>
                                <input type="submit" class="btn btn-primary" value="Upload" />
                            </div>
                        </div>
                    </form>
                    <!-- /.modal-content -->
                </div>
                <!-- /.modal-dialog -->
            </div>
            <!-- /.modal -->
{% endblock %}

Karena kita ingin membuat tombol "Ganti" dapat menghilang ketika foto sedang tidak disorot, maka kita harus tambahkan sedikit Javascript untuk melakukan aksi tersebut. Kita gunakan function mouseover dan mouseleave untuk menampilkan dan menyembunyikan tombol. Karena kita sudah membuat sebuah blok yang bernama inline_js saat melakukan templating di tutorial sebelumnya, sekarang silahkan letakan blok inline_js dibagian bawah file setelah blok content. Kemudian tambahkan source code berikut (ingat jangan letakkan blok inline_js di dalam blok content):

{% block inline_js %} <script type="text/javascript"> $(window).load(function(){ $('#foto-karyawan').mouseover(function(){ $('#ganti-foto-button').css('display', 'block'); }).mouseleave(function(){ $('#ganti-foto-button').fadeOut(); }); }); </script> {% endblock %}

Sekarang mari kita melangkah ke bagian tutorial berikutnya.

Menambahkan views untuk upload file

Sekarang saatnya kita membuat views untuk menampilkan template yang telah kita ubah sebelumnya. Sekarang tambahkan views ganti_foto di file karyawan/views.py: ```python

@login_required(login_url=settings.LOGIN_URL) def ganti_foto(request): karyawan = Karyawan.objects.get(id=request.session['karyawan_id']) karyawan.foto = request.FILES['files'] karyawan.save()

return redirect('/')

Pada kode diatas, seperti biasa kita bentengi <strong>ganti_foto</strong> dengan <em>decorator</em> <strong>login_required</strong> kemudian di dalamnya kita ambil dulu objek atau <em>rows</em> karyawan yang <em>login</em> dari tabel Karyawan. Kemudian kita ubah isi <strong>Karyawan.foto</strong> dengan <em>file</em> yang kita <em>upload</em>. <em>File</em> yang di-<em>upload</em> akan tersimpan ke dalam memori yang dapat diakses melalui <strong>request.FILES</strong>. Kemudian akses nama <em>field</em>-nya, dan di tutorial ini <em>field</em> dari <em>file</em> yang di-<em>upload</em> bernama <strong>files</strong>. Sesuai dengan nama input <em>files</em> yang ada di <em>form</em>. Setelah itu barulah kita simpan perubahannya dengan memanggil <em>method</em> <strong>save()</strong>. Dan kita alihkan halaman ke halaman "/" (<em>root</em> atau utama).

Tapi sebelum dieksekusi, kita harus mendefinisikannya terlebih dahulu di <strong>mini_hrd/urls.py</strong>. Tambahkan URL berikut di <strong>urls.py</strong>:
<pre><code>url(r'^ganti_foto/', karyawan_views.ganti_foto),
</code></pre>
Sekarang mari kita lihat hasilnya seperti pada gambar berikut:

<img src="https://dl.dropboxusercontent.com/u/54840757/picture/codepolitan/minihrd-upload-file.gif" alt="upload foto django" />
<h2>Penutup</h2>
Akhirnya sampai juga di seri terakhir tutorial Django dengan contoh kasus membuat sub modul aplikasi kepegawaian yaitu mencatat kehadiran karyawan. Memang belum semua dapat disampaikan dengan benar dan lengkap tapi diharapkan dengan adanya tutorial django berseri ini dapat memberi gambaran secara umum bagaimana membuat aplikasi <em>web</em> dengan Django. Setelah menyelesaikan tutorial berseri ini diharapkan Anda sudah mengetahui beberapa hal berikut:
<ul>
 	<li>cara mengunduh dan menggunakan Django di <em>local machine</em></li>
 	<li>memahami <em>model</em>, <em>views</em>, dan <em>template</em> di Django</li>
 	<li>memahami cara kerja halaman Django Admin</li>
 	<li>mengetahui cara migrasi <em>database</em> dan membuat <em>form</em> Django</li>
 	<li>mengetahui cara <em>templating</em> halaman <em>web</em> dan cara memasang <em>template web</em></li>
 	<li>mengetahui cara autentikasi sederhana di Django</li>
 	<li>mengenal bagaimana cara membuat grafik, <em>pagination</em>, dan menghasilkan <em>file</em> PDF di Django</li>
 	<li>mengetahui cara <em>upload</em> file di Django</li>
</ul>
Semoga bermanfaat, sampai jumpa di tutorial berseri berikutnya.

(rfs/djangoproject)