วันเสาร์ที่ 14 ธันวาคม พ.ศ. 2556

คำจำกัดความ

    API คือ API หรือ Application Programming Interface มันคือ อะไรที่เป็นเหมือนกับ library  (function/module/utility) ที่องค์กร บริษัท หรือนักพัฒนาได้สร้างขึ้นมาทำงานอย่างใดอย่างหนึ่ง เพื่อให้นักพัฒนาอย่างเราๆ ไม่ต้องไปเขียนระบบหรือฟังชั่นส่วนนั้นเองมากมาย เป็นการลดความยุ่งยาก ซับซ้อน และน่าเบื่อของการพัฒนา ซึ่งจากสิ่งที่ผมเคยได้จับและสัมผัสกับ API หลายๆตัวมา ก็พบว่า ช่วยให้เราได้พัฒนา Application ได้ง่ายและรวดเร็ว เป็นระบบมากขึ้นด้วยครับ ซึ่งโดยสรุปแล้ว API ก็คือ Module/library ตัวหนึ่งที่เราสามารถนำมาพัฒนาร่วมกับ Application ของเราได้ โดยไม่ต้องเข้าใจหรือไปแตะต้อง code ของ API แค่รู้ว่าต้องทำงานยังไงกับ API นั้นก็พอหรือแค่รู้ว่า API นี้เราจะเอาไว้ใช้อะไรได้บ้าง และใช้ยังไงก็พอ

อ้างอิง : API


    Web application คือ ส่วนมากคนมักจะคุ้นเคยกับ Desk top Application หรือโปรแกรมคอมพิวเตอร์ที่ติดตั้งบนคอมพิวเตอร็์ส่วนบุคคล เช่น โปรแกรมพวก Microsoft Office เช่นโปรแกรมพิพม์งาน หรือ Word Processor ที่ใช้พิมพ์งาน ซึ่งจะติดตั้งบนเครื่องคอมพิวเตอร์ของคุณ  และใช้ได้ทีละคน หากทำงานที่บริษัทคุณจะคุ้นเคยกับโปรแกรมที่บริษัทใช้ เช่น ERP หรือ MRP หรือโปรแกรมห้องสมุด โปรแกรมพวกนี้มักจะเป็นโปรแกรมแบบ Client - Server คือ โปรแกรมที่ใช้งานโดยคนหลายๆคนพร้อมๆกัน มีการเก็บข้อมูลไว้ที่ฐานข้อมูลกลาง ทำให้ทุกคนใช้ข้อมูลเดียวกัน ร่วมกันได้ โดยโปรแกรมจะถูกแบ่งออกเป็นสองส่วนคือส่วนหนึ่งถูกติดตั้งที่ Server ส่วนกลาง และอีกส่่่่วนติดตั้งที่คอมพิวเตอร์ของผู้ใช้ หรือที่เรียกว่า Client ซึ่งทั้งสองส่วนจะทำงานร่วมกัน โดยโปรแกรมบน Server มักจะทำงานหลักๆ ที่จำเป็นเช่นการคำนวน การค้นหาข้อมูล การเก็บข้อมูล ส่วนโปรแกรมที่คอมพิวเตอร์ของเรา หรือที่เรียกว่า Client นั้นจะทำหน้าที่นำเสนอข้อมูล และรับข้อมูลจากผู้ใช้ หรือที่เรียกว่าเป็น User Interface โปรแกรมแบบนี้ซับซ้อนและดูแลยาก เพราะหากคุณ Upgrade โปรแกรมที่ Server คุณก็ต้อง Upgrade โปรแกรมที่ Client ด้วย ซึ่งเป็นเรื่องที่น่าปวดหัวเนื่องจาก Client มีหลายเครื่อง ยากที่ Upgrade ได้ครบ  ในระยะหลังๆนี้คุณคงได้ยินโปรแกรมอีกประเภทที่ได้รับความนิยมมากขึ้นโปรแกรมนั้นก็คือ Web Application เป็นโปรแกรมที่ติดตั้งที่ Server  ซึ่ง Web Application สามารถใช้งานแทนโปรแกรมทั้งแบบ  Desktop และแบบ Client - Server เช่น โปรแกรม Google Application ซึ่งใช้แทน Microsoft Office เช่นมีทั้ง Word Processor และหรือ Spread Sheet ที่ใช้แทน Excel โดยเฉพาะโปรแกรมแบบ Client-Server หลายตัวก็กำลังแปลงตัวเป็น Web Application เพื่อตอบสนองความต้องการของลูกค้า เช่น SAP, Lotus Notes ฯลฯ ข้อดีของ Web Application ตรงที่ Web Application ไม่ต้องใช้ Client Program ทำให้ไม่ต้อง Upgrade Client Program และสามารถใช้ผ่าน Internet Connection ที่มีความเร็วต่ำกว่า ทำให้ใช้โปรแกรมได้จากทุกแห่งในโลก

