จากการลองเล่น framework ตัวหนึ่งชื่อ Django (จังโก้) เพื่อนำมาใช้ในการทำ Web GUI สำหรับ project หนึ่ง
พอลองเล่นมาถึง Writing your first Django app, part 3 เกิดงงเรื่อง directory structure ของ template ที่ต้องเป็น project_name/app_name/templates/app_name/ และการสั่ง render template ต้องอ้างอิงชื่อเป็น app_name/home.html ซึ่งเค้าบอกว่าเป็น Best Practice
ที่ผมงงคือ... ทำไม directory structure ต้องมี app_name ซ้ำ 2 ครั้งเลยล่ะ ครั้งเดียวมันน่าจะรู้แล้วไหม และ ตอนเรียก template มา render ก็ต้องใส่ app_name ข้างหน้าชื่อ template อีก ซึ่งเราทำที่ app นี้อยู่แล้วทำไม่ยังต้องระบุอีกล่ะ
OK! ถ้ามันเป็น Best Practice ความไม่ make sense ต้องมีคำอธิบาย
มาดูกัน ผมเจออะไร (ต้องบอกก่อนว่าผมเพิ่งหัดใช้นะครับ เรื่องนี้หลายคนอาจรู้อยู่แล้ว 😁)
ใน settings.py ของ Django ที่เป็น "DjangoTemplate" จะเป็นแบบนี้
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
เราจะสนใจ 2 parameters นี้ก่อนคือ
-
DIRSคือ path ที่เราต้องการให้ django ไปค้นหา เป็น list of strings (default = []) -
APP_DIRSคือ เป็น boolean บอกว่าให้หา template ใน directory ของ app หรือ ไม่ (default = True)
โดย พฤติกรรมในการหา template ของ "DjangoTemplate" จะเป็นลำดับตามนี้
-
หาใน
DIRSก่อน โดยหาตามลำดับของ list ที่เรากำหนด
เช่นDIRS = ['path/to/template1', 'path/to/template2', 'path/to/template3']จะหาตามลำดับดังนี้/path/to/template1/
/path/to/template2/
/path/to/template3/ -
หาใน
APP_DIRSโดยถ้าเราตั้งค่าเป็นTrueDjango จะไปดูจาก ตัวแปรINSTALLED_APPSในsettings.pyซึ่ง เป็น list of string เช่นINSTALLED_APPS = ['app-a', 'app-b', 'app-c']Django จะหาตามลำดับของ list นี้ ดังนี้/path/to/project/app-a/templates/
/path/to/project/app-b/templates/
/path/to/project/app-b/templates/
จากตัวอย่างข้างต้น ลำดับของ directory ที่ Django ใช้หา template คือ
/path/to/template1/
/path/to/template2/
/path/to/template3/
/path/to/project/app-a/templates/
/path/to/project/app-b/templates/ 👈 เราจะเขียน template ที่นี่
/path/to/project/app-b/templates/
ด้วย logic การทำงานแบบนี้ ถ้าเราเขียน template ที่ app-b ชื่อ home.html แล้วเราระบุ ชื่อ template ในการ render แค่ home.html ถ้าบังเอิญว่า app-a ก็มี home.html อยู่เช่นกัน มันจะไป render home.html ของ app-a แทน เพราะมันหาเจอก่อน
ด้วยพฤติกรรมการทำงานแบบนี้ เราจึงต้องทำตาม Best Practice โดยสร้าง sub directory ที่เป็นชื่อ app ใต้ directory templatate ของ app นั้นๆ ด้วย ดังนี้
/path/to/template1/
/path/to/template2/
/path/to/template3/
/path/to/project/app-a/templates/app-a/
/path/to/project/app-b/templates/app-b/ 👈 เราจะเขียน template ที่นี่
/path/to/project/app-b/templates/app-c/
และเวลาที่เราเรียก template มาใช้งานก็จะเรียกด้วยการระบุชื่อ template ดังนี้ app-b/home.html
ด้วยวิธีนี้ การ render จะไม่หยิบ template มาผิด app
Top comments (0)