รู้จักกับวิว (view) ใน django
วิว (views)
ส่วนประกอบหนึ่งของสถาปัตยกรรม MVC นอกจากโมเดล (models) ดังที่กล่าวไปแล้ว ยังมีอีกสองส่วนที่เรียกว่าคอนโทรลเลอร์ (controller) และวิว (views) ในส่วนของโมเดลเราได้เรียนรู้กันไปแล้วว่าเป็นส่วนในการจัดการข้อมูล สำหรับคอนโทรลเลอร์จะเป็นส่วนการประมวลผล การคำนวณต่างๆ จะมาเขียนโค้ดรวมไว้ที่นี่ และสุดท้ายคือวิว จะเป็นส่วนที่ใช้แสดงผลข้อมูลที่คำนวณแล้วออกมาทางหน้าจอ
แต่ในจังโก้จะต่างกับ MVC ของเฟรมเวิร์คอื่นอยู่เล็กน้อย นั่นก็คือจังโก้จะเป็น MVT (models-views-template) โดยมันจะทำการประมวลผลข้อมูลต่างๆ ไว้ที่ส่วนของวิว และส่งผลลัพธ์ที่ได้ออกมาทางเทมเพลตนั่นเอง เรามาลองดูตัวอย่างของวิวและเทมเพลตอย่างง่ายๆ กันก่อนดีกว่า อันดับแรกให้สร้างวิวโดยแก้ไขไฟล์ myapp/views.py จากนั้นเพิ่มโค้ดต่อไปนี้ลงไป
from django.shortcuts import renderdef index(request):
return render(request, 'index.html')
ต่อมาให้สร้างโฟลเดอร์ templates และเพิ่ม index.html สำหรับใช้แสดงผลในส่วนของเทมเพลตดังต่อไปนี้
<!doctype html>
<html>
<head>
<title>E-Exam</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
ขั้นตอนสุดท้ายให้แก้ไขไฟล์ urls.py เพื่อผูกวิวของเราให้จังโก้รู้จัก
...
from myapp import viewsurlpatterns = [
...
url(r'^$', views.index, name='index'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
เมื่อแก้ไขครบทุกไฟล์แล้วลองกด refresh ที่เว็บเบราเซอร์จะเห็นว่ามันแสดงผลข้อมูลตามเทมเพลตของเราแล้ว

คราวนี้เรามาลองอีกซักตัวอย่างหนึ่งนั้นก็คือ เทมเพลตแสดงผลข้อมูลได้อย่างไร? โดยการสร้างอาเรย์ข้อมูลปลอมๆ ที่ myapp/views.py จากนั้นส่งข้อมูลดังกล่าวมาแสดงใน template ดังต่อไปนี้
from django.shortcuts import renderdef index(request):
products = [
{'id': 'P01', 'name': 'Macbook Pro Retina', 'price': 45000.00 },
{'id': 'P02', 'name': 'Lenovo Thinkpad', 'price': 40000.60 },
{'id': 'P03', 'name': 'Dell Vostro', 'price': 35000.50 },
{'id': 'P04', 'name': 'Lenovo Yoga', 'price': 32000.70 },
{'id': 'P05', 'name': 'Mac Mini', 'price': 40000.00 },
]
return render(request, 'index.html', { 'products': products })
ที่ส่วนของเทมเพลตให้แก้ไข html เพื่อแสดงผลข้อมูลจากอาเรย์ที่ส่งมาดังนี้
<!doctype html>
<html>
<head>
<title>E-Exam</title>
</head>
<body>
<h1>Products</h1>
<ul>
{% for p in products %}
<li>{{ p.name }}</li>
{% endfor %}
</ul>
</body>
</html>อธิบายโค้ดโปรแกรมจากไฟล์ myapp/views.py เราส่งอาเรย์ของข้อมูลผ่านเข้ามาในชื่อของ “products” จากนั้นที่เท็มเพลตจะสามารถของเห็นตัวแปรนี้ได้ เราก็จัดการวนรอบโดยใช้ {% for %} เพื่อดึงข้อมูลออกมา ซึ่งการแสดงผลจะเขียนด้วยแท็ก {{...}} ซึ่งเป็นคำสั่งของจังโก้ในการแสดงผลค่าตัวแปรออกมานั่นเอง

เรามาเพิ่มตัว filter เพื่อเปลี่ยน format การแสดงผลข้อมูลใน template โดยใช้เครื่องหมาย “|” (pipe) จากตัวอย่างนี้จะเป็นการแสดงผลตัวเลขทศนิยมโดยเอาแค่สองตำแหน่ง
...
<ul>
{% for p in products %}
<li>{{ p.name }} (Price <strong>{{ p.price|floatformat:2 }}</strong> THB)</li>
{% endfor %}
</ul>
...
สร้างส่วนของ Frontend ระบบ e-Exam
เอาล่ะครับทุกท่านคงพอจะรู้จักวิวและเทมเพลตกันพอหอมปากหอมคอไปบ้างแล้ว คราวนี้เรากลับมาดูระบบ e-Exam ของเรากันบ้าง สำหรับหัวข้อนี้จะเป็นการสร้างหน้าจอแสดงข้อมูลข้อสอบกันนะครับ มาเริ่มกันเลย! ก่อนอื่นให้ผู้อ่านล็อกอินเข้าไปที่ admin เพิ่มข้อสอบเข้าไปอีก แล้วเซตให้ข้อสอบต่างๆ อยู่ในสถานะเผยแพร่ซะให้เรียบร้อยก่อนนะครับ

ให้แก้ไข myapp/views.py โดยใช้คำสั่งจัดการเกี่ยวกับโมเดลเพื่อดึงข้อมูลข้อสอบทั้งหมด มาแสดงในเทมเพลตดังต่อไปนี้
from django.shortcuts import render
from .models import Examdef index(request):
exams = Exam.objects.filter(published=True)
return render(request, 'index.html', { 'exams': exams })
จากโค้ดข้างบนเราจะดึงเอาออบเจ็กต์ Exam (ที่ถูกเซตให้มีสถานะ “เผยแพร่”) ออกมาทั้งหมด จากนั้นแก้ไขเทมเพลต index.html ให้แสดงผลรายการข้อสอบออกมาดังนี้
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>E-Exam</title>
</head>
<body>
<h1>e-Exam</h1>
<hr>
<ul>
{% for e in exams %}
<li><a href="#">{{ e.name }}</a></li>
{% endfor %}
</ul>
<hr>
</body>
</html>
ต่อมาเราจะเขียนโค้ดเพื่อรองรับการคลิกเลือกข้อสอบ โดยเราจะแสดงรายละเอียดของข้อสอบนั้นออกมาไม่ว่าจะเป็นชื่อข้อสอบ คำอธิบาย ข้อคำถาม และตัวเลือก โดยเริ่มจากการดึงข้อสอบออกมาจาก ID ที่เลือกขึ้นมาก่อนดังนี้
def index(request):
# get all published exams
exams = Exam.objects.filter(published=True) # get exam by id
id = request.GET.get('id')
if id:
exam = Exam.objects.get(pk=id) return render(request, 'index.html', { 'exams': exams, 'exam': exam })
จากนั้นที่ index.html ให้เพิ่มลิงค์ในการเลือกข้อสอบเข้าไป
...
<ul>
{% for e in exams %}
<li><a href="{% url 'index' %}?id={{ e.id }}">{{ e.name }}</a></li>
{% endfor %}
</ul>
...สำหรับคำสั่ง {% url 'index' %} หมายความว่าให้ลิงค์เข้าไปในยูอาร์แอลชื่อว่า "index" ตามที่เราได้กำหนดไว้ใน urls.py โดยที่ ?id={{ e.id }} หมายความว่าให้ส่ง parameters ชื่อว่า id เป็นแบบ GET เมื่อส่งเข้าไปแล้วตัว views จะทำการนำค่า id นี้ไปดึงเอาข้อสอบนั้นออกมาพร้อมกับส่งออบเจ็กต์ของข้อสอบนั้น กลับมาในชื่อของ "exam" อีกทีนั่นเอง
คราวนี้เราจะมาแก้ไข index.html ให้แสดงรายละเอียดของข้อสอบออกมา
...
<table border="1" width="100%">
<tr>
<td><strong>ชื่อข้อสอบ</strong></td>
<td>{{ exam.name }}</td>
</tr>
<tr>
<td><strong>รายละเอียด</strong></td>
<td>{{ exam.description }}</td>
</tr>
</table>
...