วันอังคารที่ 21 มกราคม พ.ศ. 2557

Django Book Chapter 3 : Views and URLconfs

    จาก Chapter 2 นั้นเราได้สร้างโปรเจคที่ชื่อ mysite ไว้แล้วดังนั้นจะเริ่ม ต้นเรียนรู้การใช้งาน Views และ Urls เบื้องต้นโดยการสร้างเพจที่แสดงคำว่า Hello world ขึ้น

1.สร้างไฟล์ชื่อ views.py ไว้ในโฟลเดอร์ชื่อ mysite ที่อยู่ภายในของโปรเจค mysite ของเราและเขียนโค้ดภายในไว้ดังนี้
from django.http import HttpResponse
def hello(request):
    return HttpResponse("Hello world")
    ซึ่งโค้ดที่เขียนลงไปนั้นคือการสร้างฟังก์ชั่นที่ชื่อ hello ขึ้นมามี Argument 1 ตัวชื่อ request ซึ่งจะเป็น Objects ที่เก็บข้อมูล Web ที่ส่ง request มายัง Views นี้โดยเมื่อเรียกฟังก์ชั่นนี้จะตอบสนองแบบ http ส่งเป็นข้อความว่า Hello world กลับไปและใน views.py นี้ได้มีการ import API มาจาก Django ชื่อ HttpResponse
    จากนั้นหากลอง runserver แล้วเข้าไปยังหน้าเว็บของเรานั้นก็จะยังไม่พบคำว่า Hello world แต่จะยังคงขึ้น It worked! แบบใน Chapter 2 เนื่องจาก Django ยังไม่รู้ว่าเมื่อใดที่เราจะต้องเรียกฟังก์ชั่น hello นี้ขึ้นมาใช้

ภาพตัวอย่างที่อยู่ของไฟล์ views.py


2.จากในข้อ 1 หากเราต้องการให้ Django รู้ว่าเราต้องจะเรียกใช้ฟังก์ชั่น hello ที่อยู่ใน views เมื่อใดก็ต้องใช้ Urls เป็นตัวกำหนดดังนั้นเปิดไฟล์ urls.py ที่อยู่ที่เดียวกับที่เราสร้าง views.py ไปในข้อ 1 แล้วเพิ่ม from mysite.views import hello เข้าไปและเพิ่ม ('^hello/$', hello), เข้าไปใน urlpatterns จะได้รูปแบบดังนี้


    โดยเราได้ import ฟังก์ชั่น hello ใน views.py เข้ามาเพื่อใช้ใน urlpatterns โดย ('^hello/$', hello), เป็นการบอกว่าหากมีการเรียก urls เป็น http://localhost:8000/hello/ ก็จะให้เรียกฟังก์ชั่น hello เป็นตัวจัดการว่าจะส่งอะไรกลับไปแสดงผล โดย hello ส่วนแรกจะเป็นการระบุรูปแบบของ urls โดยมี regular expressions "^" เป็นตัวบอกว่าเริ่ม และ "$" เป็นตัวบอกว่าจบ ส่วน hello ตัวที่ 2 ใช้บอกว่าหากมีชื่อ urls แบบ hello ตัวแรกนั้นจะเรียกฟังก์ชั่นอะไรมาจัดการซึ่งในตัวอย่างนี้ก็เรียกฟังก์ชั่น hello มาจัดการนั่นเอง ทดลองเข้าไปที่ http://localhost:8000/hello/ ก็จะแสดงผลออกมาเป็น hello world ดังนี้


3.หากเราลองเรียก http://localhost:8000/ จะแสดงหน้า 404 Error เหตุผลเพราะเราไม่ได้ตั้งค่าที่ urlpatterns ใน Urls.py ว่าหากมีการเรียกหน้า http://localhost:8000/ จะให้ฟังก์ชั่นอะไรมาจัดการเมื่อไม่มีฟังก์ชั่นไหนมาจัดการก็เลยทำให้เกิด Error ขึ้นอย่างที่เห็น

ภาพตัวอย่างหน้า 404 Error


4.รูปแบบการจัดการ request ของ Django นั้นเมื่อมี request เข้ามานั้น จะอ่านค่า ในไฟล์ setting.py หัวข้อ ROOT_URLCONF ว่ามีค่าเป็นอะไรในเบื้องต้นโปรเจคที่เราสร้างนั้นจะกำหนดไว้เป็นดังนี้ ROOT_URLCONF = 'mysite.urls' ซึ่งก็คือการกำหนดให้อ่านค่าจากไฟล์ urls.py ที่เราแก้ไขในข้อ 2 นั่นเองจากนั้นก็เข้าไปจัดการตามสิ่งที่เราเขียนไว้ใน views และ urls จะได้ค่ากลับมาเป็น HttpResponse เมื่อได้มา Django ก็ทำการแปลงให้เป็นโค้ด HTML กลับไปแสดงผลที่ Browser นั่นเอง

5.หน้าเว็บนั้นหลักๆมีอยู่ 2 ประเภทนั่นคือรูปแบบ Static และ Dynamic ซึ่งตัวอย่างของ Static นั้นก็คือ Hello world ที่เราทำไปแล้วนั่นเอง โดย Static คือไม่ว่าเราจะเรียกหน้านี้ที่เวลาใดๆ ก็จะยังคงให้ข้อมูลกลับมาเหมือนกันทุกครั้ง แต่หากเป็นแบบ Dynamic ข้อมูลที่ได้จะมีการเปลี่ยนแปลงไปตามเวลาที่เรียกใช้ตามตัวอย่างต่อไปนี้

