ในการ test แบบ functional test จะขออธิบายไล่ถ้าได้ test อะไรบ้าง จะไม่ได้อธิบายเป็น commit ต้องขออภัยด้วย เพราะว่าตอนทดลองทำ test ได้ทำแล้วก็แก้ แล้วก็ทำต่อเลยไม่ได้ทำการ commit
เป็น method เรียกใช้ตัวเองในการกำหนด browser ที่จะใช้ในการ test ในกรณีนี้จะเป็น firefox และจะมีการเรียกใช้ method create_test_date() เพื่อใช้ในการสร้างข้อมูลเพื่อใช้ในการ test
เหตุผลที่จะต้องมีการสร้างข้อมูลก่อนเทสนั้นก็เพราะว่า web app ตัวนี้จะเป็น web app ที่ใช้ในการสุ่ม รายชื่ออาหารซึ่งเป็นข้อมูลใน Database ซึ่งมันจะต้องมีข้อมูลเพื่อใช้ในการสุ่ม แต่ว่าในการ test นั้นเราจะใช้ Database จำลองซึ่งจะไม่มีข้อมูล และ สามารถใส่ข้อมูลจากการ test ได้ โดยไม่ไปกระทบกับตัวข้อมูล ของ Database ที่ใช้งานอยู่จริงๆ
Method tearDown จะเป็น method เรียกใช้ตัวเอง เพื่อใช้ในการปิด browser หลังจากที่ได้ทำการ test เสร็จแล้ว
Method create_test_data() จะทำการสร้างข้อมูลลงไปใน Database จำลองเพื่อใช้ในการทดลองสุ่มอาหาร ซึ่งจะใส่ไว้แค่ตัวเดียว เพื่อที่จะดูว่ามีการแสดงผลที่ถูกต้องหรือไม่
ในการ test จะ test ตาม user story ที่ได้เขียนเอาไว้ โดย ตอนแรกจะทำการค้นหา title ของ web page ก่อน หลังจากนั้น ก็จะทำการกด ปุ่มโดยค้นหา element โดยใช้ id ว่า button_box โดยจะถูกกำหนดไว้ตอนเขียน web app หลังจากนั้นจะใช้คำสั่ง click() เพื่อทำการคลิกปุ่มแล้วก็จะ check หา id ที่เป็น choice หรือ ก็คือ เหล่าตัวเลือกหมวดอาหาร
พอค้นหาเจอแล้วก็จะใช้คำสั่ง click เช่นเดิม แล้วก็จะหา id submit ซึ่งจะเป็นปุ่มกด submit นั้นเอง แต่วิธีกดจะไม่เหมือนเดิมเพราะจะใช้การ send_keys(Keys.ENTER) หรือ ก็คือสั่งให้กด Enter นั้นเอง ก็จะไปหน้าผลลัพธ์ แล้วก็ จะค้างไว้ 5 วินาทีเพื่อดูผล แล้วหน้าต่างจะปิดลง แล้วขึ้น Finish the test! ไว้ที่หน้าต่าง terminal
วันเสาร์ที่ 8 กรกฎาคม พ.ศ. 2560
วันพฤหัสบดีที่ 29 มิถุนายน พ.ศ. 2560
แก้ไขเพิ่มเติม
จากการ present ครัังล่าสุดได้มีการแนะนำจาก SPN ให้นำหน้าเว็บบางหน้าออกไปเพราะจะทำให้คลิกเยอะเกินไป ทางผมก็ได้ทำการแก้ไขนำเอา แล้วก็ลองใช้ web app และแก้ไขเพิ่มเติมดังนี้
ก็ได้ทำเพิ่มมาสอง commit อันแรกก็จะเป็นปุ่ม back ในหน้าแก้ไข ซึ่งได้พบว่าลืมใส่เอาไว้ เลยไม่สามารถกลับไปที่หน้าหลักได้
ก็ได้ทำเพิ่มมาสอง commit อันแรกก็จะเป็นปุ่ม back ในหน้าแก้ไข ซึ่งได้พบว่าลืมใส่เอาไว้ เลยไม่สามารถกลับไปที่หน้าหลักได้
commit ถัดไปก็ได้นำหน้า Home ออกไปเพราะว่าจาก คำแนะนำของ SPN ก็ได้เข้าใจว่า มันก็มีหน้า Homepage ที่ไว้สำหรับลิงค์ไปหา App ต่างๆแล้ว หน้านี้ก็คงไม่จำเป็นเพราะจะทำให้เกิดการคลิก ที่เยอะจนเกินไปครับ
หน้านี้ก็จะหายไป
จะกลายมาเป็นหน้านี้แทน
ในส่วนนี้ก็จะขอชี้แจ้งเพียงเล็กน้อยก็คือ version control ตอนนี้ใช้ Bitbucket ครับ https://bitbucket.org/thanut_suwannawong/
โดย commit จะหายไปบางส่วนเนื่องจากมีการนำไฟล์มา push กับ repository ตัวใหม่ แล้วเผลอลบ repository บน cloud อันเก่าไปด้วย โดยลืมคิดเรื่อง commit ไป commit ในส่วนของการสร้าง web app ก็จะหายไปบางส่วน ครับผม และสาเหตุที่ต้องสร้าง repository ก็เพราะว่าต้องการที่จะใช้ในการ pull ลง pythonanywhere ได้ง่าย เลยแยก repository ไว้เก็บเป็น repo ละ app ครับผม
วันศุกร์ที่ 9 มิถุนายน พ.ศ. 2560
วันศุกร์ที่ 19 พฤษภาคม พ.ศ. 2560
วันอาทิตย์ที่ 30 เมษายน พ.ศ. 2560
Random_food (v.1.0)
ในตอนนี้ฟังก์ชั่นการทำงานของ app Random_food นั้นสามารถที่จะ
- สุ่มอาหารได้
- เพิ่มเมนูที่จะสุ่มอาหารได้
- ลบเมนูอาหารได้
ในส่วนนี้จะไม่ขออธิบายโค้ด แต่จะอธิบายการทำงานเฉยๆพร้อมกับรูปประกอบเล็กน้อย
ก็สามารถเลือกหมวดอาหารที่จะสุ่มได้ ได้ที่ต้องการแล้วกด สุ่มเลย แต่หากต้องการที่จะแก้ไข หรือ เพิ่มเมนูในคลิกปุ่มด้านล่าง
เมื่อกดเข้ามาแล้ว ให้กดเลือกหมวดที่จะแก้ไข แล้วก็กด 'Edit'
- สุ่มอาหารได้
- เพิ่มเมนูที่จะสุ่มอาหารได้
- ลบเมนูอาหารได้
ในส่วนนี้จะไม่ขออธิบายโค้ด แต่จะอธิบายการทำงานเฉยๆพร้อมกับรูปประกอบเล็กน้อย
หน้าแรกก็จะเป็นดังนี้
ด้านบนจะเลือกเพื่อที่จะลบรายการส่วนด้านล่าง จะเป็นการแอดเมนูอาหารให้กับหมวดๆนั้น
ปัญหาที่พบ
ยังไม่เจอปัญหาร้ายแรง ส่วนใหญ่จะเป็นการลืมนู้นนี้ซะส่วนใหญ่
วันพุธที่ 19 เมษายน พ.ศ. 2560
Random_food : User story
# Mr.Wick want to have dinner
# he goes to restaurant
# he don't know what to eat
# he've heard about new app "Random_food"
# app will random food for the one who doesn't know what to have for that meal
# he goes in to website
# then he see its homepage and
# he sees message "Just click" and a button
# he clicks on it
# he sees many options and he decide to choose "หมวดข้าวจานเดียว"
# the website shows the result, it's "ข้าวกะเพราะหมูกรอบ"
# he feels okay with that then he closes website.
# he goes to restaurant
# he don't know what to eat
# he've heard about new app "Random_food"
# app will random food for the one who doesn't know what to have for that meal
# he goes in to website
# then he see its homepage and
# he sees message "Just click" and a button
# he clicks on it
# he sees many options and he decide to choose "หมวดข้าวจานเดียว"
# the website shows the result, it's "ข้าวกะเพราะหมูกรอบ"
# he feels okay with that then he closes website.
วันอาทิตย์ที่ 16 เมษายน พ.ศ. 2560
AS2 : Random_food
ในช่วงพักหยุดช่วงสงกราต์ SPN ได้ให้นักศึกษาไปทำงาน AS2 โดยหัวข้อที่จะให้ทำนั้น นศ. เป็นคนกำหนดเอง โดยหลักการคือนำปัญหาที่พบในปัจจุบัน มาทำเป็นโปรแกรมเพื่อทำการช่วยแก้ปัญหานั้นๆ โดยปัญหาของผมนั้นนึกไม่ออกว่าจะทานอะไร จึงเป็นที่มาของ App สุ่มเมนูอาหาร โดยได้ทำงาน ไปส่วนนึงแล้วสามารถที่จะสุ่มอาหารแล้วบอกแคลลอรี่ได้ โดยอาจจะทำเพิ่ม extra เพิ่มเติมทีหลัง แต่ที่หลักๆคิดว่า SPN เน้นไปที่เรื่อง TDD ซะเป็นส่วนใหญ่
นี้เป็นการ commit ทั้งหมด ในตอนนี้ โดยจะมาอธิบายอีกภายหลังครับผม
นี้เป็นการ commit ทั้งหมด ในตอนนี้ โดยจะมาอธิบายอีกภายหลังครับผม
วันอาทิตย์ที่ 26 มีนาคม พ.ศ. 2560
Selenium pt.2
ใน Tutorial บทที่ 1 จะไม่ค่อยมีอะไรมากแค่สอนวิธีการใช้ Django สร้าง project แล้วก็การรัน test อย่างง่ายๆ ซึ่งจะเป็น FT (functional test) เพราะฉะนั้นจะขอข้ามไปบทที่ 2 เลย
ในบทนี้ก็จะเป็นการสอนการทำ function test ต่อ โดยโค้ดจะมีหน้าตาดังนี้
from selenium import webdriver
import unittest
class NewVisitorTest(unittest.TestCase): #1
def setUp(self): #2
self.browser = webdriver.Firefox()
self.browser.implicitly_wait(3)
def tearDown(self): #3
self.browser.quit()
def test_can_start_a_list_and_retrieve_it_later(self): #4
# Edith has heard about a cool new online to-do app. She goes
# to check out its homepage
self.browser.get('http://localhost:8000')
# She notices the page title and header mention to-do lists
self.assertIn('To-Do', self.browser.title) #5
self.fail('Finish the test!') #6
# She is invited to enter a to-do item straight away
#[...rest of comments as before]
if __name__ == '__main__': #7
unittest.main(warnings='ignore') #8
โดย #1 มีการสืบทอด unittest
#2 จะเป็นการ set up โดยจะเปิดเป็น browser firefox
#3 เมื่อ test เสร็จก็จะออก browser ให้อัตโนมัติ
#4 พวก function หรือ method ที่ขึ้นตันด้วย test_ จะเป็นการ test ทั้งสิ้น
#5 โดยใน function นี้จะเรียก url localhost:8000 และก็จะเช็ค โดยใช้คำสั่ง assertIn(a,b) คือจะทำการเช็คว่ามี a อยู่ใน b หรือไม่
#6 เป็นการบังคับ fail แล้วให้ขึ้นข้อความว่า "Finish the test"
#7 & #8 ขอข้ามไปก่อนครับผม
ในบทนี้ก็จะเป็นการสอนการทำ function test ต่อ โดยโค้ดจะมีหน้าตาดังนี้
from selenium import webdriver
import unittest
class NewVisitorTest(unittest.TestCase): #1
def setUp(self): #2
self.browser = webdriver.Firefox()
self.browser.implicitly_wait(3)
def tearDown(self): #3
self.browser.quit()
def test_can_start_a_list_and_retrieve_it_later(self): #4
# Edith has heard about a cool new online to-do app. She goes
# to check out its homepage
self.browser.get('http://localhost:8000')
# She notices the page title and header mention to-do lists
self.assertIn('To-Do', self.browser.title) #5
self.fail('Finish the test!') #6
# She is invited to enter a to-do item straight away
#[...rest of comments as before]
if __name__ == '__main__': #7
unittest.main(warnings='ignore') #8
โดย #1 มีการสืบทอด unittest
#2 จะเป็นการ set up โดยจะเปิดเป็น browser firefox
#3 เมื่อ test เสร็จก็จะออก browser ให้อัตโนมัติ
#4 พวก function หรือ method ที่ขึ้นตันด้วย test_ จะเป็นการ test ทั้งสิ้น
#5 โดยใน function นี้จะเรียก url localhost:8000 และก็จะเช็ค โดยใช้คำสั่ง assertIn(a,b) คือจะทำการเช็คว่ามี a อยู่ใน b หรือไม่
#6 เป็นการบังคับ fail แล้วให้ขึ้นข้อความว่า "Finish the test"
#7 & #8 ขอข้ามไปก่อนครับผม
Selenium pt.1
ในการทดลองใช้ selenium SPN ได้เขียน keyword ลงใน Blog ของเขาซึ่งผมก็ได้ทำตาม tutorial ไปเรื่อยๆก็ได้พบกับคำเหล่านี้ เต็มไปหมด ซึ่งผมจะหาคำนิยามของ keyword เหล่านี้
- Functional test ( การรันทดสอบการทำงานของโปรแกรม จากมุมองของ user ที่ user สามารถเข้าถึงได้ )
- User story ( เป็นการที่ user จะใช้โปรแกรมทำอะไร แล้วผลที่โปรแกรมจะส่งกลับมาเป็นยังไง )
- Expected failure ( ในการเขียน test จะต้องมีการคาดว่า การกระทำใดจะทำให้ผล test fail ได้ )
- Unit test ( เป็นการทดสอบโปรแกรมแบบ ด้านในของโปรแกรม ในมุมมองของคนเขียนโปรแกรม )
- Refactoring ( การปรับปรุงโค้ด โดยจะไม่ทำให้การทำงานของโปรแกรมเปลี่ยนแปลงไป )
- Functional test ( การรันทดสอบการทำงานของโปรแกรม จากมุมองของ user ที่ user สามารถเข้าถึงได้ )
- User story ( เป็นการที่ user จะใช้โปรแกรมทำอะไร แล้วผลที่โปรแกรมจะส่งกลับมาเป็นยังไง )
- Expected failure ( ในการเขียน test จะต้องมีการคาดว่า การกระทำใดจะทำให้ผล test fail ได้ )
- Unit test ( เป็นการทดสอบโปรแกรมแบบ ด้านในของโปรแกรม ในมุมมองของคนเขียนโปรแกรม )
- Refactoring ( การปรับปรุงโค้ด โดยจะไม่ทำให้การทำงานของโปรแกรมเปลี่ยนแปลงไป )
วันเสาร์ที่ 18 มีนาคม พ.ศ. 2560
Wiki
ในช่วงเวลา 1 สัปดาห์ในการพักผ่อน ทางผมได้ทำจัด Tutorial สำหรับสร้าง web app ledger หรือบันทึกรายรับ รายจ่าย ไว้ใน link => https://github.com/a5810067/ledger/wiki ซึ่งถ้าหากผิดพลาดประการใด ก็ขออภัยไว้ ณ ที่นี้ด้วย
วันจันทร์ที่ 27 กุมภาพันธ์ พ.ศ. 2560
Ledger (Export csv)
ข้ามจากการตกแต่งด้วย css เป็นเรื่อง csv ก่อนละกันนะครับ เนื่องจากว่า SPN ได้ให้ลองสามารถ export ข้อมูลออกเป็นไฟล์ csv ได้ ผมเลยไปทำการค้นคว้าข้อมูล โดยได้เว็บของ
django เว็บนี้มาช่วยในการทำงานเกี่ยวกับ csv output Click โดยจะเป็นการใช้ api ของ python ในการ generate csv file หรือ ก็คือสร้าง csv ไฟล์ขึ้นมาได้เองเลย โดยโค้ดเป็นดังนี้
django เว็บนี้มาช่วยในการทำงานเกี่ยวกับ csv output Click โดยจะเป็นการใช้ api ของ python ในการ generate csv file หรือ ก็คือสร้าง csv ไฟล์ขึ้นมาได้เองเลย โดยโค้ดเป็นดังนี้
โดยเขาบอกว่า วิธีการ generate นี้ง่ายมากกก ก็แค่ส่งผ่าน response ให้กับ csv.writer()
ส่วน response['Content-Disposition'] = 'attachment; filename="history.csv"'
จะเป็นการตั้งชื่อไฟล์ที่จะดาวน์โหลด โดยผมตั้งว่า history.csv
หลังจากนั้นก็จะ wrtiterow(.....) โดยตัวแรกผมเอาไว้เขียนหัวไฟล์ ส่วนที่เหลือก็ใช้การวน for loop ในการใส่ลงไปในไฟล์ csv โดยจะเรียงเป็น pubdate note income expenese
นี้ก็เป็นหน้าตาของไฟล์ csv ที่ได้ดาวน์โหลดมาก็ตรงตาม
ตารางบันทึกรายรับ รายจ่ายอย่างถูกต้อง โดยผมจะทำปุ่มไว้ให้ user กด
ส่วนวิธีเชื่อม link ต่างๆ ผมขอข้ามไปเพราะว่าถ้าติดตามบล็อกผมมาตลอดก็จะรู้วิธีทำแล้วละครับวันนี้ก็ขอจบเพียงเท่านี้ ขอตัวไป ตกแต่งต่อเลยนะครับ
Ledger (Theme)
commit ที่มีแค่ 2 commits เกิดจาก ปัญหามันมีไม่เยอะ แต่แก้ลำบากครับ (55+)
ใน commit แรกสิ่งที่ได้ทำก็จะประมาณว่า ผมสร้างไฟล์ css สำหรับไว้ใช้สำหรับ template แล้วผมก็สร้างไว้ 2 ชุด เพื่อนำไปทำ ธีม แต่ปัญหาก็จะเกิดก็ตอนที่ว่าเปิดไป แล้วเปิดกลับ สิ่งที่เกิดขึึ้นคือ รูปภาพกลับไปยังที่เดิม วิธีแก้ของผมก็คือใส่ ค่า theme ซึ่งเป็นค่าตัวแปรที่รับค่ามาจาก selected_theme เป็นค่าที่รับมาจากปุ่มกด แบบ radio
โดยค่า selected_theme จะถูก request และเก็บในตัวแปร theme
จากฟังก์ชั่น theme_select() ใน views.py
แล้วก็จะใช้ HttpResponseRedirect และ reverse ไปที่ หน้า index และ
ส่ง argument theme ไปให้เพื่อให้รู้ว่า theme นั้นถูกเลือก
หลังจากนั้นก็จะเปลี่ยนแปลงการเรียกไฟล์ css โดยจะใช้เป็น
/ledger/{{theme}}.css ถ้าหากค่าของ theme = style1
url ที่ได้ก็จะเป็น /ledger/style1.css
โดยทั้งนี้จะต้องมีการแก้ไข urls.py ด้วยเช่นกัน โดยแก้ไข reg ex เสียใหม่
?P<theme>[a-zA-Z0-9] จะเป็นการรับค่าพวก a-z ได้ และ
A-Z ได้ และก็สามารถรับ ตัวเลขได้ 0-9 ได้
แต่ทว่า ผมไม่ค่อยชอบการตกแต่ง templates สักเท่าไรเลยยังไม่ได้ตกแต่งไฟล์ templates ด้วย css เลย
Update Github's status
ในการทดลองแยก repository ตาม app แต่ละ app นั้น ส่วนตัวผมนั้นรู้สึกชอบมาก เพราะว่ามันเป็นระบบดีในการทำงาน นี้ก็เป็นการ commit ทั้งหมด หลังจากที่ได้ สร้าง repository ใหม่
repository => homepage มีการทำงานนิดหน่อย
repository => polls หลังจากแอดไว้ ก็ไม่ได้แตะเลย 55
repository => ledger อันนี้เด็ดเลยครับ เนื่องจากเป็นงานที่ทำอยู่ปัจจุบัน ก็มีการ commit เรื่อยๆทำไปเจอบัคไปแก้บัคไป สนุกสนาน : )
วันพุธที่ 22 กุมภาพันธ์ พ.ศ. 2560
New Repository
ในตอนนี้ได้ทำการแยกไฟล์ แต่ละ App ให้มี repository เป็นของตัวเอง เพื่อเป็นการทดลองว่าจะสะดวกต่อการแก้ไข และ push กับ pull ระหว่างในเครื่องและบน pythonanywhere มากกว่าที่จะเก็บเป็น project หรือ เปล่า โดยตอนนี้จะมีทั้งหมด 3 repository (commit อันเก่าหายไปหมดเลย) ซึ่งถ้าหากว่าไม่ได้มีผลดีขึ้น งานหน้าก็จะกลับไปใช้เก็บทั้งโปรเจคท์ดังเดิม
วันอาทิตย์ที่ 19 กุมภาพันธ์ พ.ศ. 2560
Ledger Final Chapter
ในบทความนี้จะเป็นการเล่าถึง web app Ledger หรือ บันทึกรายรับรายจ่ายครั้งสุดท้าย เพราะคิดว่าคงไม่มีปัญหาอะไรแล้วครับ แต่ถ้าหากมีเพิ่มเติม ก็อาจจะว่ากันต่อภายในบทความครั้งหน้าครับ
นี้คือหน้าตาตอนหลังจากตกแต่งเสร็จ(ไม่ค่อยสวยเท่าไร 55)
finally fix that input date problem
นี้คือหน้าตาตอนหลังจากตกแต่งเสร็จ(ไม่ค่อยสวยเท่าไร 55)
โดยจะขออธิบายตาม commit (จากล่างขึ้นบน)
delete use timezone(not necessary)
ลบวิธีการใส่เวลาแบบ use timezone ออกไปเนื่องจากไม่จำเป็น
delete total_income and total_expense to 1 funtion
จากครั้งที่แล้วที่นำเสนอไป ฟังก์ชั่นคำนวณค่ารวมของรายรับ กับ ร่ายจ่าย ใช้ฟังก์ชั่นเป็นของตัวเองในการคำนวณ ได้ยุบเหลือเพียงฟังก์ชั่นเดียวโดยดังนี้
ในการวนลูป 1 ครั้งจะเช็คเลยว่าเป็นรายรับ หรือ รายจ่าย แล้วก็แยกบวกตามประเภทนั้นๆ หลังจากนั้น ก็เก็บค่าไว้ใน list ชื่อ total แล้ว return กลับไป
โดย total[0] = total_income และ total[1] = total_expense
เนื่องจาก Firefox ไม่รองรับการใช้ input date เลยได้ไปหาวิธีการใช้ datepicker วิธีอื่นๆ สิ่งที่ได้คือการใช้ jQuery https://jqueryui.com/datepicker/#default
ซึ่งช่วยแก้ปัญหาได้มากเลยที่เดียว แต่ว่าจะต้องมีการตั้งค่า format ให้มันก่อน เพราะว่า Model เราใช้เป็น DateField() โดยมันจะรับค่าเป็น yy-mm-dd เท่าน้้น โดยวิธีการตั้งค่า format ก็ได้มาจากการเปิด youtube หาวิธี https://www.youtube.com/watch?v=9U_5Z4WqswI ( ต้องขอบคุณจริงๆที่สมัยนี้การค้นคว้าหาข้อมูลทำได้ง่ายๆ)
delete total column
ได้ลบตัวค่ายอดคงเหลือ ของแต่ละแถวออกไปเพราะมันไม่จำเป็นอีกต่อไปแล้ว
ครั้งที่แล้วการลบนั้นก่อให้เกิดปัญหาเรื่องยอดคงเหลือของแต่ละแถว แต่ตอนนี้ได้ลบยอดคงเหลือดังกล่าวไปแล้ว ทำให้สามารถสานต่อการลบได้ โดยจะเปลี่ยนจากการลบได้หลายๆตัว ให้เป็นลบได้เพียงตัวเดียว ก็เพราะว่า ต้องการจะให้มีหน้าแสดงเตือน ด้วยว่าจะต้องการลบจริงๆ แล้วอีกอย่างคือ บันทึกรายรับ รายจ่ายเป็นสิ่งที่ต้องคิดก่อนที่จะบันทึก เลยไม่น่าจะมีความผิดพลาดมากมายให้ขนาดว่า ต้องลบทีละหลายๆรายการ
เมื่อเลือกรายการแล้วกด Submit
จะมีปุ่ม Yes กับ No ให้เลือก
เมื่อเลือก Yes ก็จะลบรายการนั้นทิ้งไป แต่ถ้าหากว่าเลือก No ก็จะกลับไปหน้าเลือกลบรายการใหม่
ตกแต่งสีสันให้สวยงาม(แต่ดันไม่สวยไม่งาม)
วันพุธที่ 15 กุมภาพันธ์ พ.ศ. 2560
Ledger pt.7
ในที่สุดก็ใส่ comma ผ่านได้แล้ว ต้องขอขอบคุณ Thakdanai Kunsaen ที่แนะนำมาเว็บนี้เลย
https://docs.djangoproject.com/en/1.10/ref/contrib/humanize/
https://docs.djangoproject.com/en/1.10/ref/contrib/humanize/
โดยเริ่มจาก
ไปเพิ่ม 'django.contrib.humanize' ใน INSTALLED_APPS ในไฟล์ setting ก่อนแล้วก็ใส่
{% load humaninze %} ไว้ใน template ที่ต้องการใช้ filter นี้ วิธีใช้ก็ตามภาพด้านล่างเลยครับผม
Ledger pt.6
ในตอนนี้ web app ledger สามารถที่จะลบรายการบันทึกได้แล้ว
ในฟังก์ชั่น del_list มีการรับค่าแบบเป็น list เผื่อว่ามีการลบรายการ โดยค่าที่รับจะเป็น id ของรายการที่ต้องการจะลบ โดยนำไปใส่ไว้ในตัวแปร g(ไม่สื่อความหมายนะเนี่ย) หลังจากนั้นก็วนลูปลบ object ของ Model Note หรือ ก็คือลบรายการบันทึก โดยใส่ค่า pk = g[n] หลังจากนั้นก็ redirect ไปที่หน้า edit_list เช่นดังเดิม
ในส่วนของ edit_list นั้นผมก็ไม่อธิบาย เพราะว่ามันก็คือการนำ template index.html มาแก้ไขให้เป็นลักษณะของหน้าแก้ไขเท่านั้นเองครับผม
สิ่งที่ต้องทำต่อ
- แก้ไขเรื่องบัคของเวลา
- การใส่ comma
- ใส่ comment
- pep8
Use case การลบรายการ
- คลิกที่คำว่า 'Click' ด้านล่างของข้อความ 'Edit'
- เมื่อเข้ามาหน้าต่างนี้ เลือกรายการที่จะลบ โดยติ๊กเลือกที่คอลัมน์แรก สามารถเลือกได้หลายรายการ
- กด Submit
โค้ดที่เพิ่มมาจากครั้งที่แล้วมีดังนี้
- template => edit_page.html
- url => edit_list, del_list
- funtion => edit_list, del_list
โดยจะให้ดูที่ส่วนของ template ก่อน
ใช้ form โดยเมื่อกด submit จะ link ไปที่ url ชื่อ del_list ค่าที่ส่งไปจะเป็นค่า id ของรายการนั้นๆ
Function del_list
ในส่วนของ edit_list นั้นผมก็ไม่อธิบาย เพราะว่ามันก็คือการนำ template index.html มาแก้ไขให้เป็นลักษณะของหน้าแก้ไขเท่านั้นเองครับผม
สิ่งที่ต้องทำต่อ
- แก้ไขเรื่องบัคของเวลา
- การใส่ comma
- ใส่ comment
- pep8
วันอังคารที่ 14 กุมภาพันธ์ พ.ศ. 2560
Ledger pt.5
ในขณะที่ทำงานอยู่นั้น เพื่อนได้มาหอแล้วได้บอกว่าที่ผมทำไปเกี่ยวกับเรื่อง Total นั้นมันยังไม่ถูกนะ บอกว่าผมเข้าใจผิด เพื่อนบอกให้ลองหารูปใน google ดู ผลก็คือ......
ผิดเต็มๆ ใช่แล้วครับบรรทัดแรกของการบันทึก เงินคงเหลือก็ขึ้นตามนั้นเลยครับไม่ได้เป็น 0 ผมเลยนั่งแก้ ผลที่ได้ก็เป็นดังนี้
เย้ !! ดูมีมาตรฐานขึ้นมาเยอะเลย โดยวิธีที่ใช้ในการแก้ปัญหาก็คือ
บรรทัด ที่สามแค่บรรทัดเดียวเลย โดยโค้ดส่วนนี้จะอยู่ใน function add_list วิธีก็คือเวลาเราจะใส่ค่า cost_total เราจะเอาค่าที่ได้จากการคำนวณค่ายอดคงเหลือ ที่ได้มาจาก function total_money() มาเลยไม่ได้เพราะว่าตอนแรกมัน มันยังไม่มี object ไปคำนวณเงินค่ามันเลยออกมาเป็น 0 ผมก็เลยให้มันบวกกับค่า new_money ที่ถูกกลับเครื่องหมาย แล้วไปบวกเพิ่มกับ ค่าที่ได้จาก total_money() ก่อน แล้วค่อยใส่ลงไปในค่า cost_total นั้นเอง ง่ายใช่ไหมละ ทำไมคิดไม่ได้ตั้งแต่แรก ส่วน สองบรรทัดแรกนั้นผมไม่ได้อธิบายไว้ก่อนหน้านี้ ซึ่งมันก็คือ
money_type จะเป็นค่าที่ได้จากการ request.POST หรือ ค่าที่รับมาจากการ submit form นั้นเองโดยตัวนี้จะรับค่ามาจากเจ้านี้..!
โดย value ก็จะเป็น in , ex ก็ถ้า money_type = ex หรือ ติ๊กว่าเป็นรายจ่าย ก็จะนำค่า new_money มาใส่เครื่องหมาย - ด้านหน้า ทำให้เป็นค่าติดลบนั้นเองงง !!
ส่วนที่ทำเพิ่มมาอีกนิดนึง ก็จากตัวอย่างเลยครับ คือ บรรทัดสุดท้ายเขาจะใส่เป็น รวมของแต่ละหลักไว้ๆ ซึ่งผมก็ต้องขอขอบคุณตัวอย่างมาก เพราะผมก็ลืมเรื่องนี้ไปสนิทเลยเหมือนกัน ว่ามันควรจะเป็นแบบนั้น ก็เลยไปจัดเพิ่มมาอีก 2 function ก็คือ total_income() กับ total_expense()
ก็จะเหมือนกับ total_money() function ที่ไว้คำนวณยอดคงเหลือทั้งหมด เกือบทุกประการเพียงแต่เพิ่มเจ้าเงื่อนไข if ไว้เช็คว่าค่า cost_value นั้นติดลบหรือไม่ ถ้าหากติดลบ ซึ่งก็คือรายจ่าย ก็จะให้บวกเฉพาะค่าติดลบไปเรื่อยๆ ถ้าหากไม่ติดลบหรือเป็นบวก ก็จะให้บวกเฉพาะค่าบวกไปเรื่อยๆ แค่นี้ก็เรียบร้อย
การเรียกใช้ function ก็จะไปเรียกใช้ใน function index เพื่อที่จะให้ส่งค่า ไปแสดงโดย มีตัวแปร income_index, expense_index ไว้เก็บค่ารวมของรายรับรายจ่าย แล้วก็ที่ใส่ - ให้กับ total_expense() เพราะว่าตัวนี้จะ return ค่าที่เป็นลบ แต่อยากให้แสดงผลเป็น + ก็เลยให้กลับเครื่องหมายอีกครั้งหนึ่ง แล้วก็ใส่ค่าใน context ไปแสดงผลต่อ
วันจันทร์ที่ 13 กุมภาพันธ์ พ.ศ. 2560
Ledger pt.4
ในตอนนี้ได้แก้ปัญหาเกี่ยวกับ total ได้แล้ว !!
ซึ่งวิธีการแก้ปัญหาของผมนั้นก็คือ ....
ซึ่งวิธีการแก้ปัญหาของผมนั้นก็คือ ....
ตอนแรกตารางแสดงผลจะแสดงผลจากล่าสุดมาก่อน แต่ตอนนี้ผมได้เปลี่ยนให้แสดงเป็นล่าสุดไปต่อด้านล่าง แล้วก็สร้างตัวแปรอีกตัวมานั้นก็คือ total_index หรือ ก็คือส่วนบรรทัดสุดท้ายนั้นแหละ มาให้แสดงล้นตรงบรรทัดสุดท้ายของรายการ
โค้ดของมันก็จะมีหน้าตาดังนี้ ในส่วนของ function index ผมได้ใส่ context เพิ่มเข้าไปอีกตัว เอาไว้เรียกใช้งาน ซึ่งก็คือ total_index ซึ่งจะรับค่ายอดคงเหลือในปัจจุบัน
จากครั้งที่แล้วที่ได้อธิบายปัญหาใน Part3 จริงๆแล้วมันก็ไม่ใช่ปัญหาซะทีเดียว เพราะผมมานั่งคิดแล้วว่าจริงๆแล้วมันก็ควรจะเป็นแบบนั้นและ ถูกแล้ว อย่างบรรทัดแรก พ่อให้เงิน 5000 บาท ในตอนนั้นยอดคงเหลือที่เป็นของบรรทัดเดียวกันก็ควรจะเป็น 0 ก่อน เพราะว่าในตอนแรกนั้นยังไม่มีเงินจริงไหมครับ ก็เลยกลายเป็นว่าปัญหาก็คือเราไม่ได้เห็นจำนวนเงินคงเหลือในปัจจุบันเท่านั้นเอง
เพราะฉะนั้นผมจึงหาวิธีที่จะแสดงจำนวนเงินในปัจจุบันมาให้ได้ก็พอแล้ว โดยที่ผมต้องใส่เข้าไปใน function index ก็เพราะว่า ถ้าคิดจาก flow chart การทำงานของการเพิ่มรายการแล้ว เมื่อ add note เสร็จมันก็จะ redirect หน้าของ index มา เราก็ควรจะให้มีการรับค่ายอดคงเหลือปัจจุบันให้อยู่ใน function index ครับผม
ส่วนนี้ผ่านไป ต่อไปเป็นเวลาของการใส่เวลาในบันทึกโดยไม่อิงจากเวลาเครื่อง หรือ ใช้ timezone
สมัครสมาชิก:
บทความ (Atom)