อ้างอิง : Web application


    Framework คือ เฟรมเวิร์ก (Framework) หรือ โครงร่างซอฟต์แวร์ เป็นขอบเขตของระบบงาน ที่เป็นรูปแบบที่นำกลับมาใช้ใหม่ได้สำหรับระบบซอฟต์แวร์ (หรือระบบย่อย) ซึ่งสามารถอยู่ในรูปของคลาสนามธรรม (Abstract class) และกับวิธีในการใช้ตัวตน (instance) ของคลาสร่วมกันจำเพาะสำหรับซอฟต์แวร์ชนิดใดชนิดหนึ่ง โครงร่างซอฟต์แวร์ทุกโครงร่างใช้การออกแบบเชิงวัตถุ(Object-oriented programming, OOP) 
    โปรแกรมของโครงร่างซอฟต์แวร์มักจะเป็นโปรแกรมเชิงวัตถุ และ PHP Framework ในปัจจุบัน ส่วนใหญ่อยู่ภายใต้แนวคิด MVC (Model-view-controller) 
ตัวอย่าง PHP Framework เช่น 

  • Zend Framework 
  • CodeIgniter
  • Seagull
  • CakePHP
  • Symfony
  • ZooP
  • ...

อ้างอิง : Framework

วันอังคารที่ 10 ธันวาคม พ.ศ. 2556

สรุป Django W6-2

Apps คือ ส่วนที่จะสร้างไฟล์ database เพื่อเก็บข้อมูลต่างๆไว้
  • การสร้างโมเดล หรือ คลาสเพื่อใช้ในการเก็บข้อมูล
  • การเพิ่ม app ใน INSTALL_APPS
  • การสร้างไฟล์ database และ super user
  • การสร้างออปเจ็ค
  • การแก้ไขข้อมูลในออปเจ็ค
  • การดูออปเจ็คทั้งหมดของคลาส
     ดูรายละเอียด Model ที่นี่

Admin คือ ส่วนที่จะจัดการหน้าของ admin
  • การเข้าหน้า admin
  • การแสดง object ของ class ใน admin
  • การแก้ไขการแสดงผลของ attribute
  • รูปแบบการแสดงลำดับของ object
  • รูปแบบการแยกกรอบข้อมูล
  • รูปแบบการ ซ่อน/โชว์ ข้อมูล
  • การใช้งานความสัมพันธ์ระหว่าง object
  • รูปแบบการแสดงแบบ StackInline และ TabularInline
  • การใช้งาน list_display
  • การใช้งาน list_filter
  • การใช้งาน search_fields
     ดูรายละเอียด Admin ที่นี่

URL & TEMPLATE
    URL คือ ส่วนที่ใช้จัดการ url ต่างๆ
    Template คือ การแยกส่วนแสดงผลออกจากส่วนของ code python
  • การแสดงข้อความออก browser
  • การ include url จาก app 
  • การตั้งชื่อ url และการรับข้อมูลจาก url
  • การแสดงข้อมูลล่าสุด 5 ลำดับแรก
  • การอ้างถึงที่อยู่ Template directory
  • การใช้ if และ for ใน template
  • การเรียกใช้ และ การใช้งาน template
  • การใช้ Shortcut: render()
  • การใช้ 404 error
  • การใช้ Shortcut: get_object_or_404()
  • การ Removing hardcode
  • การใช้งาน Namespacing url
     ดูรายละเอียด URL & TEMPLATE ที่นี่

