Django Forms วิธีใช้งาน

   By: Withoutcoffee Icantbedev

   อัปเดตล่าสุด Dec. 12, 2023

Django Forms วิธีใช้งาน

Forms ถือว่าเป็นอีกหนึ่งส่วนที่มีความจำเป็นในด้าน web development  เว็บไซต์สำเร็จรูปโดยส่วนใหญ่แล้วเช่น WordPress, Wix, etc ก็จะมีการฟีเจอร์ form แต่จะดีกว่าแน่ ๆ ถ้าเรารู้เบื้องลึก เบื้องหลังการทำงานของ form บทความนี้จะมาเรียนรู้การสร้าง form ให้กับ Django โปรเจคท์ของเรากันครับ


Forms Fundamentals

Form คือส่วนที่ผู้ใช้กรอก input เข้ามา โดยปกติแล้วที่เราเห็นได้บ่อย ๆ ก็คือในหน้า contact การจัดการกับฟอร์มนับว่าเป็นส่วนที่มีความซับซ้อน และต้องคำนึงถึงความปลอดภัยด้วยเช่นกัน เพราะไม่ว่าอะไรก็ตามที่มีการรับค่า input จาก user นั้นให้เราคิดไว้ก่อนเสมอว่ามันไม่ปลอดภัย ดังนั้นจึงต้องมีการทำ Form Validation

แต่ Django ก็มีการจัดการเกี่ยวกับความปลอยภัยของ form ให้เสร็จสรรพ ช่วยให้การทำงานกับ form ง่ายและสะดวกขึ้นมาก โดยมีโดยที่มีชื่อว่า   django.forms 


GET & POST Methods

Form จะมี HTTP methods 2 ตัวที่สำคัญ ๆ คือ GET และ POST โดย 2 ส่วนนี้ใช้ตอนไหน เรามาดูกันครับ

  • GET: ใช้สำหรับ request ที่ไม่มี effect กับฐานข้อมูล เช่น การดึงข้อมูลมาแสดงผล
  • POST: ใช้ในกรณีที่มีการ  request นั้นมีการ effect กับฐานข้อมูล เช่น การเพิ่มข้อมูล (กรอกฟอร์ม) เป็นต้น


1. สร้าง form ใน Django Model

ตอนนี้เรากำลังสร้างฟอร์ม แน่นอนว่าต้องมีการเก็บข้อมูล ดังนั้นต้องสร้างตารางหรือใน Django จะเรียกว่า model ขึ้นมา 1 ตารางชื่อว่า  Contact 

# blog/models.py
from django.db import models

class Contact(models.Model):
    subject = models.CharField(max_length=120)
    sender = models.CharField(max_length=80)
    email = models.EmailField()
    detail = models.TextField()
    date_sent = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.subject


2. ทำการ migrate ตาราง Contact

เมื่อได้ตาราง Contact แล้ว จากนั้นก็ทำการ makemigrations และ migrate เพื่ออัปเดตเข้าไปในฐานข้อมูลของเราครับ

$ python manage.py makemigrations


จากนั้น Migrate ได้เลย

$ python manage.py migrate


สร้างไฟล์ forms.py  forms.py ใน blog ขึ้นมาใหม่

blog/
    templates/...
    admin.py
    forms.py # New
    models.py
    urls.py
    views.py
    ...


จากนั้นทำการอิมพอร์ต   Contact   โมเดลเข้ามาใช้งานพร้อมกับสร้างคลาสที่มีชื่อว่า   ContactForm  

# blog/forms.py
from django import forms 
from .models import Contact  

class ContactForm(forms.ModelForm):
    class Meta: 
        model = Contact 
        fields = [
            'subject', 
            'sender', 
            'email', 
            'detail'
        ]

ข้างในทำการสร้างคลาส  meta   ขึ้นมาอีกหนึ่งคลาส เพื่อกำหนดข้อมูลที่จะใช้ในฟอร์มว่ามีอะไรบ้าง โดยมี 2 ส่วนที่จำเป็นคือ

  •   model   : โมเดลที่จะใช้ในการสร้าง form ในที่นี้คือ   Contact 
  •  fields   :  คือฟีลด์ที่จะใช้แสดงผลรับ input เข้ามาจากฝั่งหน้าเว็บเพื่อให้ user กรอกฟอร์มเข้ามา


