เวลาดึงข้อมูลจาก Model เช่น
blogs = Blog.objects.all() # ได้ QuerySet ของบล็อกหลายๆ อัน print blogs[0].title print blogs[0].body print blogs[1].title print blogs[1].body
จะเห็นว่าเราใช้ QuerySet ได้เหมือนเป็นอาเรย์หรือ list เลย
แต่สิ่งที่ต้องระวังคือ blogs เป็น QuerySet ไม่ใช่ list
เวลาอัพเดทข้อมูลใน model ต้องระวัง
bug แบบนี้
blogs[0].title = "New Title" blogs[0].body = "new content" blogs[0].save()
ถ้ารันโค้ดข้างบนแล้ว blogs[0] จะไม่เปลี่ยนแปลงค่าอะไรเลย เพราะ:
- blogs[0] ในแต่ละบรรทัดเป็น object คนละอันกัน (คนละ instance กัน)
- การเรียก blogs[0] แต่ละครั้ง QuerySet จะให้ object ใหม่ทุกครั้ง ทำให้การกำหนดค่ามีผลกับ object ในบรรทัดนั้นเฉยๆ
- blogs[0].save() ในบรรทัดที่ 3 จะอ่านค่า blogs[0] จาก database และ save() กลับไปโดยยังไม่ได้แก้ไขอะไรเลย
ที่ถูกต้องควรเป็น
b = blogs[0] b.title = "New Title" b.body = "new content" b.save()
แต่ถ้าอยากใช้ได้เหมือน list จริงๆ ก็ทำได้โดยบังคับให้ Django มัน evaluate QuerySet ให้กลายเป็น list ด้วยฟังก์ชัน list
เช่น
blogs = list(blogs)
มีข้อเสียคือ
* มี large memory overhead
* blogs.filter ต่อไม่ได้… เพราะโดน evaluate ไปแล้ว