ค้นหาบล็อกนี้

วันอาทิตย์ที่ 23 กุมภาพันธ์ พ.ศ. 2557

Django Book ตอนที่ 3 การใช้งาน Template



Template Loading
                ในตอนนี้เราจะลองใช้ template ในการแสดงผลหน้าเว็บเพจแทนการนำโค้ด python กับโค้ด html ไปรวมกันในไฟล์ views.py เพียงอย่างเดียว  โดยให้เราสร้าง directory ใหม่ชื่อว่า templates ใน directory ของโปรเจ็ค  แล้วเพิ่มโค้ดและแก้ไขฟังก์ชัน current_datetime ดังนี้

 
from django.template.loader import get_template
from django.template import Context
from django.http import Http404, HttpResponse
import datetime

def current_datetime(request):
now = datetime.datetime.now()
               t = get_template('current_datetime.html')
               html = t.render(Context({'current_date': now}))
               return HttpResponse(html)
เสร็จแล้วให้เพิ่มโค้ดต่อไปนี้ในไฟล์ settings.py
TEMPLATE_DIRS = (
    os.path.join(BASE_DIR, 'templates'),
)
ให้สร้าง template ชื่อว่า current_datetime.html ใน directory ชื่อ templates ที่สร้างขึ้นในตอนแรก  แล้วแก้ไขโค้ดใน template ที่สร้างขึ้นใหม่ดังนี้
<html><body>It is now {{ current_date }}.</body></html>
                เมื่อทำการแก้ไขโค้ดเสร็จสิ้นตามที่ผ่านมาแล้ว  หากเปิด browser แล้วไปที่ 127.0.0.1:8000/time จะพบการแสดงผลวันเวลาปัจจุบันในลักษณะเหมือนเดิม  แต่ตอนนี้โค้ด python กับโค้ด html ได้แยกกันอย่างชัดเจนแล้วซึ่งจะมีส่วนช่วยให้เราสามารถพัฒนาหน้าเว็บได้สะดวกมากยิ่งขึ้น

render_to_response()
                เราจะลองใช้ render_to_response() แทนการเรียกใช้ template แบบเดิมเพื่อทำให้โค้ดดูสั้นลง  โดยแก้ไขโค้ดในฟังก์ชัน current_datetime ดังนี้
from django.shortcuts import render_to_response
import datetime

def current_datetime(request):
               now = datetime.datetime.now()
               return render_to_response('current_datetime.html', {'current_date': now})
                เมื่อเราแก้ไขโค้ดแล้วจะพบว่าการแสดงผลหน้าเว็บเพจจะไม่มีการเปลี่ยนแปลงใดๆ แต่จะทำให้โค้ดในฟังก์ชัน current_datetime นั้นดูสั้นลง

The locals() Trick
                เราจะลองใช้คำสั่ง locals() แทนตัวแปร now ในฟังก์ชัน current_datetime โดยเราจะต้องตั้งชื่อตัวแปรในฟังก์ชันให้มีชื่อเดียวกันกับตัวแปรใน template โดยทำการแก้ไขโค้ดในฟังก์ชัน current_datetime ดังนี้
def current_datetime(request):
               current_date = datetime.datetime.now()
                return render_to_response('current_datetime.html', locals())
                ข้อดีของการใช้ locals() ก็คือถ้าหากว่าเรามีตัวแปรหลายๆ ตัว  จะช่วยทำให้โค้ดเราดูสั้นลงและมีความสะดวกขึ้นกว่าการใช้ Context  แต่ข้อเสียของการใช้ locals() ก็คือเราจะต้องตั้งชื่อตัวแปรที่เราต้องการให้ตรงกับชื่อตัวแปรใน template ด้วย

Template Inheritance
                ในตอนนี้เราจะลองเปลี่ยนฟังก์ชัน hours_ahead มาใช้รูปแบบการแสดงผลแบบ template เหมือนกับในฟังก์ชัน current_datetime โดยสร้าง template ใหม่ที่ชื่อว่า hours_ahead.html ใน directory ของ templates และทำการแก้ไขโค้ดดังต่อไปนี้
<html lang="en">
    <head>
        <title>Future time</title>
    </head>
    <body>
        <h1>My helpful timestamp site</h1>
        <p>In {{ hour_offset }} hour(s), it will be {{ next_time }}.</p>
       
        <hr>
        <p>Thanks for visiting my site.</p>
    </body>
</html>
                เสร็จแล้วให้ทำการแก้ไขโค้ดในฟังก์ชัน hours_ahead ดังต่อไปนี้
def hours_ahead(request, offset):
try:
hour_offset = int(offset)
except ValueError:
raise Http404()
next_time = datetime.datetime.now() + datetime.timedelta(hours=hour_offset)
return render_to_response('hours_ahead.html', locals())
                ต่อมาเราจะแก้ไขโค้ดใน template ที่ชื่อ current_datetime เพื่อให้มีรูปแบบการแสดงผลหน้าเว็บเพจในรูปแบบเดียวกันกับหน้าเว็บเพจ hours_ahead.html  โดยทำการแก้ไขโค้ดดังต่อไปนี้
<html lang="en">
    <head>
        <title>The current time</title>
    </head>
    <body>
        <h1>My helpful timestamp site</h1>
        <p>It is now {{ current_date }}.</p>
       
        <hr>
        <p>Thanks for visiting my site.</p>
    </body>
</html>
               
หลังจากที่เราได้สร้าง template เพื่อแสดงผลหน้าเว็บเพจทั้งสองหน้าแล้ว  จะพบว่าในทั้งสอง template จะมีบางส่วนที่คล้ายๆ กัน  ซึ่งเราสามารถที่จะสร้าง template มาใหม่เพื่อเป็น template ของ template อีกทีหนึ่ง  โดยใน template ใหม่นี้จะสร้างส่วนที่เหมือนกันของแต่ละ template เอาไว้เพื่อให้แต่ละ template เรียก template ใหม่นี้ไปใช้งาน  วิธีการทำคือให้สร้าง template ใหม่ที่มีชื่อว่า base.html แล้วแก้ไขโค้ดดังต่อไปนี้
<html lang="en">
    <head>
        <title>{% block title %}{% endblock %}</title>
    </head>
    <body>
        <h1>My helpful timestamp site</h1>
        {% block content%}{% endblock %}
        {% block footer %}
            <hr>
            <p>Thanks for visiting my site.</p>
        {% endblock %}
    </body>
</html>
                ต่อมาให้ทำการแก้ไขโค้ดใน template ชื่อ current_datetime.html ดังนี้
{% extends "base.html" %}

{% block title%}The current time{% endblock %}

{% block content %}
    <p>It is now {{ current_date }}.</p>
{% endblock %}
                เสร็จแล้วทำการแก้ไขโค้ดใน template ชื่อ hours_ahead.html ดังนี้
{% extends "base.html" %}

{% block title %}Future time{% endblock %}

{% block content %}
    <p>In {{ hour_offset }} hour(s), it will be {{ next_time }}.</p>
{% endblock %}
                การแก้ไขโค้ดดังกล่าว template ที่ชื่อว่า base.html จะเป็น template ที่สร้างหน้าเว็บเพจที่เราต้องการให้ลักษณะที่เหมือนๆ กัน  ในส่วนที่แตกต่างกันเราจะใช้ block เข้ามาช่วย เพื่อให้ในแต่ละ template กำหนดลักษณะเฉพาะของหน้าเว็บเพจในส่วนที่แตกต่างกันของแต่ละ template ที่สืบทอดไปใช้งาน

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

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