แผนการเรียนรู้
/

Forms and CRUD: จัดการข้อมูลผู้ใช้

สร้าง Form รับข้อมูลจากผู้ใช้ และจัดการข้อมูลในฐานข้อมูล (CRUD)

ผลการเรียนรู้

  • อธิบายรูปแบบการรับข้อมูลจากผู้ใช้และแก้ไขข้อมูลในฐานข้อมูลได้
  • ประยุกต์ใช้ความรู้เพื่อสร้างฟอร์มในการรับข้อมูลจากผู้ใช้และแก้ไขข้อมูลในฐานข้อมูลโดยไม่ได้ใช้คลาสได้
  • ประยุกต์ใช้ความรู้เพื่อสร้างฟอร์มในการรับข้อมูลจากผู้ใช้และแก้ไขข้อมูลในฐานข้อมูลโดยใช้คลาสได้

เนื้อหาหลัก

  • Forms: รับข้อมูลจากผู้ใช้, validate ข้อมูล, และแปลงข้อมูล
  • CRUD: Create, Read, Update, Delete - การจัดการข้อมูลในฐานข้อมูล
  • HTML Forms: โครงสร้างพื้นฐานของ Form บนเว็บ
  • Django Forms: การสร้าง Form ด้วย Django
  • Form Fields: ประเภทของ input fields (text, email, select, etc.)
  • Form Validation: การตรวจสอบความถูกต้องของข้อมูล
  • Form Rendering: การแสดงผล Form ใน Template
  • FBV vs CBV: การใช้ Form กับ Function-Based View และ Class-Based View

Agenda

  • ทำความเข้าใจ Forms และ CRUD ใน Django
  • สร้าง HTML Forms พื้นฐาน
  • สร้าง Django Forms (โดยไม่ใช้ Class)
  • สร้าง Django Forms (โดยใช้ Class)
  • Validate Form Data
  • Render Form ใน Template
  • จัดการ Form Submissions ใน Views
  • ตัวอย่างการใช้งานจริง และ Workshop

Django Forms: การสร้าง Form ด้วย Django

สร้าง Form เพื่อรับข้อมูลจากผู้ใช้และ validate ข้อมูล

Django Form คืออะไร?

  • คลาสที่ represent HTML form
  • กำหนด fields และ validation rules
  • จัดการการ render form ใน template
  • จัดการการประมวลผลข้อมูลที่ส่งมาจาก form

Form Fields

  • CharField: ข้อความ
  • IntegerField: จำนวนเต็ม
  • EmailField: อีเมล
  • BooleanField: ค่า boolean (True/False)
  • ChoiceField: เลือกจากตัวเลือก
  • DateField: วันที่

Form Validation

  • ตรวจสอบความถูกต้องของข้อมูลที่ผู้ใช้กรอก
  • Django มี validation rules ให้ใช้งานมากมาย
  • สามารถสร้าง custom validation rules ได้

สร้าง Django Form (โดยไม่ใช้ Class)

สร้าง Form อย่างง่ายโดยตรงใน View

View (myapp/views.py)

                          
from django.shortcuts import render
from django import forms

def contact_form(request):
    if request.method == 'POST':
        name = request.POST.get('name')
        email = request.POST.get('email')
        message = request.POST.get('message')

        # Validate data (example)
        if not name or not email or not message:
            error = "กรุณากรอกข้อมูลให้ครบถ้วน"
            return render(request, 'contact_form.html', {'error': error})

        # Process data (example)
        print(f"Name: {name}, Email: {email}, Message: {message}")
        success_message = "ส่งข้อมูลสำเร็จ"
        return render(request, 'contact_form.html', {'success_message': success_message})

    return render(request, 'contact_form.html')
                          
                      

Template (myapp/templates/myapp/contact_form.html)

                          
<form method="post">
    <label for="name">Name:<label><br/>
    <input type="text" id="name" name="name"/><br/><br/>

    <label for="email">Email:<label>lt;br/>
    <input type="email" id="email" name="email"/><br/><br/>

    <label for="message">Message:<label/><br/>
    <textarea id="message" name="message">lt;/textarea><br/><br/>

    <button type="submit">Submit</button>
</form>

{% if error %}
    <p style="color:red;">{{ error }}</p>
{% endif %}

{% if success_message %}
    <p style="color:green;">{{ success_message }}</p>
{% endif %}
                          
                      

ข้อจำกัด

  • จัดการยากเมื่อ Form ซับซ้อน
  • Code ซ้ำซ้อน
  • ไม่รองรับ Django Form features (เช่น field types, validation)

สร้าง Django Form (โดยใช้ Class)

สร้าง Form ด้วย Class เพื่อความยืดหยุ่นและการจัดการที่ง่ายขึ้น

Form Class (myapp/forms.py)

                          
from django import forms