Form คือ ส่วนที่ใช้จัดการเก็บข้อมูลจากผู้ใช้
  • การใช้ form ใน template
  • การใช้ Generic View
     ดูรายละเอียด Form ที่นี่

วันอาทิตย์ที่ 8 ธันวาคม พ.ศ. 2556

การจัดการและการใช้งาน Form (Tutorial part 4)

    ใน tutorial part 4 นี้จะเป็นเนื้อหาเกี่ยวกับการใช้งาน form ซึ่ง form จะถูกใช้งานก็ต่อเมื่อต้องการจะเก็บข้อมูลจากผู้ใช้ ไม่ว่าจะเป็น ประวัติ การเข้าชมเว็บไซต์ และ อื่นๆอีกมากมาย

เริ่มต้นเราจะแก้ไขไฟล์ detail.html ที่อยู่ใน polls/templates/polls/ ตามนี้

<h1>{{ poll.question }}</h1>

{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}

<form action="{% url 'polls:vote' poll.id %}" 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>
    จาก code html ข้างบนจะเป็นการใช้ form สร้าง action โดยการเรียกใช้ฟังก์ชั่น vote จาก app polls และจะมีการวน for เพื่อทำการดึงค่า choice ทั้งหมดออกมา


<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
เป็นการสร้าง input แบบให้เลือกติ๊ก


<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
label คือ text ที่ใช้แสดงข้อมูลของ string 


<input type="submit" value="Vote" />
เป็นการสร้างปุ่มกด โดยจะมีข้อความบนปุ่มกดว่า Vote

จากนั้นให้ทำการแก้ไขฟังก์ชั่น vote ที่อยู่ใน polls/views.py ๖ามนี้

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()
        return HttpResponseRedirect(reverse('polls:results', args=(p.id,)))
จาก code
p = get_object_or_404(Poll, pk=poll_id)
เป็นการใช้ shortcut 404 error

selected_choice = p.choice_set.get(pk=request.POST['choice'])
เป็นการดึงค่า object จาก choice โดย request.POST เป็น dictionary โดยรับ key คือ choice ไปแล้วจะ return string ของ value กลับมา

selected_choice.votes += 1
selected_choice.save()
เป็นการเพิ่มค่า vote ไป 1 แล้วทำการ save ข้อมูล


return HttpResponseRedirect(reverse('polls:results', args=(p.id,)))
เป็นการ ส่งข้อมูลโดยตรงไปยังฟังก์ชั่น results

เมื่อลองเทสจะได้ผลลัพธ์ดังนี้
ต่อไปจะทำการแก้ไขฟังก์ชั่น 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})
จาก code ข้างบน จะสังเกตุได้ว่าเหมือนตอนแก้ไขฟังก์ชั่น detail ใน Tutorial part 3 

จากนั้นให้ทำการสร้างไฟล์ results.html ไว้ใน polls/templates/polls/ แล้วเขียน code ตามนี้

<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>
จาก code html ข้างบน จะเป็นการวน for เพื่อจะดึงข้อมูล choice ทั้งหมดออกมา เพื่อแสดงค่า โหวตของ choice


<a href="{% url 'polls:detail' poll.id %}">Vote again?</a>
เป็นการแสดง link ชื่อว่า Vote again? เมื่อทำการคลิก จะเรียกใช้ฟังก์ชั่น detail เพื่อทำการโหวตอีกครั้ง เมื่อทำการเทส จะได้ผลลัพธ์ดังนี้

ต่อไปจะเป็นการใช้ generic views
    การใช้ generic views นั้นจะทำให้ code สั้นลงมาก โดยการเปลี่ยนฟังก์ชั่นใน views.py ทั้งหมดเป็น class โดยเริ่มต้นเราจะทำการแก้ไขไฟล์ polls/urls.py ตามนี้

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'),
)
    จาก code ข้างต้น จะเปลี่ยนจาก view.index เป็น view.IndexView.as_view() เพื่อจะทำการเรียกใช้ class IndexView และเปลี่ยนจาก poll_id เป็น pk ในส่วนของ detail และ result เพราะว่าทั้งสอง class นี้จะใช้ generic views แบบ DetailView ซึ่งสามารถรองรับข้อมูลเป็น pk(primary key) ได้เลย ในส่วนของ vote นั้นเราจะไม่ทำการเปลี่ยนแปลงใดๆเพราะว่ายังใช้เป็น ฟังก์ชั่นเหมือนเดิม

