จากการลองเล่น 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
โดยถ้าเราตั้งค่าเป็นTrue
Django จะไปดูจาก ตัวแปร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)