class ContactForm(forms.Form):
    name = forms.CharField(label="Name", max_length=100)
    email = forms.EmailField(label="Email")
    message = forms.CharField(label="Message", widget=forms.Textarea)
                          
                      

* สร้าง Form class โดย inherit จาก forms.Form
* กำหนด fields ด้วย forms.CharField, forms.EmailField, etc.
* กำหนด label และ widget (เช่น Textarea)

View (myapp/views.py)

                          
from django.shortcuts import render
from .forms import ContactForm

def contact_form_view(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            # Process data
            name = form.cleaned_data['name']
            email = form.cleaned_data['email']
            message = form.cleaned_data['message']
            print(f"Name: {name}, Email: {{email}}, Message: {message}")
            success_message = "ส่งข้อมูลสำเร็จ"
            return render(request, 'contact_form.html', {'success_message': success_message})
    else:
        form = ContactForm()
    return render(request, 'contact_form.html', {'form': form})
                          
                      

* สร้าง instance ของ Form class * ตรวจสอบว่า Form valid หรือไม่ด้วย form.is_valid() * ดึงข้อมูลที่ cleaned แล้วจาก form.cleaned_data

Template (myapp/contact_form.html)

                          
<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Submit</button>
</form>

{% if form.errors %}
    <p style="color:red;">มีข้อผิดพลาดใน Form</p>
    {{ form.errors }}
{% endif %}

{% if success_message %}
    <p style="color:green;">{{ success_message }}</p>
{% endif %}
                          
                      

* ใช้ {{ form.as_p }} เพื่อ render Form fields
* แสดง errors ด้วย {{ form.errors }}
* อย่าลืม {% csrf_token %} สำหรับป้องกัน CSRF attacks

แสดง Student List ด้วย ListView และ Template

ใช้ ListView เพื่อแสดง List ของ Student objects และ Template ที่กำหนดเอง

View (myapp/views.py)

                          
from django.views.generic import ListView
from myapp.models import Student

class StudentListView(ListView):
    model = Student
    template_name = 'myapp/student/list.html'  # ระบุ path ของ template
                          
                      

* Inherit จาก ListView * กำหนด model เพื่อระบุ Model ที่ต้องการแสดง * กำหนด template_name เพื่อระบุ path ของ template file (สำคัญ)

Template (myapp/templates/myapp/student/list.html)

                          
<h1>Student List</h1>
<ul>
    {% for student in object_list %}
        <li>{{ student.name }} - {{ student.email }}></li>
    {% endfor %}
</ul>
                          
                      

* object_list คือชื่อตัวแปร default ที่ ListView ส่งให้ template * วน loop ผ่าน object_list เพื่อแสดงข้อมูล Student

URL Configuration (urls.py)

                          
from django.urls import path
from . import views

urlpatterns = [
    path('students/', views.StudentListView.as_view(), name='student_list'),
]
                          
                      

* Map URL ไปยัง ListView โดยใช้ .as_view()

Template Directory

ตรวจสอบให้แน่ใจว่าคุณสร้าง directory structure myapp/templates/myapp/student/ และมีไฟล์ list.html อยู่ใน directory นั้น

จัดการ Form ด้วย Class-Based View (CreateView)

ใช้ CreateView เพื่อสร้าง Form และจัดการข้อมูลอย่างง่ายดาย

View (myapp/views.py)

                          
from django.views.generic import CreateView
from myapp.models import Student
from django.urls import reverse_lazy

class StudentCreateView(CreateView):
    model = Student
    fields = ('name', 'dob', 'email')
    template_name = 'myapp/student/create.html'
    success_url = reverse_lazy('myapp:student_list')  # Redirect หลังจาก save
                          
                      

* Inherit จาก CreateView * กำหนด model, form_class, template_name, และ success_url * CreateView จัดการการสร้าง Form และ save ข้อมูลให้

Template (myapp/templates/myapp/student/create.html)

                          
<h1>Create Student</h1>
<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Save</button>
</form>
                          
                      

* Render Form ด้วย {{ form.as_p }}
* CreateView ส่ง Form instance ให้ใน Template

แสดงรายละเอียด Student ด้วย DetailView

ใช้ DetailView เพื่อแสดงรายละเอียดของ Student object

View (myapp/views.py)

                          
from django.views.generic import DetailView
from .models import Student

class StudentDetailView(DetailView):
    model = Student
    template_name = 'myapp/student/detail.html'  # ระบุ template
    context_object_name = 'student'       # เปลี่ยนชื่อ object เป็น student
                          
                      

* Inherit จาก DetailView
* กำหนด model เพื่อระบุ Model ที่ต้องการแสดง
* กำหนด template_name เพื่อระบุ template file
* กำหนด context_object_name (optional) เพื่อเปลี่ยนชื่อ object ที่ส่งไปยัง template (default คือ object)

Template (myapp/templates/myapp/student/detail.html)

                          
<h1>Student Detail</h1>
<p>Name: {{ student.name }}</p>
<p>Email: {{ student.email }}</p>
<p>Date of Birth: {{ student.dob }}</p>
                          
                      

* ใช้ {{ student.name }}, {{ student.email }}, {{ student.dob }} เพื่อแสดงข้อมูลของ Student
* student คือชื่อตัวแปรที่เรากำหนดใน context_object_name (ถ้าไม่ได้กำหนด default คือ object)

URL Configuration (myapp/urls.py)

                          
from django.urls import path
from . import views

urlpatterns = [
    path('student/<int:pk>/', views.StudentDetailView.as_view(), name='student_detail'),
]
                          
                      

* กำหนด URL ที่มี pk (primary key) เพื่อระบุ Student object ที่ต้องการแสดง
* DetailView จะ fetch object จาก database โดยใช้ pk นี้

ข้อควรจำ

  • pk ใน URL ต้องตรงกับ primary key field ของ Student model
  • ตรวจสอบว่า template file อยู่ใน directory ที่ถูกต้อง

จัดการ Form ด้วย Class-Based View (UpdateView)

ใช้ UpdateView เพื่อแก้ไข Form และจัดการข้อมูลอย่างง่ายดาย

View (myapp/views.py)

                          
from django.views.generic.edit import UpdateView
from .forms import StudentForm
from .models import Student
from django.urls import reverse_lazy

class StudentUpdateView(UpdateView):
    model = Student
    fields = ('name', 'dob', 'email')
    template_name = 'myapp/student/update.html'
    success_url = reverse_lazy('student_list')
                          
                      

* Inherit จาก UpdateView
* กำหนด model, form_class, template_name, และ success_url
* UpdateView จะ fetch object จาก database และแสดงใน Form

URL Configuration (myapp/urls.py)

                          
from django.urls import path
from . import views

urlpatterns = [
    path('student/<int:pk>/update/', views.StudentUpdateView.as_view(), name='student_update'),
]
                          
                      

* ต้องส่ง pk (primary key) ใน URL เพื่อระบุ Student object ที่ต้องการแก้ไข

Template (myapp/templates/myapp/student/update.html)

                          
<h1>Update Student</h1>
<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Update</button>
</form>
                          
                      

* Render Form ด้วย {{ form.as_p }}
* UpdateView ส่ง Form instance ที่มีข้อมูลเดิมอยู่แล้วให้ใน Template

จัดการข้อมูลด้วย Class-Based View (DeleteView)

ใช้ DeleteView เพื่อลบข้อมูลอย่างง่ายดาย

View (myapp/views.py)

                          
from django.views.generic.edit import DeleteView
from .models import Student
from django.urls import reverse_lazy

class StudentDeleteView(DeleteView):
    model = Student
    template_name = 'student_confirm_delete.html'  # Template สำหรับยืนยันการลบ
    success_url = reverse_lazy('student_list')
                          
                      

* Inherit จาก DeleteView
* กำหนด model, template_name, และ success_url
* DeleteView จะ fetch object จาก database และแสดงหน้ายืนยันการลบ

URL Configuration (myapp/urls.py)

                          
from django.urls import path
from myapp import views

urlpatterns = [
    path('student/<int:pk>/delete/', views.StudentDeleteView.as_view(), name='student_delete'),
]
                          
                      

* ต้องส่ง pk (primary key) ใน URL เพื่อระบุ Student object ที่ต้องการลบ

Template (myapp/templates/myapp/student/delete.html)

                          
<h1>ยืนยันการลบ Student<</h1>
<p>คุณต้องการลบ {{ object }} ใช่หรือไม่?</p>
<form method="post">
    {% csrf_token %}
    <button type="submit">ยืนยัน</button>
    <a href="{% url 'student_list' %}">ยกเลิก</a>
</form>
                          
                      

* แสดงข้อความยืนยันการลบ
* ใช้ {{ object }} เพื่อแสดงข้อมูลของ Student object ที่ต้องการลบ

Workshop: CRUD Operations for Students

สร้าง application ที่สามารถสร้าง, อ่าน, แก้ไข, และลบข้อมูลนักเรียน

Workshop Steps

  1. สร้าง Django project และ app (students)
  2. กำหนด Model สำหรับ Student (name, email, dob)
  3. สร้าง Form สำหรับ Student
  4. สร้าง Views สำหรับ:
    • แสดง list ของ Students
    • สร้าง Student ใหม่
    • แก้ไข Student
    • ลบ Student
    ใช้ทั้ง FBV และ CBV เพื่อเปรียบเทียบ
  5. สร้าง Templates สำหรับ Views
  6. กำหนด URL patterns ใน urls.py
  7. เพิ่มข้อมูล Student ใน database
  8. ทดสอบ CRUD operations

Extra Challenges

  • เพิ่ม validation rules ใน Form
  • ใช้ pagination ใน list ของ Students
  • เพิ่ม search functionality
  • เพิ่ม User Authentication (login/logout)