tutorial part 1
ใน tutorial part 1 จะพูดถึงงวิธีการสร้าง Django App อย่างง่าย รู้จักคำสั่งพื้นฐานในการสร้าง App เพื่อนำไปใช้ในการพัฒนา web application ได้
ทำไมต้องมี apps ในไฟร์ project
project สร้างขึ้นเพื่อเก็บข้อมูลการแสดงผล และ setting ค่าต่างๆใน database เมื่อมีการแสดงผลมากขึ้น การที่มีเฉพาะไฟร์ project เพียงอย่างเดียวอาจทำให้ยุ้งยากต่อการแก้ไข
django app จึงถูกสร้างขึ้นเพื่อความเป็นระเบียบ ง่ายต่อการแก้ไข และถูกสร้างขึ้นเพื่อใช้ในการพัฒนา web application โดยเฉพาะ
คำสั่งที่เกียวข้อง
- เราสามารถทำการตรวจสอบ version ของ django โดยใช้คำสั่ง
python -c "import django; print(django.get_version())"
- เราสามารถกำหนด port ในการ run server ได้โดยใช้คำสั่ง
python manage.py runserver 8080
ซึ่ง server ก็จะรันอยู่ที่ port 8080
- เราสามารถกำหนด HOST ที่จะ run server ได้โดยใช้คำสั่ง
python manage.py runserver 0.0.0.0:8000
ซึ่ง server ก็จะรันอยู่ที่ HOST: 0.0.0.0
- การ set time zone เพื่อให้ได้เวลาของฐานข้อมูลจริง ณ ที่อยู่ปัจจุบัน เราสามารถ set โดยเข้าไปในไฟร์ settings.py ที่อยู่ใน Directory ของ project ทำการเปลี่ยนตรง TIME_ZONE = 'Asia/Bangkok'
ขั้นตอนและวิธีการสร้าง Django apps
1. cd เข้าไปยัง part ที่ได้ทำการสร้าง project ไว้ ซึ่งเราจะสร้าง app ไว้ใน part ที่มีไฟร์ manage.py อยู่
2. เริ่มทำการ startapp โดยใช้คำสั่ง
python manage.py startapp polls
3. เมื่อมีการใช้คำสั่ง startapp จะมีไฟร์ทั้งหมดเพิ่มขึ้นมาใน Directory polls ดังนี้
4. ทำการจัดการเกี่ยวกับไฟร์ models.py ซึ่งเป็นไฟร์ที่ใช้ในการเก็บรูปแบบข้อมูลพื้นฐานต่างๆ เกี่ยวกับ app และ admin เช่น วัน เวลาปัจจุบัน ทำการแก้ไขไฟร์ models.py โดยการเพิ่มคลาส Choice และ Poll
from django.db import models
class Poll(models.Model):
question = models.CharField(max_length=200)
#เก็บค่า question เป็น char ขนาดไม่เกิน 200
pub_date = models.DateTimeField('date published')
#เก็บค่า pub_date เป็น DateTime
class Choice(models.Model):
poll = models.ForeignKey(Poll)
#เชื่อม ForeignKey เข้ากับ class Poll
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
#เก็บค่า votes เป็น Integer
จากโค้ดด้านบนเป็นรูปแบบการเก็บข้อมูลซึ่งประกอบด้วยสอง class, class Poll และ Choice แต่ละ class จะเก็บเป็นตาราง ซึ่งเราสามารถ set ค่าต่างๆใน class Poll ได้โดยตรง แต่การ set ใน class Choice ต้อง set ผ่าน class Poll โดยใช้ ForeignKey เป็นตัวเชื่อม
5. ทำการเพิ่ม 'polls', เข้าไปยัง INSTALLED_APPS ในไฟร์ settings.py เพื่อให้ ptoject รู้จัก app ดังภาพ
เราสามารถตรวจสอบส่วนประกอบของ Poll app ที่เราได้สร้างขึ้นโดยใช้คำสั่ง
python manage.py sql polls
6. ทำการ syncdb เพื่อทำการสร้างฐานข้อมูลด้วยคำสั่ง
python manage.py syncdb
แล้วใส่ superuser username, e-mail และ password ของเราเพื่อนำไปใช้ในการจัดการข้อมูลในส่วนของ admin
7. เมื่อทำการ syncdb เรียบร้อยแล้วเราก็จะได้ฐานข้อมูลที่เราสร้างขึ้น มาถึงขั้นตอนนี้เราก็จะมาลองแก้ไขข้อมูล และแสดงผลข้อมูลต่างๆใน models ซึ่งสามารถทำได้โดย
ผ่าน Python shell ซึ่งเป็น API Django โดยใช้คำสั่ง
python manage.py shell
ตัวอย่างการใช้คำสั่งการ set ข้อมูลโดยใช้ shell
- เริ่มต้นเมื่อเรายังไม่ได้ทำการ set ค่าใดๆเลยทดลองใช้คำสั่ง
from polls.models import Poll, Choice
#เรียกใช้ class Poll และ Choice
Poll.objects.all() #คำสั่งเรียกค่าที่อยู่ใน objects ของ Poll
จะเห็นได้ว่าสิ่งที่ได้หลังจากการเรียกใช้คำสั่ง Poll.objects.all() คือ [] หมายถึงยังไม่มีการเริ่ม set ค่าใดๆ
- ทดลองทำการ set ค่า
from django.utils import timezone
#ทำการ import timezone
p = Poll(question="What’s new?", pub_date=timezone.now())
#ทำการ set ค่า question และ pub_date ใน class Poll
p.save() #จัดเก็บค่า p
p.id #คำสั่งแสดงค่า id ของ p
>>> 1
p.question #คำสั่งแสดงค่า question ที่ได้ทำการ set
>>> "What’s new?"
p.pub_date #คำสั่งแสดง pub_date ที่ได้ทำการ set
>>> datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)
p.question = "What’s up?" #ทำการเปลี่ยนค่า question
p.save()
- เมื่อทำการ set ค่าไปบ้างแล้วทดลองใช้คำสั่ง Poll.objects.all() อีกครั้งซึ่งจะทำให้ได้ผลเป็น [<Poll: Poll object>] เมื่อได้ผลดังนี้ต้องไปทำการเพิ่ม object ใน class Poll และ Choice เพื่อให้ทำการ return ค่าออกมา โดยทำการเพิ่มดังนี้
from django.db import models
class Poll(models.Model):
# ...
def __unicode__(self): # Python 3: def __str__(self):
return self.question
class Choice(models.Model):
# ...
def __unicode__(self): # Python 3: def __str__(self):
return self.choice_text
เมื่อทำการเพิ่มเสร็จแล้วทดลองใช้คำสั่ง Poll.objects.all() อีกครั้งซึ่งจะทำให้ได้ผลเป็น [<Poll: What’s up?>] คือค่าที่ return ออกมา
- ซึ่งการ set ค่าต่างๆใน class Choice โดยใช้คำสั่งผ่าน Python shell สามารถศึกษาเพิ่มเติมได้ที่เอกสาร Django tutorial part1 : https://docs.djangoproject.com/en/dev/intro/tutorial01/
สิ่งที่ได้เรียนรู้จาก tutorial part1
- รู้คำสั่งต่างๆที่ใช้ run server และวิธีการ set time zone
- ได้รู้จักเริ่มต้นการสร้าง Django App อย่างง่าย
- ได้รู้จักวิธีการกำหนดค่าใน models
- ได้ทดลองใช้ python shell ในการเขียน แสดงค่า และแก้ไข ไฟร์ models
=======================================================================
tutorial part 2
โดย part นี้จะพูดเกี่ยวกับ admin site ซึ่ง admin site ก็เป็นอีกช่องทางหนึ่งสำหรับการแก้ไขและเพิ่มข้อมูลต่างๆใน models
1. เริ่มจากการรัน server project ด้วยคำสั่ง python manage.py runserver แล้วทำการเข้าไปตาม url/admin เช่น 127.0.0.0:8000/admin
2. ทำการ login ด้วย superuser ที่เคยได้ใส่ไปตอน syncdb ซึ่งก็จะได้หน้าหลักดังภาพ
ซึ่งเริ่มต้นยังไม่มีการแก้ไขไฟร์ admin.py ก็จะมีเฉพาะ groups และ users ซึ่งสามารถเพิ่มและแก้ไขได้โดยการคลิกที่ add และ change
3. ทดลองแก้ไขไฟร์ admin.py โดยเพิ่มโค้ดส่วนนี้ไปในไฟร์ admin.py
from polls.models import Poll
admin.site.register(Poll)
ซึ่งส่วนนี้จะเป็นการเพิ่มตารางการแก้ไข class Poll เข้าไปใน admin site เมื่อเข้าไปยังหน้า admin site ก็จะมีตารางส่วนการแก้ไข Poll เพิ่มขึ้นมาสามารถเพิ่มและแก้ไขได้โดยกด add และ change
4. Polls ทำการคลิก change > What's up? จะได้หน้าแก้ไขดังภาพ
ส่วนนี้เราสามารถจัดลำดับการแสดงผลเพิ่มลำดับการจัดเก็บข้อมูลต่างๆ โดยทดลองทำการแก้ไขไฟร์ admin.py ดังนี้
from django.contrib import admin
from polls.models import Poll
class PollAdmin(admin.ModelAdmin):
fields = ['pub_date', 'question']
admin.site.register(Poll, PollAdmin)
จากโค้ดจะเป็นการเพิ่ม class PollAdmin ซึ่งจะมีคำสั่ง fields = ['pub_date', 'question'] ทำหน้าที่ในการจัดการแสดงผลโดยให้ pub_date ขึ้นก่อน question จากเดิมที่ question อยู่ก่อน pub_date
5. นอกจากนี้ยังสามารถปรับเปลี่ยนการแสดงผลต่างๆได้โดยการแก้ไขโค้ดเช่น
from django.contrib import admin
from polls.models import Poll
class PollAdmin(admin.ModelAdmin):
fieldsets = [(None,{'fields': ['question']}),
('Date information', {'fields': ['pub_date']}),]
admin.site.register(Poll, PollAdmin)
จากโค้ดด้านบรจะเป็นการแยกการแสดงผลออกเป็นสองตาราง fields แรกจะแสดง
question, fields สองจะแสดง pub_date
from django.contrib import admin
from polls.models import Poll
class PollAdmin(admin.ModelAdmin):
fieldsets = [(None,{'fields': ['question']}),
('Date information', {'fields': ['pub_date'],
'classes': ['collapse']}),]
admin.site.register(Poll, PollAdmin)
ส่วนโค้ดด้านบนก็จะเป็นการแยก fields question กับ pub_date แต่จะเพิ่มลูกเล่นเข้าไปในส่วนของ pub_date ให้มีการกด show หรือทำการ hide ได้
6. ต่อไปก็จะเป็นส่วนการเพิ่มตารางการแก้ไขในส่วนของ class Choice เข้าไปใน admin site ซึ่งสามารถทำได้โดยการแก้ไข admin.py ดังนี้
from django.contrib import admin
from polls.models import Choice
admin.site.register(Choice)
โค้ดด้านบนก็เป็นการ import class Choice เข้ามาใน admin site ซึ่งก็จะสามารถ add เก็บค่า Choice text ตาม question ของ class Poll
from django.contrib import admin
from polls.models import Choice, Poll
class ChoiceInline(admin.StackedInline):
model = Choice
extra = 3
class PollAdmin(admin.ModelAdmin):
fieldsets = [(None,{'fields': ['question']}),
('Date information', {'fields': ['pub_date'],
'classes': ['collapse']}),]
inlines = [ChoiceInline]
admin.site.register(Poll, PollAdmin)
โค้ดส่วนด้านบนเป็นการเพิ่ม class Poll และ class Choice ไปใน admin site ซึ่งเมื่อกด add ที่ Polls เริ่มต้นจะมี Choice ทั้งหมด 3 Choice ให้ใส่ และสามารถเพิ่มข้อมูล Choice ได้เรื่อยๆ
สิ่งที่ได้เรียนรู้จาก tutorial part2
- ได้รู้ถึงวิธิการปรับแต่งการแสดงผลในหน้า Addmin site
- ได้รู้วิธีการเพิ่ม แก้ไข ข้อมูลใน model โดย Addmin site ได้
- ได้รู้คำสั่งและวิธีการแก้ไขไฟร์ addmin.py เพื่อการแสดงผลบน Addmin site
=======================================================================
tutorial part3
ในส่วนของ part 3 จะเป็นส่วนการแสดงผลข้อมูลที่เราได้เขียนลงไปในไฟร์ poll/views.py โดยจะ return ด้วยคำสั่ง HttpResponse( .. ) ผ่านไฟร์ poll/url.py และ mysite/url.py ซึ่งสามารถนำ Template มาช่วยในการเขียนส่วนของการแสดงผล
1. เริ่มต้นให้ทดลองเขียนโค้ด poll/views.py เพื่อทำการแสดงผลดังนี้
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the poll index.")
จากโค้ดด้านบนจะเป็นการเขียนโค้ดเพื่อทำการแสดงผลข้อความ Hello, world. You’re at the poll index. โดยจะ return ส่วนแสดงผลไปยัง poll/url.py เพื่อไปทำการแสดงผลผ่าน mysite/url.py อีกทีหนึ่ง
2. ทำการสร้างไฟร์ poll/urls.py แล้วทำการเขียนโค้ดในไฟร์ poll/urls.py ดังนี้
from django.conf.urls import patterns, url
from polls import views
urlpatterns = patterns('',
url(r'^$', views.index, name='index')
)
จากโค้ดด้านบนจะเป็นการเรียกการแสดงผลจากไฟร์ views.py ฟังก์ชั่น index เพื่อมาแสดงผล
3. ทำการแก้ไขไฟร์ mysite/urls.py เพื่อให้ไปเรียกไฟร์ poll/urls.py มาแสดงผลอีกทีโดยเพิ่ม
url(r'^polls/', include('polls.urls')),
เข้าไปในส่วนของ urlpatterns ในไฟร์ mysite/urls.py ซึ่งจะเป็นส่วนในการเชื่อมโยงไปหาไฟร์ poll/urls.py
4. ทำการเข้าไปยัง url ที่ได้รัน server url/polls (http:127.0.0.1:8000/polls/) ได้ได้ผลดังรูป

