7 days of WordPress plugins, themes & templates - for free!* Unlimited asset downloads! Start 7-Day Free Trial
Advertisement
  1. Code
  2. Python

Pengenalan Flask: Menambahkan Halaman Kontak

Scroll to top
Read Time: 19 mins

Indonesian (Bahasa Indonesia) translation by Aditia Dwiperdana (you can also view the original English article)

Pada artikel sebelumnya di mini seri ini, kita menggunakan Flask untuk membuat website yang berisi halaman "Home" dan "About" menggunakan alur kerja yang umum yang bisa kita aplikasikan ke aplikasi web berbasis Flask. Pada tutorial ini saya akan menunjukkan bagaimana cara menambahkan halaman "Contact" yang membuat user bisa mengirim kamu pesan.

Kode yang digunakan pada artikel ini bisa didapatkan di GitHub. Caption, seperti Checkpoint: 05_contact_form, berarti kamu bisa berpindah ke branch bernama "05_contact_form" dan mereview kode pada bagian yang bersangkutan di artikel ini.


Ekstensi Flask

Kamu bisa melihat daftar ekstensi di Flask Extension Registry.

Flask tidak datang dengan banyak fitur di awal, membuatnya mudah digunakan dan dipelajari. Tidak ada pemetaan objek untuk interaksi database atau antarmuka admin untuk menambahkan dan memperbarui konten. Flask hanya menyediakan set kecil fungsi, dua di antaranya sudah kita gunakan, url_for() dan render_template().

Ekstensi Flask membuat kamu bisa menambahkan fungsi sesuai kebutuhan, tidak dimasukkan dari awal. Sebuah ekstensi Flask adalah paket yang menambahkan fungsi tertentu pada aplikasimu. Contohnya, Flask-SQLAlchemy menambahkan dukungan database ke aplikasimu, sedangkan Flask-Login menambahkan dukungan login/logout. Kamu bisa menemukan daftar lengkap ekstensi di Flask Extension Registry.

Untuk membuat halaman Contact, kita gunakan Flask-WTF untuk menangani dan memeriksa data form dan Flask-Mail untuk mengirim email berisi data form.


Flask-WTF

Flask-WTF adalah eksteksi yang menangani dan mamvalidasi data form. Apakah artinya? Lihat diagram berikut:

Gambar 1

  1. Seorang user mengirim request GET untuk halaman web yang berisi form.
  2. User mengisi form.
  3. User menekan tombol "Send", mengirimnya ke server menggunakan request POST.
  4. Server memvalidasi informasi.
  5. Jika satu atau lebih kolom tidak sah, halaman web berisi form akan terbuka kembali dengan pesan error, meminta user untuk mencoba kembali.
  6. Jika semua isian sah, informasi dari form akan digunakan di langkah berikutnya pada pipeline.

Sebuah halaman kontak akan memiliki kotak isian untuk nama user, email, subjek, dan pesan. Dalam Flask, kita akan POST data pada form ke fungsi di dalam routes.py. Fungsi ini disebut form handler. Kita akan jalankan beberapa validasi, dan jika salah satu input tidak sesuai, kita akan refresh halaman untuk menampilkan pesan yang menjelaskan kesalahannya. Begitu semua validasi lolos, kita akan gunakan data form untuk langkah berikutnya: mengemail pesan padamu, pemilik website.

Ekstensi Flask itu alat yang sederhana namun kuat yang menambahkan fungsionalitas untuk aplikasi berbasis Flask.

Itu adalah bagaimana form handling dan validasi bekerja. Di mana kita mendefinisikan form tersebut? Kita bisa menulis HTML menggunakan elemen <form> dan mengatur atribut action ke skrip Python. Skrip Python tersebut akan menyalin form untuk menangkap setiap kotak isian dan memvalidasi data isian. Jika kita menggunakan strategi ini, kita akan mendefinisikan form dua kali, sekali di front-end, dan sekali di back-end.

Akan lebih baik jika untuk mendefinisikan form hanya sekali: dalam skrip Python. Ini adalah fungsi utama dari Flask-WTF. Kita akan definisikan form sekali saja pada skrip Python, dan kita akan gunakan Flask-WTF untuk menghasilkan form HTML untuk kita. Tujuan semua ini adalah untuk memisahkan presentasi dari konten.

Cukup basa basinya. Mari menulis kode.

Membuat Form

Sebagai langkah pertama, kita kembali ke lingkungan pengembangan terisolasi yang kita buat sebelumnya.

Sekarang kita sudah masuk dan mengaktifasi lingkungan pengembangan kita, kita bisa install Flask-WTF dengan aman.