ต่อไปเราจะทำการแก้ไขไฟล์ polls/views.py ตามนี้

from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.views import generic

from polls.models import Choice, Poll

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):
    ....

    จาก code จะเห็นได้ว่าจะเปลี่ยนจาก def index, def detail, def results มาเป็น class IndexView, class DetailView, class ResultsView และภายใน class นั้นจะสั้นลงมากโดย

template_name = 'polls/index.html'
เป็นการระบุไฟล์ template 

context_object_name = 'latest_poll_list'
เป็นการกำหนดชื่อ tag ของ template ที่ต้องการ context 

def get_queryset(self):
        """Return the last five published polls."""
        return Poll.objects.order_by('-pub_date')[:5]
ฟังก์ชั่นนี้สร้างมาเพื่อแสดงค่าของ object ในเวลา 5 ลำดับล่าสุด

model = Poll
เป็นการกำหนดเลือกใช้ Model ที่ต้องการ 

class IndexView(generic.ListView):
เป็นการระบุว่าใช้ generic views แบบ ListView


class DetailView(generic.DetailView):
class ResultsView(generic.DetailView):
เป็นการระบุว่าใช้ generic views แบบ DetailView

    จากบทความนี้ จะสอนให้รู้จักการใช้ form ได้เข้าใจเกี่ยวกับ generic views ที่ทำให้ code สั้นลง

ข้อมูลอ้างอิง : Tutorial part 4

วันอาทิตย์ที่ 1 ธันวาคม พ.ศ. 2556

การจัดการ URL และ Template (Tutorial part 3)

    ใน tutorial part 3 นี้จะกล่าวถึงการจัดการและการใช้งาน URL และ Template เป็นหลักโดยเริ่มต้นนั้นให้เราแก้ไขไฟล์ใน polls/views.py โดยใส่ code ตามนี้

from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello, world. You're at the poll index.")
จาก code เป็นการสร้างฟังก์ชั่นเพื่อส่งข้อความออก Browser ปกติ

จากนั้นทำการสร้างไฟล์ urls.py ขึ้นมาในโฟลเดอร์ polls แล้วทำการเขียน code ตามนี้ 

from django.conf.urls import patterns, url

from polls import views

urlpatterns = patterns('',
    url(r'^$', views.index, name='index')
)
จาก code เป็นการตั้งหน้า default โดยเรียกใช้ฟังก์ชั่น index จากไฟล์ views

ต่อไปเราจะทำการแก้ไขไฟล์ urls.py ของโปรเจ็ค โดยทำการเขียน code ตามนี้

from django.conf.urls import patterns, include, url

from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    url(r'^polls/', include('polls.urls')),
    url(r'^admin/', include(admin.site.urls)),
)
จาก code เมื่อมีการเข้า url http://127.0.0.1:8000/polls/ ก็จะทำการเรียกไฟล์ polls/urls.py และจะได้ output ดังนี้
ต่อไปเราจะทำการเพิ่มฟังก์ชั่น detail, result, vote เข้าไปในไฟล์ polls/views.py ตามนี้

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)
 
โดยฟังก์ชั่น detail สร้างมาเพื่อโชว์รายละเอียดของ poll
                result สร้างมาเพื่อโชว์ผลรับของ poll
                vote สร้างมาเพื่อแสดงผลโหวตของ poll 

ต่อไปเราจะทำการแก้ไขไฟล์ polls/urls.py โดยเขียน code ตามนี้

from django.conf.urls import patterns, url

from polls import views

urlpatterns = patterns('',
    url(r'^$', views.index, name='index'),
    url(r'^(?P<poll_id>\d+)/$', views.detail, name='detail'),
    url(r'^(?P<poll_id>\d+)/results/$', views.results, name='results'),
    url(r'^(?P<poll_id>\d+)/vote/$', views.vote, name='vote'),
)
จาก code เราเพิ่มขึ้นมา 3 บรรทัด โดย