5. เราสามารถนำ url มาใช้ในการแสดงผลโดยการเขียนฟังก์ชั่นเพิ่มไปในไฟร์ polls/views.py ดังนี้
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the poll index.")
def detail(request, poll_id):
return HttpResponse("You're looking at poll %s." % poll_id)
def results(request, poll_id):
return HttpResponse("You're looking at the results of poll %s." % poll_id)
def vote(request, poll_id):
return HttpResponse("You're voting on poll %s." % poll_id)
จากโค้ดด้านบนจะเป็นการเพิ่มฟังก์ชั่นขึ้นมาหลายฟังก์เพื่อแยกการแสดงผลที่แต่กต่างกันและเป็นการรับค่าตัวเลขจาก url มาแสดงด้วย ซึ่งการแสดงผลเมื่อเรียกใช้ฟังก์ชั่น index จะแสดงข้อความ Hello, world. You're at the poll index. เมื่อเรียกใช้ฟังก์ชั่น detail จะแสดงข้อความ You're looking at poll 'ตัวเลขที่ใส่ใน url'. เมื่อเรียกใช้ฟังก์ชั่น results จะแสดงข้อความ You're looking at the results of poll 'ตัวเลขที่ใส่ใน url'. เมื่อเรียกใช้ฟังก์ชั่น vote จะแสดงข้อความ You're voting on poll 'ตัวเลขที่ใส่ใน url'.
6. เมื่อมีการเพิ่มฟังก์ชั่นการแสดงผลไปในไฟร์ polls/views.py แล้วก็จะมาถึงส่วนสร้าง url เพื่อทำการเรียกใช้ฟังก์ชั่น โดยเราจะไปทำการแก้ไขไฟร์ polls/urls.py ดังนี้
from django.conf.urls import patterns, url
from polls import views
urlpatterns = patterns('',
# url/polls/5/
# เป็นส่วนการเรียกฟังก์ชั่น detail มาแสดงผล
url(r'^(?P<poll_id>\d+)/$', views.detail, name='detail'),
# url/polls/5/results/
# เป็นส่วนการเรียกฟังก์ชั่น resulte มาแสดงผล
url(r'^(?P<poll_id>\d+)/results/$', views.results,
name='results'),
# url/polls/5/vote/
# เป็นส่วนของการเรียกฟังก์ชั่น vote มาแสดงผล
url(r'^(?P<poll_id>\d+)/vote/$', views.vote, name='vote'),
# url/polls/
# เป็นส่วนของการเรียกฟังก์ชั่น index มาทำการแสดงผล
url(r'^$', views.index, name='index')
)
จากโค้ดเป็นการเขียน url เพื่อเรียกใช้ฟังก์ชั่นโดย url/polls/5/ จะเรียกใช้ฟังก์ชั่น detail มาแสดงผล url/polls/5/resulte/ จะเรียกใช้ฟังก์ชั่น resulte มาแสดงผล url/polls/5/vote จะเรียกใช้ฟังก์ชั่น vote มาแสดงผล url/poll/ จะเรียกฟังก์ชั่น index มาแสดงผล
7. เราสามารถเขียนโค้ดเพื่อเรียกการแสดงผล question ที่ได้ใส่ลงไปใน tutorial part1 และ part2 ที่เป็นการแสดงผลผ่าน Python Shell และ admin site ซึ่งมาถึง part3 เราจะทำการเขียนโค้ดเพื่อการแสดงผลโดยต้องทำการแก้ไขตรงไฟร์ polls/views.py โดยแก้ไขฟังก์ชั่น index() ดังนี้
from django.shortcuts import render
from django.http import HttpResponse
from polls.models import Poll
def index(request):
latest_poll_list = Poll.objects.order_by('-pub_date')[:5]
output = ', '.join([p.question for p in latest_poll_list])
return HttpResponse(output)
def detail(request, poll_id):
return HttpResponse("You're looking at poll %s." % poll_id)
def results(request, poll_id):
return HttpResponse("You're looking at the results of poll %s." % poll_id)
def vote(request, poll_id):
return HttpResponse("You're voting on poll %s." % poll_id)
def vote(request, poll_id):
return HttpResponse("You're voting on poll %s." % poll_id)
จากโค้ดจะเป็นการเรียก class Poll ใน polls/models.py ออกมาทำการแสดงผล question ซึ่งเมื่อเราเข้าไปยัง url/polls/ ก็จะมีข้อความที่เก็บใน question แสดงอยู่
ซึ่งในส่วนการแสดงผลนี้เราสามารถเขียนแยกเป็น Template ได้ ในที่นี้จะยกตัวอย่างโดยการสร้าง directory template ไว้ใน directory polls
polls/template/poll/index.html ทำการใส่ path template ในไฟร์ setting.py ของ directoty project
แล้วเราจะทำการแก้ไขสองไฟร์คือ ไฟร์ template/poll/index.html และไฟร์ polls/view.py ซึ่งไฟร์ template/polls/index.html เราจะทำการแก้ไขดังนี้
{% if latest_poll_list %}
<ul>
{% for poll in latest_poll_list %}
<li><a href="/polls/{{ poll.id }}/">{{ poll.question }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
จากโค้ดเป็น form ส่วนการแสดงผล question ซึ่งจะเชื่อมโยงกับไฟร์ polls/view.py โดยทำการแก้ไขไฟร์
from django.template import RequestContext, loader
from django.http import HttpResponse
from polls.models import Poll
def index(request):
latest_poll_list = Poll.objects.order_by('-pub_date')[:5]
template = loader.get_template('polls/index.html')
context = RequestContext(request, {
'latest_poll_list': latest_poll_list,
})
return HttpResponse(template.render(context))
def detail(request, poll_id):
return HttpResponse("You're looking at poll %s." % poll_id)
def results(request, poll_id):
return HttpResponse("You're looking at the results of poll %s." % poll_id)
def vote(request, poll_id):
return HttpResponse("You're voting on poll %s." % poll_id)
จากโค้ดเป็นโค้ดส่วนการแสดงผลใน polls/view.py ซึ่งจะเป็นส่วนที่ดึง form ที่่เขียนไว้มาแสดงผล เมื่อเราเข้าไปยัง url/polls/ ก็จะมีข้อความที่เก็บใน question แสดงอยู่
ซึ่งใน part นี้การเขียนออกมาในรูปของ form มีอีกหลายรูปแบบซึ่งสามารถศึกษาเพิ่มเติมได้ที่เอกสาร Django tutorial part3 :
https://docs.djangoproject.com/en/dev/intro/tutorial03/
8. Http404 หรือ get_object_or_404() เป็น function ของ django ที่ช่วยในการดัก exception ซึ่งเราจะใช้เมื่อมีการเรียกใช้งานจาก url ซึ่งการเรียกใช้นั้นไม่ตรงกับเงื่อนไขไดๆในโค้ด ก็จะกลายเป็น exception แสดงหน้าของ Http404 เพื่อให้รู้ว่า url ที่ทำการเรียกไม่ตรงกับเงื่อนไขไดๆ หรือไม่มีในข้อมูล ซึ่งตัวอย่างการใส exception ก็เช่นทำการแก้ไขฟังก์ชั่น detail ในไฟร์ polls/view.py ดังนี้
from django.http import Http404
from django.shortcuts import render
#....
def detail(request, poll_id):
try:
poll = Poll.objects.get(pk=poll_id)
except Poll.DoesNotExist:
raise Http404
return render(request, 'polls/detail.html', {'poll': poll})
#....
สร้างไฟร์ template/polls/detail.html แล้วทำการแก้ไขไฟร์ดังนี้
{{ poll }}
จากโค้ดเมื่อเข้าไปยัง url/polls/1 ก็จะแสดง question poll_id 1 ซึ่งเมื่อเปลี่ยนเลย 1 เป็นเลขอื่นเช่น 2 ก็จะแสดงหน้า Http404 ซึ่งเป็น exception ที่สร้างขึ้น เนื่องจาก question poll_id 2 ไม่มีในฐานข้อมูล
9. url in template
url เป็นอีกอย่างหนึ่งที่สำคัญที่ใช้ใน template ซึ่งก็มีรูปแบบที่ง่ายต่อการเขียน และง่ายต่อการลิ้ง url ไปยังฟังก์ชั่นต่างๆ ซึ่งตัวอย่างเช่น แก้ไขไฟร์ urls.py ใน directory project จาก
url(r'^polls/', include('polls.urls')),
เป็น
url(r'^polls/', include('polls.urls', namespace="polls")),
และแก้ไขไฟร์ polls/index.html จาก
<li><a href="{% url ’detail’ poll.id %}">{{ poll.question }}</a></li>
เป็น
<li><a href="{% url ’polls:detail’ poll.id %}">{{ poll.question }}</a></li>
ซึ่งจะทำให้ง่ายต่อการเรียกใช้และมีความยืดหยุ่นมากกว่า
สิ่งที่ได้เรียนรู้จาก tutorial part3
- ได้รู้ถึงวิธีการสร้างส่วนการแสดงผลของ Django app ซึ่งมีหลักการเหมือนกับการสร้างส่วนแสดงผลของไฟร์ project
- ได้รู้วิธีการนำส่วนการแสดงผลมาทำในรูปของ Template ใน Django app
- ได้รู้การทำส่วนแสดงผลให้แสดง question
- ได้รู้หลักการใช้ Http404
- การใช้ url ใน template
=======================================================================
tutorial part 4
part นี้จะพูดถึงการเขียน form ไว้ในไฟร์ html เพื่อเรียกไปแสดงผลผ่าน Django app และจะพูดถึงโค้ดส่วน view.py โดยจะทำการเขียนแยกเป็น class เพื่อความสะดวกในการเรียกใช้งาน และการเขียนโค้ดมากขึ้น
1. เริ่มจากการเขียน form โดยการสร้างไฟร์ template/polls/detail.html ทำการแก้ไขไฟร์
<h1>{{ poll.question }}</h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="polls.views.vote" method="post">
{% csrf_token %}
{% for choice in poll.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
{% endfor %}
<input type="submit" value="Vote" />
</form>
จากโค้ดเป็น form การแสดงผลโดยจะแสดงข้อความ question ตามด้วยข้อความ
You didn't select a choice. ตามด้วย choice ทั้งหมดให้เลือก และปุ่ม vote
2. ทำการแก้ไขไฟร์ poll/view.py เพื่อทำการเชื่อมต่อและเรียกใช้ form ที่ได้เขียนไว้ซึ่งจะทำการแก้ไขดังนี้
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
from polls.models import Choice, Poll
#....
def vote(request, poll_id):
p = get_object_or_404(Poll, pk=poll_id)
try:
selected_choice = p.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
# Redisplay the poll voting form.
return render(request, 'polls/detail.html', {'poll': p,
'error_message': "You didn't select a choice.",
})
else:
selected_choice.votes += 1
selected_choice.save()
# Always return an HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
return HttpResponseRedirect(reverse('polls:results', args=(p.id,)))
#....
ซึ่งจากโค้ดจะเป็นการสร้างส่วนของการ vote คือ render detail.html มาแสดงผล และเมื่อมีการ vote ก็จะมีการไป
Redirect url ไปยัง class resuits ซึ่ง results จะแสดงค่า vote ของแต่ละ choice และหน้า results จะมี Vote again? เพื่อลิ้งกลับมาหน้า detail
3. ทำการสร้างไฟร์ template/polls/results.html และแก้ไขดังนี้
<h1>{{ poll.question }}</h1>
<ul>
{% for choice in poll.choice_set.all %}
<li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
{% endfor %}
</ul>
<a href="{% url 'polls:detail' poll.id %}">Vote again?</a>
4. ทำการแก้ไข class results ใน polls/views.py
from django.shortcuts import get_object_or_404, render
def results(request, poll_id):
poll = get_object_or_404(Poll, pk=poll_id)
return render(request, 'polls/results.html', {'poll': poll})
เมื่อเข้าไปยัง url/poll/1/vote/ ก็จะได้ผลดังรูป
5. generic views เป็นอีกตัวช่วยหนึ่งของ django เป็น api ที่สร้างขึ้นเพื่อช่วยในการเขียนโค้ดใน views มีความเป็นระบบมากขึ้น ทำให้โค้ดอ่านง่ายและดูสั้น ง่ายต่อการแก้ไข ซึ่งตัวอย่างการใช้ generic เช่น ทำการแก้ไขไฟร์ polls/views.py ดังนี้
...
from django.views import generic
...
class IndexView(generic.ListView):
template_name = 'polls/index.html'
context_object_name = 'latest_poll_list'
def get_queryset(self):
"""Return the last five published polls."""
return Poll.objects.order_by(’-pub_date’)[:5]
class DetailView(generic.DetailView):
model = Poll
template_name = 'polls/detail.html'
class ResultsView(generic.DetailView):
model = Poll
template_name = 'polls/results.html'
def vote(request, poll_id):
....
จะเห็นได้ว่าการใช้ generice ต้องทำการ import generice แล้วทำการเขียนแยกเป็น class ซึ่งทำให้ดูง่ายขึ้น
ทำการแก้ไขไฟร์ polls/urls.py โดยแก้ไข url ตามรูปแบบ generice
from django.conf.urls import patterns, url
from polls import views
urlpatterns = patterns('',
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),
url(r'^(?P<pk>\d+)/results/$', views.ResultsView.as_view(), name='results'),
url(r'^(?P<poll_id>\d+)/vote/$', views.vote, name='vote'),
)
เมื่อมีการเข้าไปยัง url ที่ runserver ก็จะได้ผลเหมือนเดิม เหมือนกับตอนที่ไม่ได้ใช้ generice ซึ่งสามารถศึกษาเพิ่มเติมได้ในเอกสาร tutorial part 4 :
https://docs.djangoproject.com/en/dev/intro/tutorial04/
สิ่งที่ได้เรียนรู้จาก tutorial part4
- ได้รู้วิธีการประยุคต์ใช้ form ใน template
- วิธีการใช้ generic views
=======================================================================