5.1 แก้ไขไฟล์ views.py โดยเพิ่มโค้ดเข้าไปดังนี้
import datetime
def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)
เมื่อเพิ่มเสร็จแล้วจะได้รูปแบบดังนี้


    จากโค้ดจะเป็นการ import API ที่ชื่อ datetime เพิ่มเข้ามาเพื่อใช้ในฟังก์ชั่น current_datetime ซึ่ง ฟังก์ชั่นนี้เมื่อมีการเรียกจะนำค่าวันที่เวลา ณ ตอนที่เรียกนั้นส่งกลับไปใน HttpResponse ให้ Django ไปจัดการต่อเอง

5.2 แก้ไขไฟล์ urls.py โดยเพิ่ม current_datetime เข้าไปในบรรทัดที่ import views เข้ามา และเพิ่ม ('^time/$', current_datetime), เข้าไปใน urlpatterns จะได้ดังรูปนี้


5.3 ทดลองเข้าไปที่ http://localhost:8000/time/ จะแสดงเวลาปัจจุบันให้เราแต่ หากสังเกตดีๆจะพบว่าเวลาที่ได้จะมีความเพี้ยนซึ่งเกิดจาก Time Zone ที่เราอยู่ไม่ตรงกับค่าที่ Django ตั้งมาให้เป็นมาตราฐาน ซึ่งคือ  UTC ดังนั้นวิธีแก้ไขให้เราเปิดไฟล์ settings.py แล้วมองหาหัวข้อ TIME_ZONE จากนั้นแก้ไขเป็น Asia/Bangkok ตามรูป


 ภาพตัวอย่างตอนที่ยังไม่แก้ไข Time Zone


ภาพตัวอย่างหลังจากแก้ไข Time Zone


6.นอกจากหน้าเว็บที่สามารถทำเป็นแบบ Dynamic ได้แล้วนั้น Urls เองก็สามารถทำให้เป็นรูปแบบของ Dynamic ได้ด้วยเช่นกัน หากเราต้องการใช้รูปแบบ Urls ดังนี้
urlpatterns = patterns('',
    ('^time/$', current_datetime),
    ('^time/plus/1/$', one_hour_ahead),
    ('^time/plus/2/$', two_hours_ahead),
    ('^time/plus/3/$', three_hours_ahead),
    ('^time/plus/4/$', four_hours_ahead),
)
เราสามารถแก้ไขให้เป็นรูปแบบดังนี้
urlpatterns = patterns('',
    # ...
    (r'^time/plus/\d+/$', hours_ahead),
    # ...
)
ซึ่ง \d+ เป็นการระบุว่าสามารถใส่เป็นเลขอะไรก็ได้กี่หลักก็ได้ แต่หากเราต้องการกำหนดให้ใส่เลขไม่เกิน 2 หลักก็ให้ใช้ดังนี้ \d{1,2} ซึ่งเป็นอีกหนึ่งใน regular expressions ดังนั้นแก้ไขไฟล์ urls.py ดังนี้


และเพิ่มฟังก์ชั่น hours_ahead ใน views.py ดังนี้
def hours_ahead(request, offset):
    try:
        offset = int(offset)
    except ValueError:
        raise Http404()
    dt = datetime.datetime.now() + datetime.timedelta(hours=offset)
    html = "<html><body>In %s hour(s), it will be %s.</body></html>" % (offset, dt)
    return HttpResponse(html)
    โดยฟังก์ชั่นนี้มี Arguments 2 ตัวคือ request และ offset ซึ่ง offset นั้นจะเอาค่าของเลขที่เราใส่ใน Urls มาใช้ โดยฟังก์ชั่นนี้ใช้ API datetime ในดึงเวลามาแล้วบวกเพิ่มไปด้วย datetime.timedelta ไปเป็นจำนวนชั่วโมงตามค่าของ offset ที่รับมา จะสังเกตได้ว่าช่วงแรกนั้นมีการใช้ try & except ด้วยเนื่องจากค่าที่เราใช้ในการคำนวณเวลาต้องเป็นตัวเลขเท่านั้นหากมีการใส่ค่าใน urls มาเป็นตัวอักษรก็จะแปลงค่าจาก String ที่ได้มาจาก Urls ไปเป็น int ไม่ได้แล้วเกิด ValueError ขึ้นเพื่อป้องกันความผิดพลาดตรงนี้เลยมีการใส่ try & except เข้าไปเพื่อไม่ให้ Error ส่วนนี้สร้างปัญหาให้กับ Web Application ของเราได้ โดยหากเกิด ValueError ก็จะเปลี่ยนเพจจากการแสดงผลตามปกติไปเป็นหน้า 404 Error แทน

ภาพตัวอย่างเมื่อใส่ค่า 12 ลงใน Urls


ภาพตัวอย่างเมื่อใส่ค่า 100 ลงใน Urls จะเกิด Error เนื่องจากรูปแบบของ Urls


ภาพตัวอย่างเมื่อใส่ตัวอักษรลงใน Urls


    จาก Chapter 3 นี้เราสามารถทำให้ทั้ง Urls และ Views ของเรานั้นอยู่ในรูปแบบของ Dynamic ได้ด้วยการใช้ regular expression เป็นตัวช่วยในส่วนของ Urls และ API ของ Python และ Django มาช่วยใน Views อีกทั้งการเขียนฟังก์ชั่นในการแสดงผลควรจะมีการคิดถึงกรณีที่ผู้ใช้ใส่ค่ามามาผิดรูปแบบจากที่ต้องการเช่นใส่ ตัวอักษรมาให้แต่ฟังก์ชั่นเราต้องการตัวเลข ในส่วนนี้เป็นส่วนที่ต้องคำนึงถึงในการพัฒนา Web Application ขึ้นด้วย


ไม่มีความคิดเห็น:

แสดงความคิดเห็น