url(r'^(?P<poll_id>\d+)/$', views.detail, name='detail'),
    เป็นการรับข้อมูลตัวเลขมาใส่ไว้ใน poll_id และเรียกใช้ฟังก์ชั่น detail จาก views
ตัวอย่างการเรียกใช้ url นี้ เช่น /polls/5

url(r'^(?P<poll_id>\d+)/results/$', views.results, name='results'),
    เป็นการรับข้อมูลตัวเลขมาใส่ไว้ใน poll_id และเรียกใช้ฟังก์ชั่น results จาก views
ตัวอย่างการเรียกใช้ url นี้ เช่น /polls/5/results

url(r'^(?P<poll_id>\d+)/vote/$', views.vote, name='vote'),
    เป็นการรับข้อมูลตัวเลขมาใส่ไว้ใน poll_id และเรียกใช้ฟังก์ชั่น vote จาก views
ตัวอย่างการเรียกใช้ url นี้ เช่น /polls/5/vote

ต่อไปเราจะทำการแก้ไขฟังก์ชั่น index และใช้ API ในไฟล์ polls/views.py ตามนี้

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)
    จาก code ได้ใช้ API objects.order_by()[] โดยดึง object แล้วทำการ sort โดยวันที่ล่าสุด 5 ลำดับมาเก็บไว้ในตัวแปร latest_poll_list และมาทำการวน for เพื่อดึงข้อมูล question จาก object ที่เก็บไว้ในตัวแปร latest_poll_list และนำมาต่อกันเพื่อเก็บไว้ในตัวแปร output และแสดงออกบน browse
และเมื่อทำการ refresh หน้า default ก็จะแสดงรายชื่อ question 5 ลำดับแรกที่เรียงตามเวลาขึ้นมาดังนี้
จากภาพเนื่องจากมีเพียง 1 question จึงแสดงแค่อย่างเดียว

    ต่อไปเราจะทำการสร้าง template โดยเริ่มต้นนั้นให้เราสร้างโฟลเดอร์ templates ไว้ในโฟลเดอร์ polls แล้วเราจะทำการสร้างไฟล์ index.html ไว้ใน polls/templates/polls/ ที่เราสร้างโฟลเดอร์ polls มาอีกชั้นนั้น เพื่อให้เกิดความง่ายในการเรียกใช้ และป้องกันการสับสนหากมีการสร้าง app มากกว่า 1 app ส่วนเวลาเราจะเรียกใช้เราสามารถอ้างถึงได้ง่ายๆเช่น poll/index.html

เริ่มแรกเราจะทำการเพิ่ม code เข้าไปในไฟล์ settings.py ตามนี้

TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'templates')]
เป็นการกำหนด Directory path ของไฟล์ template เข้าไป

จากนั้นเราจะทำการเขียน code ในไฟล์ 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 %}
    จาก code html จะเป็นการเช็ค latest_poll_list ก่อนจากนั้นจะมาวน latest_poll_list เพื่อจะแสดง link เป็นชื่อ question และเมื่อทำการคลิกจะทำการเรียก url ของฟังก์ชั่น detail เพื่อแสดงรายละเอียด

ต่อไปเราจะทำการแก้ไขฟังก์ชั่น index ในไฟล์ polls/views.py ตามนี้

from django.http import HttpResponse
from django.template import RequestContext, loader

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))
    จาก code จะมีการเรียกใช้ template โดยทำการ load template มาจาก poll/index.html และจะทำ context ค่า latest_poll_list ใส่เข้าไปใน template แล้วดึงค่าจาก template ส่งออกไปให้ browser แล้วเราจะได้ผลลัพธ์ดังนี้
ต่อไปจะเป็นการใช้ Shortcut: render()
โดยที่ shortcut: render() นั้น เป็นการย่อ render ให้สั้นลง โดยเราจะแก้ไขฟังก์ชั่น index ใน polls/views.py ตามนี้

from django.shortcuts import render

from polls.models import Poll

def index(request):
    latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5]
    context = {'latest_poll_list': latest_poll_list}
    return render(request, 'polls/index.html', context)
จาก code จะเห็นได้ว่าสั้นลงกว่าเดิมแต่ความหมายและผลลัพธ์เหมือนเดิม