จากนั้นไปที่   views.py  เพื่อ render template และจัดการกับ form ที่จะนำไปแสดงผลและจัดการกับ input ที่ user ได้กรอกแบบฟอร์มเข้ามา โดยกำหนดฟังก์ชันที่มีชื่อว่า   contact     ในฟังก์ชันนี้ก็จะมีการเขียนเพื่อทดสอบ request ที่เข้ามาว่าเป็น GET หรือ POST ถ้าเข้าเงื่อนไข if ก็จะเป็นกระบวนการรับค่าที่ user ได้กรอกฟอร์มเข้ามา โดยแน่นอนว่าการที่ user กด submit ฟอร์มเข้ามาก็จะเป็น POST


ถ้า user ยังไม่ได้กรอกแบบฟอร์มล่ะ ? แน่นอนว่าก็จะเข้าเงื่อนไขนี้ และ request ที่ถูกส่งเข้ามาก็จะเป็น GET คือยังไม่ได้กรอกแบบฟอร์ม ยังไม่ได้กด submit โดยทำการแสดงผลหน้าฟอร์มเปล่า ๆ ก่อนในตอนนี้

    else:
        # If method is GET
        form = ContactForm()


เมื่อเข้าเงื่อนไขของเมธอด GET จะเป็นการแสดงหน้า form เปล่า ๆ

ตัวอย่างหน้า form


และนี่คือขั้นตอนต่อมาเมื่อหน้าฟอร์มได้ถูกแสดงผลแล้ว โดยต่อไปนี้เป็นการเช็ค user กรอกฟอร์มและกด submit เข้ามา ก็จะนำ action เหล่านี้มาเข้าเงื่อนไข POST

    # Check the incoming request
    if request.method == "POST":


จากนั้นกำหนดตัวแปร   ขึ้นมาเพื่อเรียกใช้ Class    ContactForm()   โดยในคลาสนี้จะทำการ map   request.POST เข้ามาด้วยเพราะมีการส่ง POST มาจากที่ user กด submit ฟอร์ท จากนั้นก็จะเช็คว่า form ที่ผู้ใช้กรอกเข้ามานั้นถูกต้องหรือไม่ ด้วยเมธอด    is_valid()    ถ้าถูกต้องก็ทำการบันทึกฟอร์มลง database ด้วยเมธอด  save() 

        form = ContactForm(request.POST)
        if form.is_valid():
            # Save to DB
            form.save()
            return redirect("/")

เมื่อบันทึกเสร็จสิ้นแล้วก็ให้ redirect ไปที่หน้า home ด้วยเมธอด   redirect()   เพื่อบอก user ว่าคุณได้กรอกฟอร์มเสร็จเรียบร้อยแล้วนะ เพราะถ้าไม่ redirect ไปหน้าอื่น user จะไม่รู้ว่าฟอร์มที่กรอกสำเร็จแล้วหรือยัง จะทำให้เป็นการสร้างประสบการณ์ใช้งานที่ไม่ดีต่อผู้ใช้ (bad user experience) ดังนั้นการ redirect ออกไปหน้าอื่นที่เหมาะสมก็ถือว่าเป็นสิ่งที่ควรทำ


สุดท้ายก็ render หน้าเว็บออกไปแสดงผล

    return render(request, 'blog/contact.html', {'form': form})


forms.py final code

# blog/views.py
from django.shortcuts import render
from .forms import ContactForm

def contact(request):
    # Check the incoming request
    if request.method == "POST":
        form = ContactForm(request.POST)
        if form.is_valid():
            # Save to DB
            form.save()
            return redirect("/") # Redirect to home
    else:
        form = ContactForm()
    return render(request, 'blog/contact.html', {'form': form})