Sekarang kita definisikan form dalam skrip Python. Kita sudah memiliki routes.py, yang memetakan URL ke fungsi. Jangan kita kotori dengan kode yang tidak berhubungan. Kita buat file baru bernama forms.py, dan tempatkan di dalam folder app/.

app/forms.py

Kita sudah membuat form. Apa yang kita lakukan? Pertama, kita impor beberapa kelas yang berguna dari Flask-WTF. Kelas dasar Form, text field, textarea field untuk input teks yang lebih banyak, dan tombol submit. Lalu kitai buat kelas baru bernama ContactForm, menurunkan dari kelas dasar Form. Kita buat setiap isian yang ingin kita lihat dalam form kontak. Bukannya menulis <input type="text">Name</input> di file HTML, kamu menulis name = TextField("Name").

Menggunakan Form

Mari gunakan form kita. Kita ingin form tersebut muncul saat user mengunjungi halaman kontak. Dalam istilah Flask, kita ingin form muncul di web template dan memetakan URL ke web template tersebut agar kita bisa mengunjunginya di browser. Ini artinya kita perlu membuat sebuah web template dan pemetaan URL baru. Kita mulai dengan membuat pemetaan URL baru.

Ini adalah bagian penuh aksi, dan mungkin akan sedikit membingungkan. Tapi bertahanlan dan kita akan melewatinya.

Sebagai langkah pertama, buka routes.py dan impor form yang baru kita buat dengan menambahkan from forms import ContactForm pada awal skrip.

app/routes.py

Kamu bisa mencegah serangan CSRF dengan memastikan pengiriman form berasal dari aplikasi webmu.

Lalu, atur Flask-WTF untuk menangani celah keamanan yang dikenal sebagai cross-sire request forgery (CSRF). Di dunia yang ideal, servermu hanya menangani form milik aplikasi webmu. Dengan kata lain, server kamu hanya menangani dan memvalidasi form yang kamu buat. Tapi seorang penyerang bisa membuat form di websitenya, mengisinya dengan informasi berbahaya, dan mengirimnya ke server kita. Jika server menerima informasi berbahaya ini, banyak hal buruk yang bisa terjadi.

Kamu bisa mencegah serangan CSRF dengan memastikan form yang diterima berasal dari aplikasi web kita. Salah satu caranya adalah dengan menyimpan token rahasia di dalam tag HTML <form> yang tidak bisa ditebak oleh penyerang. Saat form tersebut diPOST ke server, token ini diperiksa terlebih dahulu. Jika token tidak cocok, server akan menolak form tersebut dan tidak menyentuh data dari form. Jika token cocok, server melanjutkan proses penanganan form dan validasinya.

Flask-WTF melakukan ini dengan satu baris kode. Cukup atur Flask-WTF dengan kunci rahasia, dan Flask-WTF akan menangani pembuatan dan pengelulaan token unik untuk form kita.

app/routes.py

Pada baris enam, saya atus kunci rahasia menjadi 'development key'. Ubahlah agar kunci milikmu lebih rumit, lebih panjang, dan menggunakan karakter alfanumerik.

Sekarang kita sudah mengimporo dan mengatur form kontak, kita bisa gunakan dalam pemetaan URL di routes.py. Mari lanjutkan dan buat pemetaan URL tersebut.

app/routes.py

Sekarang saat seseorang mengunjungi URL /contact, fungsi contact() akan dijalankan. Di dalam conctact(), kita buat sebuah instance form kontak di baris tiga dan mengirimnya ke web template bernama contact.html di baris empat. Segera akan kita buat web template ini.

Kita masih punya tugas untuk dikerjakan. Gambar 1 menunjukkan jika request GET dikirim ke server, halaman web berisi form akan diterima dan dibuka di browser. Jika server menerima request POST, sebuah fungsi perlu menangkap data dari form dan memeriksa apakah isinya sah. Dalam istilah Python, logika tersebut bisa digambarkan dengan pernyataan if...else. Terdapat kelas pada Flask untuk membedakan request GET dan POST, jadi kita mulai dengan mengimpor kelas tersebut di awal routes.py dan menambahkan logika if...else ke fungsi contact().

app/routes.py

Kita sudah mengimpor kelas Flask dan render_template() di artikel sebelumnya, jadi kita impor satu kelas Flask bernama request. request menentukan apakah fungsi HTTP saat ini adalah GET atau POST. Berikutnya adalah logika if...else di dalam fungsi contact() pada baris 9-13.

Dalam kasus request POST, sebuah string yang menunjukkan bahwa form sudah dikirim akan dikembalikan.