ต่อไปจะเป็นการใช้ 404 error
    404 error คือการเรียกหาหน้าเว็บไซต์นั้นๆไม่เจอ หากไม่ใช้เมื่อเกิด error ขึ้น browser จะแสดง code ยืดยาวอาจจะทำให้ผู้ใช้สับสนได้ โดยเราจะแก้ไขฟังก์ชั่น detail ใน polls/views.py ตามนี้

from django.http import Http404
from django.shortcuts import render

from polls.models import Poll
# ...
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})
จาก code จะทำการดึงค่า pk มาเพื่อเทียบกับ poll_id หากไม่เจอจะทำการเรียกใช้ Http404

    ต่อไปเราจะสร้างไฟล์ detail.html ไว้ใน polls/templates/polls/ โดยเราจะเขียน code เพียงแค่ {{ poll }} เพื่อที่จะใช้ทดสอบ 404 error การทดสอบ เราจะทำการเข้า http://127.0.0.1:8000/polls/ ปกติ แล้วทำการคลิกจะใช้งานได้ปกติ จากนั้น ให้เราทำการเปลี่ยนตัวเลขของ url ให้เป็น id ที่ไม่มีใน database เช่น http://127.0.0.1:8000/polls/20/ แล้วจะโชว์หน้า 404 error ดังนี้

ต่อไปจะเป็นการใช้ Shortcut: get_object_or_404()
โดยที่ Shortcut: get_object_or_404() นั้น จะเป็นการใช้ 404 error แบบย่อ โดยเราจะทำการแก้ไขฟังก์ชั่น detail ในไฟล์ polls/views.py ตามนี้

from django.shortcuts import render, get_object_or_404

from polls.models import Poll
# ...
def detail(request, poll_id):
    poll = get_object_or_404(Poll, pk=poll_id)
    return render(request, 'polls/detail.html', {'poll': poll})
จะเห็นได้ว่า code สั้นลงแต่ยังมีความหมายและผลลัพธ์ เหมือนเดิม

ต่อไปจะเป็นการใช้ template system
โดยเราจะทำการแก้ไขไฟล์ detail.html ใน polls/templates/polls/ โดยเขียน code ตามนี้

<h1>{{ poll.question }}</h1>
<ul>
{% for choice in poll.choice_set.all %}
    <li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>
จาก code html ข้างต้น จะเป็นการวน for ใน object choice_set ทั้งหมด เพื่อที่จะนำค่า choice ทั้งหมดมาแสดง จะได้ผลลัพธ์ดังนี้

ต่อไปจะเป็นการ Removing hardcode
โดยเราจะทำการแก้ไขไฟล์ index.html ตามนี้

โดยของเก่าจะเป็น 
<li><a href="/polls/{{ poll.id }}/">{{ poll.question }}</a></li>

ให้แก้ไขใหม่เป็น
<li><a href="{% url 'detail' poll.id %}">{{ poll.question }}</a></li>
    จะเห็นได้ว่าจากการอ้างอิง path จะเปลี่ยนเป็นการใช้ url แทน และสามารถกำหนดฟังก์ชั่นของ url ได้ โดยตรง หาก path ของ url ยาวมากกว่านี้ แบบเก่าอาจจะเป็นส่วนที่ยุ่งยากได้

ต่อไปเป็นการใช้งาน Namespacing URL name
ซึ่งเป็นการให้ Django รู้ว่าเรียกใช้ url ใหนหากมีชื่อ url เหมือนกันในคนละ app
โดยเราจะทำการแก้ไขไฟล์ urls.py ของโปรเจ็ค โดยเขียน code ตามนี้

from django.conf.urls import patterns, include, url

from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    url(r'^polls/', include('polls.urls', namespace="polls")),
    url(r'^admin/', include(admin.site.urls)),
)
    จาก code จะเห็นได้ว่า เราได้ทำการเพิ่ม namespace="polls" เข้าไปด้านหลังเพื่อระบุว่าตั้งชื่อ namespace ว่า polls

จากนั้นเราจะทำการแก้ไขไฟล์ index.html ที่อยู่ใน polls/templates/polls/