สร้างไฟล์ที่มีชื่อว่า   contact.html  ขึ้นมาเพื่อแสดงหน้าแบบฟอร์ม โดยปกติแล้วแท็ก form ของ HTML จะสังเกตได้ง่าย ๆ เลยคือจะมีแท็ก    <form>...</form>  ถ้าเห็นแท็กนี้ชัดเจนเลยว่าส่วนนี้คือฟอร์ม ภายใน   จะมีแอตทริบิวต์ที่จำเป็นอยู่ 2 ตัวก็คือ

  •   action : คือ URL ปลายทางที่จะที่ฟอร์มจะวิ่งเข้าเจอหลังจากกด submit
  •   method : คือ เมธอดของฟอร์มที่เราจะส่งไป (แน่นอนว่าการส่ง form ต้องใช้ POST)

<!-- contact.html -->
{% extends 'blog/base.html' %}
{% block title %}Contact us{% endblock %}

{% block content %}
  <div class="container"><br>
    <div class="col-sm-8">
      <h1>Contact us</h1>
      <form action="/contact" method="POST">
          {% csrf_token %}
          {{ form.as_p }}
          <input class="btn btn-primary" type="submit" value="Submit">
      </form>
    </div>
  </div>
{% endblock content %}


จะเห็นว่าด้านบนภายในแท็ก <form> เราไม่ได้เขียน elements ของฟอร์มของแต่ละ input ขึ้นมา โดย elements เหล่านั้นไม่ว่าจะเป็น subject, sender, email และ detail จะถูก render มาจากฝั่ง back-end จะมีเพียงแค่ปุ่ม Submit เท่านั้นที่เราต้องเขียนขึ้นมาเอง

โดยเราจะใช้   {{ form.as_p }}   เพื่อแสดงผล input ต่าง ๆ ของฟอร์มให้เราเสร็จสรรพ

<form...>
    {{ form.as_p }}
</form>


จะได้หน้า Contact us แบบนี้



เพียงเท่านี้ก็จะได้หน้าฟอร์มพร้อมใช้งานแล้ว แต่ถ้าสังเกตให้ดีจะเห็นว่าหน้าตาของฟอร์มดูไม่ได้เอาเสียเลย


3. Form Widgets

ดังนั้น เราจะมาปรับอีกสักหน่อยครับ เพื่อให้หน้า form ดูมืออาชีพหรือสวยงามน่าใช้มากกว่านี้ โดยเราสามารถเพิ่มตัวแปร  widgets   ซึ่งเป็นตัวแปรของโมดูล  forms ของ Django โดยในตัวแปรนี้เราสามารถ custom Bootstrap คลาสได้เลย

# blog/forms.py
...
class ContactForm(forms.ModelForm):
    class Meta: 
        model = Contact 
        fields = [
            'subject', 
            'sender', 
            'email', 
            'detail'
        ]
        
        # New
        widgets = {
            'subject': forms.TextInput(attrs={
                'class': 'form-control col-xl-8'
            }),
            'email': forms.EmailInput(attrs={
                'class': 'form-control col-xl-8'
            }),
            'sender': forms.TextInput(attrs={
                'class': 'form-control col-xl-8'
            }),
            'detail': forms.Textarea(attrs={
                'class': 'form-control col-xl-8'
            })
        }
...


รีเฟรชหน้า Contact us จะได้ฟอร์มที่ดูสวยงาม น่าใช้เรียบร้อย


จบลงไปแล้วกับบทความ Django Forms หวังว่าคงจะเป็นประโยชน์นะครับ อย่าลืมติดตามเพจ devhub ด้วยนะครับ

หรือถ้าสนใจเรียน Django แบบ Private เป็นส่วนตัวกับผู้เขียน ตั้งแต่เริ่มต้นจนทำโปรเจคท์ได้จริง ได้หลักการที่ถูกต้อง พร้อมการซัพพอร์ต ก็สามารถดูรายละเอียด Django Course นี้ได้เลยครับ


เปิดโลกการเขียนโปรแกรมและ Software Development ด้วย online courses ที่จะพาคุณอัพสกิลและพัฒนาสู่การเป็นมืออาชีพ เรียนออนไลน์ เรียนจากที่ไหนก็ได้ พร้อมซัพพอร์ตหลังเรียน

คอร์สเรียนเขียนโปรแกรม