สนุกกับ Active Record ภาค Grails : ค้น, ค้น, ค้น
Posted September 11, 2008 at Grails66สกัดบทสนทนาจาก Twitter ด้วย Groovy
Posted September 10, 2008 at Grails66มาดูการจัดการ GORM Relationship แบบ 1 ต่อ 1
Posted September 10, 2008 at Grails66สนุกกับ ActiveRecord ภาคเกรลส์
Posted September 10, 2008 at Grails66มาดูการจัดการ GORM Relationship แบบ One-to-Many
Posted September 15, 2008 at Grails66Comet กับ ZKGrails ใน 30 บรรทัด
Posted September 15, 2008 at Grails66Groovy Category ใช้งานยังไง ??
Posted September 16, 2008 at Grails66เขียน Groovy DSL โดยกิลโยม ลาฟอร์จ ที่ JavaZone
Posted September 17, 2008 at Grails66หัดเล่น method_missing ใน Groovy Version
Posted September 19, 2008 at Grails66มาสร้าง app สำหรับอัพโหลดรูปกัน (2)
Posted September 19, 2008 at Django66เรามาต่อจากตอนแรกกันครับ ในตอนนี้เราจะสร้าง view และ template สำหรับแสดงรูปที่ upload มาครับ <!--break--> ผมคงไม่ลงรายละเอียดขั้นตอนมาก เอาเป็นดูเพิ่มได้จาก entry 1 2 3 ที่ sugree เขียนไว้นะครับ
มาตั้งค่าเกี่ยวกับไดเรกทอรีของ template กับจัดการตั้งค่า URL dispatcher (routing) กันก่อน
เราจะใช้ template โดยเราจะเก็บไว้ที่ youpics/templates ดังนั้นไปเพิ่มไดเรกทอรีดังกล่าวใน settings.py
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
"/พาธเต็ม/youpics/templates",
)
แล้วก็ไปตั้งค่า URL ในไฟล์ urls.py
เราจะเขียนฟังก์ชัน index ในโมดูล pictures.views ให้จัดการกับการเรียกหน้าหลักของเรา ดังนั้นเราจะไปเพิ่มบรรทัด
เข้าไปในรายการของ urlpatterns
พอตั้งค่าเรียบร้อยแล้ว ก็ได้เวลามาเขียน view และ template กันครับ
เดี๋ยวใน view เราจะโหลดวัตถุจากโมเดล Picture มา แล้วโยนให้ template นั้นแสดงผลครับ
เข้าไปแก้โค้ดใน pictures/views.py ก่อนเลยดีกว่าครับ
from django.shortcuts import render_to_response
def index(request):
pics = Picture.objects.all()
return render_to_response("index.html",{'pictures': pics})
เราจะใช้โมเดลที่นิยามไว้ในไฟล์ models.py ในไดเร็กทอรี pictures ดังนั้นเราจึงสั่ง import จากโมดูล pictures.models ครับ
ส่วนในการเรียกให้แสดง template นั้น เราจะใช้ฟังก์ชันลัดชื่อ render_to_response เพื่อเรียกให้แสดงผล พร้อม ๆ กับส่งพารามิเตอร์เข้าไปใน template ครับ ดังนั้น ก็ต้อง import มาก่อนเช่นเดียวกัน
ในการเรียกค้นวัตถุในโมเดลใด ๆ เราจะทำผ่าน "ผู้จัดการ" (Manager) ของโมเดลนั้น ที่เข้าถึงได้ทางคลาสของโมเดลนั้น โดยทั่วไปแล้วผู้จัดการจะถูกตั้งชื่อว่า objects
ฟังแล้วดูยาก พิจารณาโปรแกรมด้านบน ในบรรทัด
เราเรียกเมท็อด all จาก Picture.objects ซึ่งเป็นผู้จัดการของโมเดล Picture ดังนั้น เราก็จะได้วัตถุทั้งหมดคืนมาเป็น QuerySet ซึ่งคิดง่าย ๆ (ตอนนี้) ว่าเป็นลิสต์ก็ได้
จากนั้นเราเรียก render_to_response ให้ไป render ตัว template ในไฟล์ index.html โดยส่ง pics ที่ค้นมาได้เข้าไปเป็นพารามิเตอร์ชื่อ pictures
(จริง ๆ แล้วผมอยากใช้ตัวแปร pictures ในการเก็บ QuerySet แต่ไม่อยากทำให้เข้าใจผิดว่าตัวแปรใน view จะต้องถูกส่งไปยัง template ด้วยชื่อเดียวกันครับ)
ทีนี้ไปเขียน template กัน
อย่างที่ sugree กล่าวไว้ ว่าภาษา template ของ django ไม่ใช่ xml ไม่ใช่ Python เป็นภาษาของตนเองครับ
ทีนี้ ทดลองดูจากตัวอย่างเลยครับ สร้างไฟล์ index.html ไว้ในไดเรกทอรี youpics/templates ตามด้านล่าง
{% for picture in pictures %}
<h3>{{ picture.title }}</h3>
{% endfor %}
ใน template นะครับ อะไรที่อยู่เครื่องหมาย {{ วงเล็บปีกกาคู่ }} จะถูกมองว่าเป็นตัวแปร และค่าของมันจะถูกแทรกลงไปในข้อความที่ render ได้
ส่วนอะไรที่อยู่ในเครื่องหมาย {% ปีกกาและเปอร์เซ็นต์ %} จะถูกเรียกว่าเป็น template tag ซึ่งจะทำให้เราสามารถควบคุมการทำงานของ template ได้
ด้านบนเราระบุให้ตัวแปร picture วิ่งไปในรายการ pictures ด้วย template tag for ภายในลูป เราสั่งให้แสดง picture.title
ลองเรียก server มาดูผลลัพธ์กันครับ
ทีนี้เราจะทำให้มีการแสดงรูปครับ ใน ImageField ที่เราใช้เพื่อเก็บรูปนั้นมี attribute url ให้เราอ่านได้ ดังนั้นแก้ index.html เป็นดังด้านล่างครับ
{% for picture in pictures %}
<h3>{{ picture.title }}</h3>
<img src="{{ picture.image.url }}"/>
{% endfor %}
แล้วลอง refresh ที่บราวเซอร์ดูครับ น่าจะเห็นรูปแล้ว
ตอนหน้าเราจะมาทำ form สำหรับ upload รูปกันครับ
Simple Login Tutorial
Posted September 21, 2008 at Grails66มาสร้าง app สำหรับอัพโหลดรูปกัน (3)
Posted September 22, 2008 at Django66ต่อจากตอนที่แล้วนะครับ
ในตอนนี้เราจะหัดใช้ form ครับ ในตอนต้นเราจะเขียน form แบบธรรมดาเพื่อทดลองใช้ form และทดลองเก็บข้อมูลลงในโมเดล จากนั้นก่อนจะจบเราจะทดลองใช้ ModelForm ซึ่งทำให้การสร้างและใช้งานฟอร์มจากโมเดลทำได้ง่ายมากขึ้น <!--break--> Django มีโมดูล forms ที่ทำให้การเขียน form ที่ต้องมีการตรวจสอบข้อมูลทำได้สะดวกครับ
การใช้งานหลัก ๆ คือเราไปสร้างคลาสที่เป็นลูกหลานของ forms.Form วัตถุของคลาสดังกล่าว เมื่อนำไปแสดงใน template จะเผยตัวออกเป็น html form ที่สวยงาม จากนั้นเมื่อผู้ใช้ป้อนข้อมูลเข้ามาผ่านทาง form นั้น เราก็สามารถเอาเชื่อมข้อมูลที่ผู้ใช้ส่งมาจาก request เข้ากับวัตถุของ form เพื่อนำไปตรวจสอบความถูกต้องได้ เมื่อตรวจเสร็จเราก็จะมีข้อมูลที่เก็บกวาดแล้วไว้ใช้ (เรียกว่า cleaned_data)
เรามาประกาศ form สำหรับรับรูปกัน เพิ่มการประกาศนี้ไว้ที่ต้นไฟล์ pictures/views.py ครับ
class PictureForm(forms.Form):
title = forms.CharField(max_length=100)
description = forms.CharField(widget=forms.Textarea)
image = forms.ImageField()
สังเกตว่าคล้ายกับการประกาศโมเดลมากครับ ยกเว้นว่าไม่มี TextField แต่เราจะใช้ forms.CharField แทน แล้วระบุว่าในเวลาแสดงผลเป็น html ให้แสดงเป็น textarea โดยกำหนดค่า widget=forms.Textarea เจ้า widget นี่คือวัตถุที่ใช้จัดการแสดงผลแต่ละ field ใน template ครับ
มีฟอร์มแล้วก็ต้องส่งไปแสดงผลที่ template
เราจะให้ผู้ใช้ upload ได้ที่หน้าแรกเลย ดังนั้นไปแก้ฟังก์ชัน index กัน โดยเพิ่มให้มีการสร้างวัตถุของคลาส PictureForm ให้เป็นฟอร์มเปล่า ๆ แล้วโยนไปให้ template แสดงผล ผ่านทางตัวแปรชื่อ form
pics = Picture.objects.all().order_by('title')
form = PictureForm()
return render_to_response("index.html",{ 'pictures': pics,
'form': form })
จากนั้นไปแก้ template index.html จากคราวที่แล้วครับ
โดยเพิ่มส่วน form เข้าไปในตอนต้นครับ
{{ form.as_p }}
<input type="submit" value="Upload"/>
</form>
สังเกตว่าการเขียน tag form ก็เขียนตามปกติ (อย่าลืม enctype="multipart/form-data") แต่ว่าส่วนที่แสดงผลฟิลด์ต่าง ๆ ในฟอร์มเราสั่งให้แสดง form.as_p ได้เลย ลองเรียก python manage.py runserver ขึ้นมาดูหน้าตากันนะครับ สังเกตว่าฟอร์มจะเบี้ยว ๆ หน่อย ถ้าเข้าไปดูที่ html จะเห็นว่าจาก form.as_p จะได้ html ประมาณนี้ครับ
<p><label for="id_description">Description:</label> <textarea id="id_description" rows="10" cols="40" name="description"></textarea></p>
<p><label for="id_image">Image:</label> <input type="file" name="image" id="id_image" /></p>
ถ้าเราไม่ชอบเบี้ยว ๆ ก็แก้ให้แสดงเป็นตารางก็ได้ครับ แก้เป็น
<table>
{{ form.as_table }}
</table>
<input type="submit" value="upload"/>
</form>
พอได้หน้า template แล้ว เราก็ไปเขียนตัวจัดการกับการ upload เลยครับ
เราจะเขียนฟังก์ชัน upload ให้จัดการกับ url upload/ ดังนั้นไปเพิ่มบรรทัดด้านล่างในไฟล์ urls.py
ส่วนโค้ดของ upload อยู่ด้านล่างครับ
if request.method == 'POST':
# ผูก form เข้ากับข้อมูลที่ได้รับมา
form = PictureForm(request.POST, request.FILES)
if form.is_valid(): # ตรวจสอบข้อมูลในฟอร์ม
# เอาค่าที่เก็บกวาดแล้วมาใช้
title = form.cleaned_data['title']
desc = form.cleaned_data['description']
imagefile = form.cleaned_data['image']
# สร้างรูปใหม่ แล้วเก็บลงฐานข้อมูล
new_picture = Picture()
new_picture.title = title
new_picture.description = desc
new_picture.image.save(imagefile.name,imagefile)
new_picture.save()
return HttpResponseRedirect('/')
หลัก ๆ คือถ้าผู้ใช้ส่ง request มาแบบ POST (คือส่งฟอร์มมา) เราก็จะผูกวัตถุของ PictureForm เข้ากับข้อมูลที่ได้รับ อันนี้พิเศษหน่อยที่เราต้องมี request.FILES ด้วย เพราะว่าเรามีการส่งไฟล์มา
จากนั้นเรียกเมท็อด is_valid เพื่อตรวจสอบ/เก็บกวาดข้อมูลใน form ถ้าถูกแล้วเราจะได้ข้อมูลไว้ใช้เป็น dictionary ชื่อ cleaned_data (ในการตรวจสอบความถูกต้องนี้เราสามารถเขียนเพิ่มเติมเกี่ยวกับเงื่อนได้)
ตอนท้าย ๆ เป็นการสร้างวัตถุใหม่ในโมเดล แล้วเก็บลงฐานข้อมูลครับ เราเริ่มสร้างวัตถุของคลาส Picture แล้วก็กำหนดค่าให้กับแต่ละฟิลด์เลย ที่ลำบากหน่อยคือส่วนของการเก็บรูป เพราะว่าเราต้องเก็บลงไปในที่ที่ตั้งไว้ ในขณะค่าในตัวแปร image ที่ได้มาจะอิงกับข้อมูลที่ผู้ใช้ป้อน ซึ่งอาจจะเก็บอยู่ในไดเร็กทอรีไฟล์ชั่วคราว ดังนั้นจะเอามาใช้ก็ต้องสั่ง save เอาเองที่ฟิลด์นั้นครับ (ในเอกสารเก่าหน่อยจะให้สั่ง save_FIELD_file แต่มัน deprecated ไปแล้ว)
สุดท้ายเราสั่ง HttpResponseRedirect ให้ browser redirect กลับไปหน้าแรก จะสั่งฟังก์ชันนี้ได้อย่าลืมใส่บรรทัดด้านล่างไว้ตรงหัว views.py นะครับ
เท่านี้ก็เรียบร้อยครับ ทดลองเล่นได้ครับ
ที่เราทดลองมานี่เป็นการทำแบบอ้อม ๆ ครับเพื่อแสดงให้เห็นการใช้งาน Form อย่างง่ายครับ แต่จริง ๆ แล้ว ถ้าเราต้องการสร้างฟอร์มจากโมเดล เรามีคลาสช่วยเหลืออย่าง ModelForm ทำให้เขียนง่ายขึ้นมากครับ ด้านล่างเป็น views.py ในส่วนประกาศ PictureForm และฟังก์ชัน upload ที่เขียนโดยใช้ ModelForm ครับ
class Meta:
model = Picture # สร้าง form จากโมเดล Picture
def upload(request):
if request.method == 'POST':
# ผูกฟอร์มเข้ากับข้อมูล
form = PictureForm(request.POST, request.FILES)
if form.is_valid(): # ทดสอบความถูกต้อง
form.save() # เก็บ
return HttpResponseRedirect('/')
ส่วนที่หายไปก็คือการประกาศฟิลด์ตามโมเดล และส่วนการจัดการเรื่อง save ครับ
ที่นี้ก่อนจบมาเก็บกวาดกันต่ออีกสักนิดครับ
สังเกตว่าในโมเดลเรามีฟิลด์ description แต่ไม่ได้เอาไปแสดงผลเลย ถ้าต้องการแสดงก็แก้ส่วน template โดยเพิ่มให้แสดง {{ picture.description }} เข้าไปนะครับ ทีนี้ ถ้าเราพิมพ์หลาย ๆ บรรทัดแล้วเราต้องการให้มีการแปลงเครื่องหมายขึ้นบรรทัดใหม่ให้เป็น <br> ให้ใส่เป็น {{ picture.description|linebreaks }} แทน ส่วน |linebreaks เป็น filter ให้เราปรับแต่งการแสดงผลของตัวแปรได้ครับ
ปรับเอาตามชอบเลยนะครับ ตัวอย่างด้านล่างนี่แสดงรูป (ย่อเหลือความกว้าง 100) แล้วแสดงคำอธิบายข้าง ๆ ครับ
<h3>{{ picture.title }}</h3>
<table>
<tr><td>
<img src="{{ picture.image.url }}" width="100"/>
</td><td>
{{ picture.description|linebreaks }}
</td></tr>
</table>
{% endfor %}
ส่วนของ tutorial การเขียน app เพื่ออัพโหลดรูปคงจบไว้คร่าว ๆ แค่นี้ครับ (อาจมีตอนต่อไปอีกได้ เกี่ยวกับการทำ user และทำเรื่องการ follow)
เอกสารเพิ่มเติม
- ดูรายละเอียดเกี่ยวกับ file upload
- เอกสาร ModelForm
RESTful with Grails
Posted September 24, 2008 at Grails66การจัดการ GORM Relationship แบบ Many-to-Many
Posted September 28, 2008 at Grails66Looping with Groovy
Posted October 03, 2008 at Grails66ทำความรู้จักกับ Android
Posted October 06, 2008 at Android66Android คือระบบปฏิบัติการ (Operating System) บนโทรศัพท์มือและอุปกรณ์พกพาที่พัฒนาโดย Google. เราอาจเรียก Android เป็น Software Stack ที่ประกอบด้วย ระบบปฏิบัติการ โปรแกรมต่างๆ และแฟรมเวิร์ค (Framework) สำหรับนักพัฒนา เพื่อใช้ในการพัฒนาโปรแกรมบนแพลตฟอร์ม Android ได้
สถาปัตยกรรมของ Android
จากรูป Android จะประกอบด้วย องค์ประกอบหลักอยู่ 5 ส่วน ดังนี้
1. ซอฟแวร์ทั่วไป (Applications)
อุปกรณ์พกพาที่ติดตั้ง Android จะมาพร้อมโปรแกรมหลักที่ไว้ใช้งานทั่วไป เช่น โปรแกรมรับส่งอีเมล, SMS, ปฏิทิน, แผนที่, Browser (ใช้ WebKit เป็น Engine) เครื่องมือจัดการสมุดโทรศัพท์ และโปรแกรมหลักอื่นๆ
2. แฟรมเวิร์ค (Application Framework)
นักพัฒนาสามารถพัฒนาโปรแกรมบน Android โดยใช้ภาษา Java ผ่านทาง API (Application Programming Interface) โดยสามารถเข้าถึงระบบและข้อมูลต่างๆ ที่อยู่บน Android ดังนี้
- Views ประกอบด้วย UI ชนิดต่างๆ ที่ใช้ในการพัฒนาโปรแกรม เช่น lists, grids, text boxes, buttons รวมไปถึง Event และเว็บบราวเซอร์
- Content Provider โปรแกรมที่พัมนาบน Android จะสามารถส่งข้อมูลถึงกันผ่านทาง Content Provider เช่นเราสามารถพัฒนาโปรแกรมเพื่อไปดึงข้อมูลรายชื่อที่อยู่ใน Contacts ได้
- Resource Manager เป็นตัวจัดการเรื่องรูปภาพ, Localized strings และข้อมูลอื่นๆ ที่นอกเหนือจาก Code ของโปรแกรม
- Activity Manager นักพัฒนาสามารถสร้าง Custom Alert และส่งไปแสดงผลที่ Status Bar โดยผ่าน Activity Manager
3. ชุดพัฒนา (Libraries)
Android ยังประกอบด้วยชุดพัฒนาของ C/C++ อื่นๆ ที่สามารถใช้งานผ่านทาง API ของเฟรมเวิร์คที่ Android ได้จัดไว้ให้ (API เป็นภาษา Java)
- System C Library ไลบรารีมาตรฐานของ C (C system library) ปรับปรุงพิเศาสำหรับอุปกรณ์ที่รันบน Linux
- Media Library โดย Android สรับสนุนการใช้งานไฟล์ฟอร์แมตต่างๆ เช่น MPEG4, H.264, MP3, AAC, AMR, JPG และ JPG
- Surface Manager เป็นตัวจัดการระบบแสดงผล และควบคุมบนจอภาพ