โดยของเก่าจะเป็นดังนี้
<li><a href="{% url 'detail' poll.id %}">{{ poll.question }}</a></li>

ให้แก้ไขใหม่เป็นดังนี้
<li><a href="{% url 'polls:detail' poll.id %}">{{ poll.question }}</a></li>
    จาก code จะเห็นได้ว่าเราได้ใส่ polls: ไปข้างหน้า detail เพื่อบอกให้รู้ว่าจะทำการเรียกใช้ url detail ของ namespace ที่ชื่อว่า polls ซึ่งในที่นี้ก็คือ url ของ app polls

    ในบทนี้จะทำให้เราเข้าใจและได้รู้เกี่ยวกับการใช้ URL และ TEMPLATE มากขึ้น

ข้อมูลอ้างอิง : Tutorial part 3

การจัดการหน้า admin (Tutorial part 2)

    ในบทความนี้จะเป็นการจัดการในส่วนของ admin โดยต่อจากบทความที่แล้ว โดยที่ในบทความที่แล้วในตอนสร้าง super user เราต้องพิมพ์ yes เพื่อสร้าง super user ขึ้นมาเพื่อจะใช้ user และ password ในการจัดการในส่วนของ admin ผมจะทำตาม tutorial part2

เริ่มต้นให้ทำการ runserver ด้วยคำสั่ง python manage.py runserver เมื่อทำการ runserver แล้วให้เข้าเว็บด้วย http://127.0.0.1:8000/admin/
จากนั้นให้ทำการใส่ user และ password ตามที่เรากำหนดตอนสร้าง super user เมื่อ login เรียบร้อยแล้วเราจะเห็นหัวข้อ Auth เท่านั้น เราจึงจะทำการแก้ไขไฟล์ admin.py
จาก code ที่เราเพิ่งไปนั้นเป็นการดึง object จากไฟล์ models.py มาเพื่อสร้าง table เข้าไป เมื่อลองทำการ reload หน้า admin เราจะเห็น หัวข้อ Polls ขึ้นมา ถ้าคลิกเข้าไปเราจะเห็นว่ามีการสร้างข้อมูลแล้ว 1 อย่าง(ถ้าหากได้ทดลองด้วย python shell มาแล้ว)
ต่อไปจะเป็นการเปลี่ยนรูปแบบการแสดงในหน้า admin
เปลี่ยนรูปแบบเป็นการสลับเอา pub_date ขึ้นมาแสดงก่อน question โดยลำดับจะขึ้นอยู่กับ object ภายใน list ของ fields ที่กำหนดไว้
เปลี่ยนรูปแบบเป็นการแยกกรอบข้อมูล โดยใช้ fieldsets จากตัวอย่างกรอบแรกไม่มีชื่อกรอบซึ่งจะแสดงข้อมูลของ question ส่วนกรอบที่สองมีชื่อกรอบว่า  Date Information โดยแสดงข้อมูลของ pub_date
เป็นการซ่อนหรือโชว์ข้อมูลภายในกรอบ โดยเพิ่ม 'classes': [collapse] เข้าไปท้าย list ของ fields
จากรูปเป็นการแสดงความสัมพันธ์ระหว่าง class Poll และ Choice ในการสร้างข้อมูล
เป็นการเปลี่ยนการแสดง โดยเปลี่ยนคำสั่งจาก StackInline เป็น TabularInline โดยที่ StackInline เป็นการแสดง object คนละบรรทัดกัน
TabularInline เป็นการแสดง object ในบรรทัดเดียวกัน

ต่อไปเป็นการเปลี่ยนการเพิ่ม list การแสดงแต่ละแบบ
list_display เป็นการแสดงข้อมูลของ object ที่ต้องการแสดงเป็นลำดับตาม list ที่กำหนด
list_filter เป็นการแสดง filter ด้านขวา โดยจากตัวอย่างเขาดูจาก pub_date
search_fields เป็นการค้นหาข้อความ โดยจากตัวอย่างค้นหาจาก question

    ใน Tutorial part 2 นี้จะสอนให้เราเข้าใจเกี่ยวกับการจัดการหน้าตาในหน้าของ admin ให้ดูสวยงาม ตามที่เราต้องการได้

ข้อมูลอ้างอิง : Django Document