พัฒนาเว็บแอพลิเคชันด้วย Django ปฏิบัติการเกี่ยวกับวิศวกรรมคอมพิวเตอร์ (01204223) ผศ.ดร.ชัยพร ใจแก้ว ภาควิชาวิศวกรรมคอมพิวเตอร์ คณะวิศวกรรมศาสตร์ มหาวิทยาลัยเกษตรศาสตร์
แนะนำ Django เฟรมเวิร์คสำหรับสร้างเว็บแอพลิเคชัน "The Web Framework for Perfectionists with Deadlines" เฟรมเวิร์คสำหรับสร้างเว็บแอพลิเคชัน พัฒนาด้วยภาษาไพธอน 2.x (ยังไม่รองรับ 3.x) ตัวอย่างเว็บที่สร้างด้วย Django Washington Post (http://www.washingtonpost.com) Guadian.co.uk E-Labsheet (http://cloud3.cpe.ku.ac.th/elab)
เอกสาร HTML ประกอบด้วยข้อความและแท็ก (Tag) ช่องว่างที่มากกว่าหนึ่งช่องและการขึ้นบรรทัดใหม่ไม่มีผลต่อเอกสาร เปิดแท็ก ปิดแท็ก <html> <head> <title>Example</title> </head> <body> <h1>Hello</h1> Welcome to my homepage. </body> </html> ไฟล์ html ผลลัพธ์บนบราวเซอร์ <html><head><title>Example</title></head> <body><h1>Hello</h1>Welcome to my homepage.</body></html>
การตอบสนองคำร้องขอใน Django http://mysite.com/path/to/1/2 Client (Web browser) Response Request Server (Web App) Models <app>/models.py Database Views <app>/views.py URL resolver urls.py Templates templates/*.html
สร้างโปรเจ็คใหม่ สร้างโปรเจ็คชื่อ myweb ภายในโปรเจ็ค myweb สร้างแอพฯ ชื่อ shape หมายเหตุ: ภายในหนึ่งโปรเจ็คมีได้หลายแอพลิเคชัน $ django-admin startproject myweb $ cd myweb $ ./manage.py startapp shape
ระบุแอพฯ ที่ต้องการใช้งาน แก้ไขไฟล์ settings.py โดยเพิ่ม shape เข้าไปในรายการแอพลิเคชันที่ใช้ : INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'shape', # Uncomment the next line to enable the admin: # 'django.contrib.admin', # Uncomment the next line to enable admin documentation: # 'django.contrib.admindocs', ) (settings.py)
สร้างวิวแรก สร้างวิวชื่อ index ใน shape/views.py หมายเหตุ: ทุกวิวฟังก์ชันจะต้องรับ request เป็นอาร์กิวเมนต์แรกเสมอ from django.http import HttpResponse def index(request): return HttpResponse('Hello') (shape/views.py)
กำหนดวิวให้รูทพาธ (/) ระบุให้พาธ / ถูกส่งไปประมวลผลโดยวิว index โดยแก้ไขไฟล์ urls.py from django.conf.urls.defaults import * # Uncomment the next two lines to enable the admin: # from django.contrib import admin # admin.autodiscover() urlpatterns = patterns('', url(r'^$', 'shape.views.index'), # Example: # (r'^first/', include('first.foo.urls')), # Uncomment the admin/doc line below to enable admin documentation: # (r'^admin/doc/', include('django.contrib.admindocs.urls')), # Uncomment the next line to enable the admin: # (r'^admin/', include(admin.site.urls)), ) regular expression (urls.py)
ทดสอบแอพลิเคชัน รันเว็บเซิร์ฟเวอร์ผ่าน manage.py กรอก http://127.0.0.1:8000/ ลงในช่อง Location ของเว็บบราวเซอร์ หรือพิมพ์ http://0:8000 ก็ได้เช่นกัน $ ./manage.py runserver Validating models... 0 errors found Django version 1.2.5, using settings 'myweb.settings' Development server is running at http://127.0.0.1:8000/ Quit the server with CONTROL-C.
เทมเพลท สำหรับเอกสารที่ซับซ้อน การสร้างอ็อบเจ็กต์ HttpResponse โดยตรงจากวิวเป็นเรื่องยุ่งยาก ต้องสั่งพิมพ์ tag ต่าง ๆ เอาเอง Django มีทางลัดในการสร้าง HttpResponse จาก "เทมเพลท" (Template) ที่เตรียมไว้ล่วงหน้า เทมเพลทมีลักษณะเหมือนเอกสาร HTML ให้ Web Designer เป็นผู้สร้างให้ ไม่ใช่โปรแกรมเมอร์ สร้างได้สะดวกโดยอาศัยซอฟต์แวร์ประเภท HTML Editor เช่น DreamWeaver, Kompozer
สร้างเทมเพลท index.html เตรียมไดเรคตอรีให้เทมเพลท สร้างเอกสาร templates/index.html ดังแสดง (ใช้โปรแกรม Kompozer หรือซอฟต์แวร์ HTML Editor ใดก็ได้) $ mkdir templates (templates/index.html) ใช้รูปแบบ H1 สร้างลิ้งค์ไปที่ shape/rectangle/, shape/circle/ และ shape/triangle/ ตามลำดับ ใส่ชื่อตัวเอง Horizontal Bar
กำหนดที่เก็บเทมเพลท แก้ไขไฟล์ settings.py เพื่อระบุที่อยู่ของเทมเพลท import os PROJECT_DIR = os.path.dirname(__file__) : TEMPLATE_DIRS = ( os.path.join(PROJECT_DIR, 'templates'), ) (settings.py)
เรียกใช้งานเทมเพลทจากวิว แก้ไขฟังก์ชัน index ใน shape/views.py ใช้ทางลัด render_to_response สร้างอ็อบเจ็กต์ HttpResponse จากเทมเพลท รีโหลดหน้าเว็บเพื่อดูความถูกต้อง from django.http import HttpResponse from django.shortcuts import render_to_response def index(request): return render_to_response('index.html') (shape/views.py)
HTML Form เอกสาร HTML สามารถบรรจุฟอร์มเพื่อรับข้อมูลจากผู้ใช้
กำหนดวิวให้พาธ /shape/rectangle เพิ่ม URL mapping ใน urls.py from django.conf.urls.defaults import * # Uncomment the next two lines to enable the admin: # from django.contrib import admin # admin.autodiscover() urlpatterns = patterns('', url(r'^$', 'shape.views.index'), url(r'^shape/rectangle/$', 'shape.views.rectangle_form'), # Example: # (r'^first/', include('first.foo.urls')), # Uncomment the admin/doc line below to enable admin documentation: # (r'^admin/doc/', include('django.contrib.admindocs.urls')), # Uncomment the next line to enable the admin: # (r'^admin/', include(admin.site.urls)), ) (urls.py)
สร้างวิว rectangle_form เพิ่มฟังก์ชันลงไปใน views.py def rectangle_form(request): return render_to_response('rectangle.html') (shape/views.py)
สร้างฟอร์ม rectangle.html เป็นเทมเพลท พาธที่แสดงฟอร์มนี้คือ /shape/rectangle/ การระบุ Action เป็น calculate ทำให้การกด Submit ส่งข้อมูลไปยังพาธ /shape/rectangle/calculate ชื่อ: width ชื่อ: height
เตรียมเทมเพลทแสดงผลคำนวณ เราจะออกแบบให้ใช้เทมเพลทและวิวเดียวกันสำหรับการคำนวณเกี่ยวกับสี่เหลี่ยม วงกลม สามเหลี่ยม ฯลฯ สร้างเทมเพลทชื่อ result.html ดังนี้ ระบุตำแหน่งที่ให้วิวส่งค่ามาแสดงผล (templates/result.html)
สร้างวิวสำหรับคำนวณ เพิ่มฟังก์ชันใน views.py รับอาร์กิวเมนต์ระบุชนิดของรูปทรง def calculate(request, shape_type): if shape_type == 'rectangle': w = float(request.POST['width']) h = float(request.POST['height']) circum = 2*(w+h) area = w*h return render_to_response('result.html', { 'area' : area, 'circum' : circum }) (shape/views.py) ค่าเหล่านี้จะถูกแทนที่ในเทมเพลท
ข้อความส่วนนี้จะถูกส่งไปเป็นอาร์กิวเมนต์ของวิว กำหนดวิวให้พาธ เราจะให้พาธต่อไปนี้ถูกส่งไปวิวเดียวกัน /shape/rectangle/calculate /shape/circle/calculate /shape/triangle/calculate ระบุนิพจน์เรกูลาร์ใน urls.py urlpatterns = patterns('', url(r'^$', 'shape.views.index'), url(r'^shape/rectangle/$', 'shape.views.rectangle_form'), url(r'^shape/(.*)/calculate$', 'shape.views.calculate'), ) (urls.py) ข้อความส่วนนี้จะถูกส่งไปเป็นอาร์กิวเมนต์ของวิว
ระงับการใช้ CSRF Protection Django มีระบบป้องกัน Cross-Site Request Forgery (CSRF) ให้กับทุกวิวที่รับข้อมูลจากฟอร์ม ในตัวอย่างนี้คือวิว calculate เราจะระงับการใช้งานไปก่อนเพื่อความสะดวก แก้ไข shape/views.py โดยใส่ @csrf_except decorator ให้กับ calculate from django.views.decorators.csrf import csrf_exempt : @csrf_exempt def calculate(request, shape_type): (shape/views.py)
แบบฝึกหัด/การบ้าน เพิ่มการคำนวณเกี่ยวกับวงกลมและสามเหลี่ยม วงกลม: รับค่ารัศมี สามเหลี่ยม: รับค่าพิกัดของมุมทั้งสาม