String ini hanyalah sementara, kita akan ganti dengan kode di langkah terakhir di artikel ini. Jika request menggunakan GET, kita kembalikan web template contact.html yang berisi form.

Langkah berikutnya adalah membuat web template contact.html dan menyimpannya di dalam folder templates/.

app/templates/contact.html

Seperti home.html dan about.html, contact.html diturunkan dari layout.html dan mengisi blok 'content' dengan teks. Pertama kita tentukan di mana mengirim data form dengan mengatur atribut action dari elemen <form> menjadi fungsi contact() yang kita buat di routes.py (baris lima). Berikutnya, kita buat template engine Jinja2 membuat sebagian besar dari form untuk kita (baris 6-20). Kita mulai dengan memasukkan tag tersembunyi di baris enam untuk melindungi dari eksploit CSRF. Terakhir, kita tambahkan label dan kotak isian dalam form.

Sekarang kita sudah siap melihat hasil dari pekerjaan kita. Ketik perintah berikut:

Lalu buka http://localhost:5000/contact di web browser pilihanmu.

Halaman kontak berisi form sudah terbuka. Isi form isian dan klik tombol "Send". Kamu akan lihat halaman seperti ini:

Keren! Pengiriman form sudah bekerja.

Kita lihat lagi apa yang kita lakukan pada bagian ini:

  • Kita menulis http://localhost:5000/contact sebagai URL pada browser.
  • Request GET mengenai routes.py, di mana URL /contact dipetakan ke fungsi contact().
  • Fungsi contact() dijalankan, di mana variabel bernama form berisi instance dari kelas ContactForm dikirim ke web template contact.html.
  • contact.html membuat HTML form kontak.
  • HTML yang dirender dikirim balik ke routes.py.
  • routes.py mengirim balik HTML ke browser dan kita lihat halaman kontak yang berisi form.
  • Kita isi form kontak dan mengirimnya dengan menekan tombol "Send".
  • Request POST mengenai routes.py, di mana URL /contact dipetakan ke fungsi contact().
  • Fungsi contact() dijalankan sekali lagi, kali ini mengikuti kontrol flow if...else untuk request HTTP POST.
  • String 'Form posted.' dikirim balik ke browser, memberikan kita layar di atas.

— Checkpoint: 05_contact_form —

Sudah bagus, tapi form kontak terlihat jelek. Mari perbaiki dengan menambahkan CSS. Buka main.css dan tambahkan aturan-aturan berikut:

static/css/main.css

Kembali ke browser dan refresh http://localhost:5000/contact untuk melihat hasil dari CSS.

Ini terlihat lebih baik. Kita lanjutkan ke validasi form.

— Checkpoint: 06_contact_styling —

Memvalidasi Data Form

User sekarang bisa mengunjungi URL /contact dan mengisi form. Tapi apa yang terjadi jika user tidak mengisi form dengan benar? Kita perlu memvalidasi input user agar tidak menyebabkan masalah di langkah berikutnya.

Validasi form dilakukan dengan menggunakan form validator. Untungnya, Flask-WTF memiliki banyak validator bawaan yang bisa langsung kita gunakan. Kita simpan validator ini di definisi kelas ContactForm pada forms.py.

Validator paling dasar adalah presence, yang memastikan semua isian form diisi, jadi kita mulai di sini.

app/forms.py

Kita mulai dengan mengimpor validators dan ValidationError dari Flask-WTF. Ini memberi kita akses untuk validator bawaan Flask-WTF. Lalu kita tambahkan [validators.Required()] ke semua isian form untuk memvalidasi keberadaannya. Perhatikan validator ini berada di dalam list Python, artinya kita bisa dengan mudah menambahkan validator ke list ini.

Berikutnya, kita membutuhkan alamat email untuk mengikuti pola user@example.com dengan menambahkan validator Email ke isian email.

app/forms.py

Sekian untuk validasi form. 

— Checkpoint: 07_form_validations —

Pesan Error Berkelip

Melihat kembali Gambar 1, jika ada pengecekan validasi yang gagal, halaman kontak harus mereload dengan pesan error sehingga user bisa memperbaiki dan mencoba kembali. Pesan error ini hanya muncul saat validasi gagal dan menghilang saat kesalahannya sudah diperbaiki.

Langkah berikutnya adalah mengirim pesan error sementara ke user saat validasi gagal. Flask membuatnya mudah dengan menggunakan fungsi flash(). Kita mulai dengan membuka routes.py dan mengimpor fungsi flash() di awal skrip.

app/routes.py

Setelah form kontak diPOST ke server, kegagalan validasi harus mereload form dengan pesan error yang berguna. Dan data input bisa digunakan kembali untuk lain kali. Sekali lagi, logika ini bisa ditulis dalam pernyataan if...else. Mari tambahkan logika if...else ini ke fungsi contact() di dalam blok if request.method == 'POST':.

app/routes.py

Jika ada validasi yang gagal, form.validate() akan bernilai False. Pesan error All fields are required akan dikirim ke contact.html. Jika tidak, kita akan lihat string sementara Form posted, menunjukkan kalau form berhasil dikirim.

Lalu, kita ubah contact.html agar bisa menerima dan menampilkan pesan error sementara. Lihat blok berikut:

Fungsi get_flashed_messages() mengambil semua pesan berkelip dan mengembalikannya. Lalu kita tampilkan setiap pesan menggunakan loop for Jinja2. Tambahkan blok kode berikut pada contact.html setelah <h2>Contact</h2> sebelum tag <form>.

app/templates/contact.html

Terakhir, kita tambahkan aturan  CSS di main.css agar pesan error berkelip terlihat bagus.

main.css

Buka browser dan kunjungi http://localhost:5000/contact. Biarkan form kosong dan klik "Send" untuk menguji apakah validasi form dan pesan error bekerja.

Bagus! Kita sudah berhasil mengirim pesan error ke form kontak jika validasi gagal.

— Checkpoint: 08_error_message_flashing —

Tapi kita belum selesai; kita bisa memperbaikinya sedikit lagi. Daripada satu pesan error saat validasi gagal, lebih baik memiliki satu pesan error spesifik untuk masing-masing pengecekan validasi. Contohnya, jika user lupa mengisi isian subjek, pesan error yang berkata Please enter a subject akan ditampilkan. Begitu pula jika user lupa mengisi nama, kita tampilkan pesan error khusus yang berkata Please enter youe name. Kita bisa membuat ini dengan mudah, kita mulai dengan menulis pesan error di dalam masing-masing validator pada forms.py.

app/forms.py

Kita cukup tulis pesan error spesifik di dalam masing-masing validator. Lalu, kita modifikasi contact.html untuk menerima dan menampilkan pesan error khusus ini. Sebelumnya, kita mengandalkan fungsi get_flashed_messages() untuk mengambil pesan error, dan menampilkannya menggunakan loop. Kita ganti blok tersebut dengan blok ini:

Di sini, kita gunakan atribut errors untuk masing-masing isian dalam form untuk mengambil pesan error tertentu dan menggunakan loop for Jinja2 untuk menampilkannya.

Setelah digabung, contact.html akan terlihat seperti ini:

app/templates/contact.html

Kembali ke browser dan buka http://localhost:5000/contact dan klik "Send". Pastikan untuk mengosongkan semua kotak isian.

Sempurna! User sekarang mendapat pesan error yang berguna jika berbuat kesalahan.

— Checkpoint: 09_specific_message_flashing —

Kita menyelesaikan banyak pada bagian ini. Kita buat form kontak dari awal, belajar bagaimana melindungi dari serangan CSRF, membedakan request GET dan POST, membuat validasi form, dan menampilkan pesan error tertentu jika perlu. Sekarang kita perlu mengirim pesan dengan email.


Flask-Mail

Flask-Mail adalah ekstensi Flask yang membuat kamu bisa mengirim email dari aplikasi Flask. Langkah-langkah berikut mirip dengan langkah menggunakan Flask-WTF.

Kita mulai dengan menginstall Flask-Mail.

Pengaturan Flask-Mail

Berikutnya, kita impor Flask-Mail ke routes.py dan mengaturnya agar bisa kita gunakan.

app/routes.py

Pertama kita impor kelas Message dan Mail dari Flask-Mail (baris tiga). Kita gunakan kelas Message untuk membuat email baru dan kelas Mail untuk mengirim email tersebut. Lalu kita buat variabel mail yang berisi instance kelas Mail (baris lima).

Lalu kita atur Flask-Mail dengan beberapa pengaturan server SMTP (baris 11-15). Saya menggunakan pengaturan server SMTP Gmail, tapi kamu bisa menggunakan layanan email pilihanmu. Cari saja pengaturan SMTPnya dan kamu siap.

Contohnya, jika kamu ingin menggunakan Yahoo! Mail, cari "yahoo mail smtp server settings" dan perbarui konfigurasinya.

Pastikan untuk mengisi alamat email asli dan passwordnya pada app.config["MAIL_USERNAME"] dan app.config["MAIL_PASSWORD"]. Ini adalah akun yang akan digunakan untuk mengirim email.

Akhirnya, kita attach mail ke aplikasi Flask kita agar kita bisa menggunakannya (baris 17).

