รู้จักกับวิว (view) ใน django

9coding official
Jul 27, 2017 · 3 min read

วิว (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 views
urlpatterns = [
...
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 Exam
def 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>
...

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade