- Django 6.0 ที่ครบรอบ 20 ปี เป็นรีลีสใหญ่ที่ปรับปรุงครั้งมากในส่วนสำคัญอย่างเทมเพลต งานเบื้องหลัง ความปลอดภัย อีเมล และอื่น ๆ
- ฟีเจอร์ Template partials ช่วยให้การนำโค้ดในเทมเพลตกลับมาใช้ซ้ำทำได้ง่ายขึ้น และเสริมการทำงานร่วมกับเครื่องมืออย่าง htmx
- มีการเพิ่ม เฟรมเวิร์ก Tasks ใหม่ เพื่อรันงานเบื้องหลังนอกวงจร HTTP request-response
- มี Content Security Policy(CSP) ติดตั้งมาให้ในตัว ทำให้ป้องกันการโจมตีแบบแทรกเนื้อหา เช่น XSS ได้ง่ายขึ้น
- การปรับปรุงอีเมล API ให้ทันสมัย, การปรับปรุง ORM และการขยายคีย์หลัก ช่วยยกระดับประสบการณ์นักพัฒนาและความสามารถในการขยายระบบอย่างมาก
ภาพรวมของ Django 6.0
- Django 6.0 เป็นรีลีสใหม่ของ Python web framework ที่สานต่อพัฒนาการตลอด 20 ปี
- การเปลี่ยนแปลงสำคัญจัดอยู่รอบ 4 ความสามารถหลัก ได้แก่ เทมเพลต งานเบื้องหลัง ความปลอดภัย และการจัดการอีเมล
- มีผู้มีส่วนร่วมจากชุมชนนักพัฒนาจำนวนมาก และมีการสรุปจุดปรับปรุงสำคัญโดยอิงจาก release note อย่างเป็นทางการ
เครื่องมือ django-upgrade
- เมื่อต้องอัปเกรดโปรเจกต์เดิมจาก Django 5.2 หรือต่ำกว่า สามารถใช้เครื่องมือ django-upgrade เพื่อแปลงโค้ดอัตโนมัติได้
- มี fixer อัตโนมัติ 5 ตัว สำหรับ Django 6.0 และช่วยแก้คำเตือนบางส่วนได้อัตโนมัติ
Template partials
- มีการเพิ่มฟีเจอร์ การกำหนดส่วนย่อยของเทมเพลต(
{% partialdef %}) เพื่อลดโค้ดซ้ำในเทมเพลตและนำกลับมาใช้ใหม่ได้
- สามารถเรียก partial ที่นิยามไว้ในเทมเพลตเดียวกันได้หลายครั้ง
- หากใช้ตัวเลือก
inline จะสามารถเรนเดอร์ได้ทันทีพร้อมกับการประกาศ
- ฟีเจอร์ การเรนเดอร์แบบบางส่วน ทำให้สามารถเรนเดอร์เฉพาะ partial ที่ต้องการแบบแยกได้
- ตัวอย่างใช้ htmx เพื่ออัปเดตส่วน
view_count เป็นระยะ
- สามารถเรนเดอร์เฉพาะส่วนได้โดยเติม
#partial_name ต่อท้าย URL
- ฟีเจอร์นี้ถูกรวมเข้า Django ผ่าน โครงการ Google Summer of Code และพัฒนาต่อมาจากแพ็กเกจ
django-template-partials เดิม
เฟรมเวิร์ก Tasks
- Django ได้เพิ่ม เฟรมเวิร์ก Tasks สำหรับรันงานเบื้องหลัง เข้ามาใหม่
- สามารถรันโค้ดนอกวงจร HTTP request-response ได้
- ใช้กับงานแบบ asynchronous เช่น การส่งอีเมล ประมวลผลข้อมูล หรือสร้างรายงาน
- นิยามงานด้วยตัวตกแต่ง
@task และนำงานเข้าคิวได้ด้วย Task.enqueue()
- backend ที่มีมาให้มี 2 แบบคือ
ImmediateBackend และ DummyBackend สำหรับการพัฒนา
และหากใช้ DatabaseBackend ของแพ็กเกจ django-tasks ก็สามารถรันบน SQL DB ได้
- ใช้คำสั่ง
db_worker เพื่อรันวอร์กเกอร์ของงาน และตรวจสอบสถานะได้จาก log
- ฟีเจอร์นี้เริ่มจากแนวคิดใน Wagtail และถูกรวมเข้า Django หลังข้อเสนอ DEP 0014
การรองรับ Content Security Policy(CSP)
- Django 6.0 รองรับมาตรฐาน CSP โดยตรง เพื่อเสริมการป้องกันการโจมตีแบบแทรกเนื้อหา เช่น XSS
- เปิดใช้งานได้โดยเพิ่ม
ContentSecurityPolicyMiddleware ลงใน MIDDLEWARE
- สามารถกำหนดนโยบายได้ผ่านการตั้งค่า
SECURE_CSP, SECURE_CSP_REPORT_ONLY
- มี ความปลอดภัยแบบ nonce ในตัว ทำให้เพิ่มแอตทริบิวต์
nonce="{{ csp_nonce }}" ให้กับแท็ก <script> และ <style> ได้
- จะมีการสร้าง nonce แบบสุ่มในแต่ละ request เพื่อให้รันได้เฉพาะ resource ที่เชื่อถือได้
- CSP ถูกเสนอครั้งแรกตั้งแต่ปี 2004 และก่อนหน้านี้มีการใช้งานผ่านแพ็กเกจ
django-csp ก่อนจะกลายเป็นฟีเจอร์ทางการในเวอร์ชันนี้
อัปเดตอีเมล API
- ลอจิกการจัดการอีเมลของ Django ถูกย้ายไปใช้ อีเมล API แบบทันสมัยของ Python 3.6
- ภายในใช้คลาส
email.message.EmailMessage
- อินเทอร์เฟซเดิมอย่าง
send_mail() และ EmailMessage ยังใช้งานได้เหมือนเดิม
- API ใหม่นี้มีข้อดี เช่น ลดบั๊ก, เพิ่มความปลอดภัย, และ ปรับปรุงการจัดการไฟล์แนบแบบ inline
- สามารถใช้วัตถุ
MIMEPart เพื่อเพิ่ม ไฟล์แนบแบบ inline เช่น รูปภาพในเนื้อหา HTML ได้อย่างง่ายดาย
- การเปลี่ยนแปลงนี้ถูกเสนอในปี 2024 และถูกรวมหลังพัฒนามา 8 เดือน
การจำกัด positional argument ของอีเมล API
- ใน API ของ
django.core.mail มีการเปลี่ยนให้บางพารามิเตอร์ รับได้เฉพาะ keyword argument เท่านั้น
- หากส่งอาร์กิวเมนต์ทางเลือก เช่น
fail_silently แบบ positional argument จะมีคำเตือน
- เป็นมาตรการเพื่อเพิ่มความอ่านง่ายและการบำรุงรักษา
- สามารถแก้อัตโนมัติได้ด้วย fixer
mail_api_kwargs ของ django-upgrade
การขยาย auto import ใน Shell
- ฟีเจอร์ auto import ของโมเดลใน Django 5.2 ถูกขยายเพิ่ม โดย
settings, connection, models, functions, timezone จะถูก import ให้อัตโนมัติ
- สามารถดูรายการ auto import ได้ด้วย
./manage.py shell -v 2
- ช่วยเพิ่มความสะดวกในการพัฒนาและลดโค้ดซ้ำ
การปรับปรุง ORM: อัปเดตฟิลด์แบบไดนามิกเมื่อ save()
- ฟิลด์อย่าง
GeneratedField หรือฟิลด์ที่อิง expression จะถูก อัปเดตอัตโนมัติหลัง save()
- บน DB ที่รองรับคำสั่ง
RETURNING เช่น SQLite, PostgreSQL, Oracle จะสะท้อนค่าทันที
- บน MySQL และ MariaDB จะอัปเดตอัตโนมัติผ่านการโหลดแบบหน่วงเวลา
- ทำให้ใช้งานค่าล่าสุดได้ทันทีโดยไม่ต้องมี query เพิ่ม จึงมีประสิทธิภาพมากขึ้น
ฟังก์ชัน aggregate แบบ Universal StringAgg
- สามารถใช้ฟังก์ชัน aggregate
StringAgg ได้กับทุก database backend
- คืนค่าสตริงที่เชื่อมค่าข้อมูลนำเข้าด้วยตัวคั่น (delimiter)
- เดิมเป็นฟีเจอร์เฉพาะ PostgreSQL แต่ตอนนี้ใช้ได้โดยตรงจาก
django.db.models
- สามารถกำหนดตัวคั่นได้ด้วย expression
Value()
BigAutoField เป็นค่าเริ่มต้น
- ค่าเริ่มต้นของ
DEFAULT_AUTO_FIELD เปลี่ยนเป็น BigAutoField
- ใช้คีย์หลักแบบจำนวนเต็ม 64 บิต เพื่อป้องกันปัญหา Primary Key หมด
- สำหรับโปรเจกต์ใหม่จะถูกใช้โดยอัตโนมัติโดยไม่ต้องตั้งค่าเพิ่มเติม
- เป็นการทำให้การตั้งค่าที่เริ่มมีใน Django 3.2 เรียบง่ายขึ้นและลด boilerplate
การปรับปรุงเทมเพลต
- มีการเพิ่มตัวแปร
forloop.length ทำให้อ้างอิงความยาวทั้งหมดภายในลูปได้
- ใช้ในรูปแบบ
{{ forloop.counter }}/{{ forloop.length }}
- มีการปรับปรุง แท็กเทมเพลต
querystring
- เมื่อเป็น mapping ว่างจะเติม
? ให้อัตโนมัติเพื่อให้พฤติกรรมของลิงก์สอดคล้องกัน
- รองรับการรวมอาร์กิวเมนต์แบบหลาย mapping ทำให้ประกอบ query parameter ได้ง่ายขึ้น
สรุป
- ใน Django 6.0 มีผู้มีส่วนร่วม 174 คน
และรวมการปรับแต่งประสิทธิภาพกับการแก้บั๊กจำนวนมาก
- การอัปเกรดช่วยยกระดับทั้ง ความปลอดภัย ความสามารถในการบำรุงรักษา และประสบการณ์นักพัฒนา(DX) โดยรวม
- สามารถดูการเปลี่ยนแปลงเพิ่มเติมได้จาก release note อย่างเป็นทางการ
1 ความคิดเห็น
ความเห็นจาก Hacker News
ใช้ Django ที่บริษัทแบบเป็นครั้งคราวมาหลายปีแล้ว โดยรวมชอบนะ แต่ ORM ยังรู้สึกว่ายากอยู่
ตอนนี้เพิ่งเข้าใจว่า Django เป็นเฟรมเวิร์กที่มีแนวทางชัดเจน และต้องทำตาม ‘วิถีของ Django’
ปัญหาคือต้องจัดการกับ ฐานข้อมูลหลายตัว ของหลายหน่วยธุรกิจ เลยต้องคอยปรับตามความแปลกเฉพาะของแต่ละระบบทุกครั้ง
สุดท้ายก็เลยปิด
managedใช้inspectdbดึงสคีมาเข้ามา แล้วลบตารางที่ไม่อยากเปิดให้เว็บเห็นออกด้วยมือสำหรับเว็บแอปที่สร้างใหม่ Django ก็ยังเป็นตัวเลือกที่ดีที่สุดอยู่ดี
Django ไม่ได้เก็บสถานะสคีมาควบคู่ไปกับโค้ด เลยต้องอนุมานสถานะปัจจุบันทุกครั้งที่รันคำสั่งกับ DB
การนิยามสถานะ DB ผ่านโค้ดของโมเดลมีข้อจำกัดในตัวมันเอง
ฉันชอบแนวทางแบบ Rails มากกว่า ที่จัด migration ด้วยคำสั่ง DB แบบชัดเจน แล้วค่อยวางโมเดลทับลงไป
อินเทอร์เฟซ Manager ทำให้งงในตอนแรก แต่ เครื่องมือ migration นี่ดีมากจริง ๆ
ได้ทั้งความยืดหยุ่นของการจูน SQL และความสะดวกของ Django ไปพร้อมกัน
แค่อย่าลืมสร้างมันไว้ในสคริปต์ migration ด้วย
ชอบมากที่ Django ค่อย ๆ ปรับปรุงอย่างสม่ำเสมอ ในทุกรีลีส
โดยเฉพาะเวอร์ชัน 6.0 ที่มีฟีเจอร์มีประโยชน์หลายอย่าง เลยน่าสนใจมาก
คำพูดที่ว่าเทคโนโลยีที่เชื่อถือได้จะต้องน่าเบื่อนั้นไม่จริงเลย มันควรพัฒนาแบบนี้แหละ
ตอนนี้อาศัยอยู่ใกล้กับสถานที่กำเนิดของ Django พอดี
เสริมอีกนิด ตอนนี้กำลังหางานตั้งแต่เมื่อวาน ถ้าใครกำลังมองหา นักพัฒนา Django มากประสบการณ์ ติดต่อมาได้เลย (oldspiceap@gmail.com)
โค้ดหรือบล็อกที่ Adam เขียน อ่านแล้วคุ้มค่าเสมอ
รอดูว่า เฟรมเวิร์ก tasks จะพัฒนาไปอย่างไรต่อ
แต่ก็แอบเสียดายนิดหน่อยที่ Django-Q2 ตัวเยี่ยมถูกพูดถึงรวมกับ Celery
มันมีบั๊กเยอะ แต่ฐานผู้ใช้ใหญ่มากจนแทบไม่ค่อยเจอปัญหาที่ไม่มีใครเคยเจอมาก่อน
เคยใช้คู่ Celery + RabbitMQ จัดการข้อความวันละหลายสิบล้านรายการได้อย่างเสถียร
มันยังคงเป็นโซลูชันแรก ๆ ที่ควรพิจารณาอยู่ดี
ในสแตกอื่นก็ใช้ Kafka ด้วย แต่กรณีนั้นเป็น use case อีกระดับไปเลย
ใช้ Django มาราว 5–6 ปี แม้จะมีข้อดีแบบ ‘แบตเตอรี่มาครบ’ ชัดเจน แต่โดยรวมก็ยัง รู้สึกว่าหนัก
ฟีเจอร์ template partial ดูดีมาก
หนึ่งในเหตุผลที่ React ได้รับความนิยมคือ การนำโค้ดกลับมาใช้ซ้ำ และดูเหมือน Django ก็กำลังไปในทิศทางนั้น
ดูตัวอย่างได้ที่ โค้ดนี้
ฉันใช้ Odoo เป็นหลัก แต่ก็เคยแตะ Django และ Celery มาบ้าง
ในฐานะคนที่ใช้ โมดูล OCA queue ของ Odoo บ่อยมาก
เลยสงสัยมาตลอดว่าทำไม Django ถึงไม่ใช้ความสามารถ LISTEN/NOTIFY ของ Postgres
อาจเป็นเพราะฉันไม่คุ้นกับอีโคซิสเต็ม Django ก็ได้
Template Partials กับ HTMX ให้ความรู้สึกเหมือนเวอร์ชัน Django ของ Rails View Components + Stimulus
และก็ดีใจที่ฟีเจอร์ Tasks ได้รับการรองรับอย่างเป็นทางการ
ฉันใช้ Django มาตั้งแต่ยุค 1.x ตั้งแต่สมัยที่ ยังไม่มี ORM
เลยแปลกใจมากที่เพิ่งมีฟีเจอร์รัน task เพิ่มเข้ามาตอนนี้
ไม่ได้จะวิจารณ์นะ แค่มองว่าเป็นวิวัฒนาการที่น่าสนใจ
มันจะรวมแต่ฟีเจอร์ที่ผ่านการพิสูจน์มาแล้ว และให้ความสำคัญกับ LTS กับเสถียรภาพของ API
เพราะแบบนี้ ต่อให้มีเวอร์ชันใหม่ออกมา ก็แทบไม่ต้องเขียนแอปใหม่ทั้งก้อน
ตอนนั้นยังเรียบง่าย แต่ก็ไม่จำเป็นต้องใช้ raw SQL อยู่พักใหญ่เลย
มีการถกเถียงเพิ่มเติมต่อในเธรดนี้
ฉันใช้ Django คู่กับ HTMX แล้วรู้สึกว่า เทมเพลตแบบแยกเป็นคอมโพเนนต์ มันใช้งานยากมาก
เลยทำไลบรารีคอมโพเนนต์บน Python ชื่อ Compone ขึ้นมาเอง
มันใช้ได้ไม่ใช่แค่กับ Django แต่กับทุก Python web framework และให้ ประสบการณ์พัฒนาที่ลื่นไหลกว่า มาก