Kamu mungkin pernah melihat grup menggunakan alamat email seperti contact@example.com atau support@example.com. Jika kamu punya domain sendiri dan bisa membuat email kontak baru, silakan dan masukkan email tersebut di app.config["MAIL_USERNAME"]. Jika tidak, kamu bisa menggunakan email pribadi untuk menjalankannya.

Mengirim Email

Setelah pengaturan selesai, kita buat email baru berisi data form kontak dan mengirimnya. Kita hanya kirim email jika form berhasil dikirim dan lolos validasi. Ini artinya kita perlu bekerja di dalam blok if request.method == 'POST': lagi. Kita sudah memiliki logika di dalam if form.validate() == False: untuk menangani kegagalan validasi. Jika semua validasi lolos, form.validate() akan bernilai True dan program akan masuk blok else. Maka kita tambahkan logika di blok else:.

app/routes.py

Kita mulai dengan membuat pesan baru (baris 10). Kelas Message menerima subjek, alamat "from" dan alamat "to". Lalu kita kumpulkan data subjek dari form kontak dengan form.subject.data dan mengaturnya sebagai subjek pesan baru. Email akan dikirim dari akun yang diatur di app.config["MAIL_USERNAME"], jadi itulah yang kita gunakan dari sekarang sebagai alamat pengirim. Email akan dikirim ke email pribadi agar kamu bisa menerima dan merespon pesan baru.

Lalu kita tulis emailnya (baris 11-14). Kita masukkan nama user, email, dan pesannya. Saya gunakan operator format string % dari Python untuk memformat email. Akhirnya, kita gunakan mail.send(msg) untuk mengirim email (baris 15).

Kita lihat apakah semuanya bekerja dengan baik. Buka http://localhost:5000/contact, isi setiap kotak isian dan klik "Send". Jika semua lancar, kamu akan menerima email baru dari aplikasi Flask-mu.

— Checkpoint: 10_send_email —

Merapikan Kode

Langkah terakhir adalah menghapus string sementara 'Form posted.' dengan pesan memberi terima kasih pada user atas masukannya. Pesan ini hanya muncul jika aplikasi mengirim email. Sekali lagi, logika ini bisa dibuat dengan pernyataan if...else.

Saat form kontak berhasil dikirim, kita kitim penanda sukses dari routes.py ke contact.html.

Kita tempatkan logika if...else di dalam contact.html. Jika flag sukses diatur menjadi True, kita akan tampilkan pesan terima kasih. Jika tidak, kita tampilkan form kontak.

Kita mulai di routes.py di dalam fungsi contact(). Ganti baris sementara return 'Form posted.' dengan return render_template('contact.html', success=True) untuk mengirim flag sukses ke contact.html. Fungsi contact() sekarang terlihat seperti ini:

app/routes.py

Lalu buka contact.html dan tambahkan logika if...else. Kita gunakan sintaks if...else Jinja2 untuk ini.

app/templates/contact.html

Mulai dari baris enam, {% if success %} berarti jika flag sukses yang dikirim dari routes.py bernilai True, maka tampilkan <p>Thank you for your message. We'll get back to you shortly.</p>. Jika tidak, ikuti {% else %} dan tampilkan form kontak. Sintaks Jinja2 perlu kita menutup pernyataan if...else dengan {% endif %}, jadi kita tulis di bagian akhir (baris 45).

— Checkpoint: 11_success_message —

Akhirnya, kunjungi http://localhost:5000/contact sekali lagi. Isi semua kotak isian dan klik "Send".

Langkah terakhir adalah menambahkan navigasi ke halaman kontak. Pada artikel sebelumnya, kita tambahkan tautan berikut di layout.html di dalam elemen <header>. Kita lakukan juga untuk halaman kontak (baris delapan).

app/templates/layout.html

— Checkpoint: 12_contact_nav_link —

Buka browser dan buka http://localhost:5000/ untuk melihat tautan navigasi yang baru.


Kesimpulan

Pada artikel ni, kita menambahkan halaman kontak yang berisi form ke aplikasi Flask kita. Form muncul di beberapa tempat di aplikasi web, misalnya saat sign up dan login. Alur kerja ini bisa digunakan untuk memenuhi kebutuhan itu. Saat membuat halaman kontak, kita belajar bagaimana menggunakan ekstensi Flask.

Ekstensi Flask adalah perangkat mudah namun kuat yang mengembangkan fungionalitas aplikasi bebasis Flask.

Buka Flask Extension Registry untuk melihat lebih banyak ekstensi yang bisa kamu integrasi ke aplikasimu.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.