Table of Contents
หน้านี้เป็นส่วนหนึ่งของตัวอย่างการพัฒนาโปรแกรมด้วย Django: uquiz
หน้าที่เป็นตัวอย่างการใช้งานฟอร์มใน Django ผ่านทางระบบฟอร์ม อ่านข้อมูลเกี่ยวกับการจัดการฟอร์มเบื้องต้นได้จากคู่มือ Django และอ่านการใช้ระบบฟอร์มได้จากคู่มือเช่นเดียวกัน
สร้าง form และแสดง form
เพิ่ม class QuizInfoForm
ลงใน quiz/views.py
พร้อมด้วยวิวฟังก์ชัน new
ที่แสดง form นี้
สังเกตว่า เราไม่ได้ให้ผู้ใช้ระบุ is_enabled
ในฟอร์มนี้ เพราะเราจะให้สถานะเริ่มต้นของ quiz เป็นแบบยังไม่เปิดใช้งานจนกว่าผู้ใช้จะระบุต่อไป
--- a/quiz/views.py Mon Sep 14 08:10:54 2009 +0700 +++ b/quiz/views.py Mon Sep 14 08:16:55 2009 +0700 @@ -10,3 +10,12 @@ quizes = Quiz.objects.filter(is_enabled=True).all() return render_to_response("quiz/list.html", { 'quizes': quizes }) + +class QuizInfoForm(forms.Form): + title = forms.CharField() + description = forms.CharField() + +def new(request): + form = QuizInfoForm() + return render_to_response("quiz/new.html", + { 'form': form })
จากนั้นไปเพิ่ม template quiz/new.html
{% extends "base.html" %} {% block content %} <h2>Quiz creation</h2> <p> {{ form.as_p }} </p> {% endblock %}
และสุดท้ายไปเพิ่ม url mapping ใน urls.py
เราจะ map url new-quiz
ให้กับวิวนี้
--- a/urls.py Mon Sep 14 08:10:54 2009 +0700 +++ b/urls.py Mon Sep 14 08:16:55 2009 +0700 @@ -8,6 +8,7 @@ urlpatterns = patterns('', (r'^$', 'quiz.views.index'), (r'^list/$', 'quiz.views.list'), + (r'^new-quiz/$', 'quiz.views.new'), # Example: # (r'^uquiz/', include('uquiz.foo.urls')),
ทดลองใช้โดยเรียก http://localhost:8000/new-quiz/
เพิ่มลิงก์จากหน้าแรก
แก้ template quiz/index.html
ให้แสดงลิงก์ไปยังหน้าสร้าง quiz
--- a/templates/quiz/index.html Mon Sep 14 08:19:49 2009 +0700 +++ b/templates/quiz/index.html Mon Sep 14 08:20:56 2009 +0700 @@ -7,7 +7,7 @@ <p> What you can do here: <ul> - <li>Create quizes</li> + <li><a href="{% url quiz.views.new %}">Create quizes</a></li> <li><a href="{% url quiz.views.list %}">Play quizes</a></li> </ul> </p>
ประมวลผลฟอร์ม (รับค่า)
เราจะแก้ template โดยเพิ่ม tag ส่วนของ form และปุ่ม submit สังเกตว่าที่ action เราจะระบุไปที่วิวฟังก์ชันเดิม (โดยใช้ template tag url
) แต่จะระบุวิธีการเรียกใช้ (method
) เป็น post
--- a/templates/quiz/new.html Mon Sep 14 08:34:11 2009 +0700 +++ b/templates/quiz/new.html Mon Sep 14 08:38:57 2009 +0700 @@ -3,6 +3,9 @@ {% block content %} <h2>Quiz creation</h2> <p> - {{ form.as_p }} + <form action="{% url quiz.views.new %}" method="post"> + {{ form.as_p }} + <input type="submit" value="Create quiz"/> + </form> </p> {% endblock %}
จากนั้นเราจะแก้วิวฟังก์ชันให้รับและตรวจสอบฟอร์ม สังเกตว่าเราจะใช้วิวฟังก์ชันเดิม แต่เราจะเพิ่มการตรวจสอบ request.method
ว่าเรียกเข้ามาแบบ post หรือไม่
--- a/quiz/views.py Mon Sep 14 08:34:11 2009 +0700 +++ b/quiz/views.py Mon Sep 14 08:38:57 2009 +0700 @@ -16,6 +16,13 @@ description = forms.CharField() def new(request): - form = QuizInfoForm() + if request.method=="POST": + form = QuizInfoForm(request.POST) + if form.is_valid(): + print "Title:", form.cleaned_data['title'] + print "Description:", form.cleaned_data['description'] + return + else: + form = QuizInfoForm() return render_to_response("quiz/new.html", { 'form': form })
โปรแกรมด้านบนจะเรียก is_valid
เพื่อตรวจสอบฟอร์ม ถ้าตรวจสอบไม่ผ่านจะส่งกลับไปแสดงผลพร้อมด้วย error message (ให้ทดลองดู)
แต่ถ้าฟอร์มถูกต้องโปรแกรมจะพิมพ์ค่าออกมาที่ console ส่วนในเว็บจะมี error จาก django ขึ้น ว่า The view quiz.views.new didn't return an HttpResponse object.
ถ้าเราไปดูที่ console (ใน terminal เราเรียก runserver) เราจะพบข้อความประมาณด้านล่างนี้:
Title: test quiz Description: this is a test [13/Sep/2009 20:42:08] "POST /new-quiz/ HTTP/1.1" 500 49981
ประมวลผลฟอร์ม (สร้าง quiz แล้ว redirect)
เราจะเพิ่มโปรแกรมส่วนประมวลผลฟอร์มเมื่อฟอร์มผ่านการตรวจสอบ เราจะสร้าง quiz ขึ้นมาแล้วใส่ค่าที่ได้จากฟอร์มลงไป ในที่นื้เราจะกำหนดค่า is_enabled
ให้เป็น True
ไปก่อน เพื่อที่เราจะได้เข้าไปตรวจสอบความถูกต้องของการเพิ่มข้อมูลได้จากหน้ารายการ quiz
เมื่อเราสร้าง quiz เสร็จแล้ว เราก็จะ redirect ผู้ใช้กลับไปหน้าแรก โดยการคืนวัตถุของคลาส HttpResponseRedirect
กลับไป
--- a/quiz/views.py Mon Sep 14 08:45:28 2009 +0700 +++ b/quiz/views.py Mon Sep 14 08:46:42 2009 +0700 @@ -1,4 +1,5 @@ from django.shortcuts import render_to_response +from django.http import HttpResponseRedirect from django import forms from models import Quiz @@ -19,9 +20,12 @@ if request.method=="POST": form = QuizInfoForm(request.POST) if form.is_valid(): - print "Title:", form.cleaned_data['title'] - print "Description:", form.cleaned_data['description'] - return + quiz = Quiz() + quiz.title = form.cleaned_data['title'] + quiz.description = form.cleaned_data['description'] + quiz.is_enabled = True + quiz.save() + return HttpResponseRedirect('/') else: form = QuizInfoForm() return render_to_response("quiz/new.html",
การใช้ reverse แทนการระบุ url โดยตรง
เช่นเดียวกับใน template เราไม่ต้องการระบุ url ลงไปตรง ๆ ในโปรแกรม ดังนั้นจากโปรแกรมข้างต้นที่ระบุ /
เมื่อสร้าง HttpResponseRedirect เราจะหา url ผ่านทางฟังก์ชัน reverse
ที่อยู่ในโมดูล django.core.urlresolvers
(อย่าลืม import)
--- a/quiz/views.py Mon Sep 14 08:49:41 2009 +0700 +++ b/quiz/views.py Mon Sep 14 08:54:47 2009 +0700 @@ -1,5 +1,6 @@ from django.shortcuts import render_to_response from django.http import HttpResponseRedirect +from django.core.urlresolvers import reverse from django import forms from models import Quiz @@ -25,7 +26,7 @@ quiz.description = form.cleaned_data['description'] quiz.is_enabled = True quiz.save() - return HttpResponseRedirect('/') + return HttpResponseRedirect(reverse('quiz.views.index')) else: form = QuizInfoForm() return render_to_response("quiz/new.html",
ต่อจากนี้
เราวางแผนไว้ว่าเมื่อสร้าง quiz เสร็จ เราจะพาผู้ใช้ไปหน้าสำหรับใส่คำถามและจัดการ quiz ดังนั้นแทนที่เราจะ redirect กลับไปที่หน้าแรก เราควรจะ redirect ไปหน้าจัดการ quiz ซึ่งจะมี url เฉพาะสำหรับผู้สร้าง quiz เท่านั้น เราจะเขียนในส่วนนี้ในโอกาสต่อไป (โปรดติดตาม)