دليل شامل لفهم نظام قوالب Django: الوراثة، static، وأفضل الممارسات

مقدمة عن نظام القوالب في Django

عند تطوير تطبيقات الويب، من الضروري أن نفصل منطق البرمجة عن واجهة العرض، بحيث يمكن للمطورين التركيز على منطق التطبيق (Back-end) بينما يهتم المصممون بشكل وتصميم الواجهة (Front-end). لهذا السبب، وفّر إطار العمل Django نظامًا قويًا للقوالب يُعرف باسم Django Template Language أو DTL.

نظام القوالب في Django هو عبارة عن محرك بسيط ومرن يسمح بدمج البيانات التي يعالجها السيرفر مع صفحات HTML. يساعد هذا النظام في إنشاء صفحات ويب ديناميكية بطريقة منظمة وسهلة الصيانة. يمكن عن طريقه عرض المتغيرات القادمة من الـ views، استخدام جمل تحكم كـ if و for داخل القالب، واستخدام وسوم خاصة للتعامل مع الملفات الثابتة (كالصور وملفات CSS وJavaScript)، أو لتضمين قوالب أخرى أو وراثة تصاميم أساسية.

يمتاز Django Template بأنه خفيف وآمن؛ حيث يمنع تنفيذ أي كود Python مباشر داخل القوالب، مما يعزز من أمان التطبيق ويمنع العديد من الثغرات الشائعة مثل XSS (Cross-site Scripting).


بنية ملف القالب في Django

لإنشاء نظام قوالب منظم داخل مشروع Django، يجب أولًا فهم كيفية تنظيم ملفات القوالب ضمن هيكل المشروع.
بشكل افتراضي، يبحث Django عن ملفات القوالب داخل مجلد يُسمى templates، والذي يمكن وضعه إما في جذر المشروع أو داخل كل تطبيق (App) على حدة.

مثال على هيكل مجلد القوالب:

my_project/
│
├── my_app/
│   ├── templates/
│   │   └── my_app/
│   │       └── example.html
│   └── views.py
│
├── my_project/
│   └── settings.py

كيفية تعريف مكان القوالب في إعدادات المشروع:

في ملف settings.py، يتم تعريف مكان ملفات القوالب من خلال إعداد TEMPLATES:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates'],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                # ...
            ],
        },
    },
]
  • DIRS: قائمة بالمجلدات التي يريد Django أن يبحث فيها عن القوالب العامة.

  • APP_DIRS: عند تفعيلها بـ True، يبحث Django تلقائيًا عن مجلد templates داخل كل تطبيق.

امتداد ملفات القوالب:

عادةً ما يتم إنشاء ملفات القوالب باستخدام الامتداد .html مثل:

index.html
base.html
product_list.html

ملاحظة:

من الأفضل دائمًا داخل كل تطبيق أن تنشئ مجلدًا باسم التطبيق نفسه داخل templates، لتفادي التعارض عند وجود أكثر من تطبيق بنفس اسم ملف القالب.

مثال:

my_app/
├── templates/
│   └── my_app/
│       └── home.html

وبذلك، حين تقوم باستدعاء القالب من الـ view يمكنك تحديد مساره:

return render(request, 'my_app/home.html', context)

المتغيرات في القالب (Variables)

تعتمد معظم صفحات الويب الديناميكية على عرض بيانات تتغير مع كل طلب أو حسب تفضيلات المستخدم، مثل اسم المستخدم، تفاصيل منتج، أو قائمة مقالات. في Django Template، يمكن تمرير هذه البيانات من منطق التطبيق (views) إلى ملفات القالب بكل سلاسة، وعرضها باستخدام ما يُعرف بـ المتغيرات (Variables).

كيفية تمرير المتغيرات من الـ View:

في Django، يتم إرسال المتغيرات إلى القالب من خلال دالة render() أو render_to_response()، حيث يتم وضع المتغيرات داخل قاموس (dictionary) يُعرف باسم context.

مثال:

from django.shortcuts import render

def home_view(request):
    context = {
        'user_name': 'أحمد',
        'site_title': 'موقعي الشخصي'
    }
    return render(request, 'my_app/home.html', context)

في هذا المثال، تم تمرير متغيرين: user_name و site_title إلى القالب.


كيفية عرض المتغيرات داخل القالب:

لعرض المتغيرات داخل ملفات القالب، يتم استخدام الصيغة:

{{ variable_name }}

مثال:

<h1>مرحبا {{ user_name }}!</h1>
<title>{{ site_title }}</title>

الناتج في المتصفح:

<h1>مرحبا أحمد!</h1>
<title>موقعي الشخصي</title>

التعامل مع المتغيرات الفارغة:

إذا كان من المحتمل أن يكون المتغير فارغًا أو غير معرف، يمكن التعامل معه باستخدام فلتر default:

{{ user_name|default:"زائر" }}

في حال عدم وجود قيمة للمتغير user_name، سيتم عرض "زائر".


المتغيرات المعقدة (Nested Variables)

يمكن التعامل مع المتغيرات المعقدة كالكائنات أو القوائم أو القواميس:

مثال:

context = {
    'product': {
        'name': 'هاتف ذكي',
        'price': 1200
    }
}

لعرض اسم المنتج:

{{ product.name }}

لعرض السعر:

{{ product.price }}

ملاحظات هامة:

  • Django يقوم بتعقيم (sanitize) المتغيرات تلقائيًا لحمايتك من هجمات XSS، لذلك لا داعي للقلق من إدخال المستخدمين.

  • يمكن استخدام الفلاتر (Filters) مع المتغيرات لتعديل شكل العرض مباشرة (سنتناولها بالتفصيل لاحقًا).

العلامات (Template Tags) في Django Template

إلى جانب المتغيرات، يوفّر نظام القوالب في Django مجموعة قوية من الوسوم (Tags) التي تتيح التحكم في سير عرض المحتوى داخل القالب.
يمكن تشبيه الوسوم بالأوامر البرمجية المصغّرة التي تنفّذ مهامًا معينة مثل التحكم بالتدفق (شروط وحلقات تكرار)، إدراج قوالب أخرى، تحميل ملفات ثابتة، أو توليد روابط.

تُكتب الوسوم باستخدام الأقواس {% %} داخل القالب.

أنواع العلامات في Django Template

علامات التحكم بالتدفق (Control Flow Tags)

1. وسم if

يُستخدم لتنفيذ شرط معين:

{% if user_name %}
    <p>مرحبًا {{ user_name }}</p>
{% else %}
    <p>مرحبًا زائر!</p>
{% endif %}

2. وسم for

لتكرار عناصر قائمة أو مجموعة:

{% for product in products %}
    <li>{{ product.name }} - {{ product.price }} ريال</li>
{% empty %}
    <li>لا توجد منتجات متاحة</li>
{% endfor %}
  • {% empty %}: يمكن استخدامها داخل الحلقة للتعامل مع الحالة الفارغة.

وسوم تحميل الموارد (Loading Resources)

1. وسم load static

يُستخدم لتحميل ملفات ثابتة (كالصور و CSS و JS)

{% load static %}
<img src="{% static 'images/logo.png' %}" alt="الشعار">

2. وسم url

ينشئ رابط URL باستخدام اسم المسار (من urls.py)

<a href="{% url 'home' %}">الصفحة الرئيسية</a>

ويمكن تمرير وسائط للـ URL:

<a href="{% url 'product_detail' product.id %}">{{ product.name }}</a>

وسوم توريث القوالب (Template Inheritance)

وسم extends

لتوريث تصميم من قالب أساسي:

{% extends 'base.html' %}

وسم block

لتحديد أقسام قابلة للتعديل داخل القالب الأساسي:

{% block content %}
    <h1>محتوى الصفحة</h1>
{% endblock %}

3. وسم include

لتضمين قالب آخر داخل القالب الحالي:

{% include 'includes/navbar.html' %}

مفيد جدًا لتضمين شريط التنقل، الفوتر، أو أي مكون متكرر.


وسوم أخرى مفيدة

1. now

لعرض التاريخ والوقت الحالي:

{% now "Y-m-d H:i" %}

2. comment

لإضافة تعليق لا يظهر في الصفحة ولا يتم تفسيره:

{% comment %}
    هذا تعليق داخل القالب
{% endcomment %}

ملاحظات مهمة:

  • جميع الوسوم يجب أن تُكتب بين {% %}.

  • يجب إغلاق أي وسم تحكم (كـ if, for, block) بوسم النهاية الخاص به.

  • يمكنك كتابة وسومك الخاصة (Custom Tags) باستخدام مكتبة template library (في حال المشاريع الكبيرة والمتخصصة).


مثال تطبيقي شامل:

{% load static %}
{% extends 'base.html' %}

{% block content %}
    <h1>مرحبا {{ user_name }}</h1>

    <ul>
    {% for product in products %}
        <li>{{ product.name }} - {{ product.price }} ريال</li>
    {% empty %}
        <li>لا توجد منتجات حاليًا</li>
    {% endfor %}
    </ul>

    <img src="{% static 'images/banner.png' %}" alt="بانر">

{% endblock %}

الفلاتر (Filters) في Django Template

الفلاتر في Django Template هي أدوات صغيرة تُستخدم لتعديل قيمة المتغيرات أثناء العرض داخل القالب، دون الحاجة لتغيير القيمة الأصلية في الـ view.
يمكن استخدامها لسلسلة نصوص، تنسيق تواريخ، التعامل مع القوائم، وغيرها من العمليات البسيطة.

تُكتب الفلاتر باستخدام علامة | بعد المتغير.

كيفية استخدام الفلاتر

الصيغة:

{{ variable|filter_name }}

ويمكن تمرير وسيط للفلاتر إن احتاج:

{{ variable|filter_name:"value" }}

أشهر فلاتر Django Template

فلاتر النصوص

  • lower : يحوّل النص إلى حروف صغيرة

    {{ "Django"|lower }}
    

    النتيجة: django

  • upper : يحوّل النص إلى حروف كبيرة

    {{ "django"|upper }}
    

    النتيجة: DJANGO

  • title : يحوّل أول حرف من كل كلمة إلى حرف كبير

    {{ "web development"|title }}
    

    النتيجة: Web Development

  • length : يُرجع عدد الأحرف أو العناصر

    {{ "Django"|length }}
    

    النتيجة: 6

  • truncatechars : يقطع النص بعد عدد معين من الأحرف

    {{ "هذا نص طويل"|truncatechars:7 }}
    

    النتيجة: هذا نص...


فلاتر القوائم

  • first : يُرجع أول عنصر

    {{ products|first }}
    
  • last : يُرجع آخر عنصر

    {{ products|last }}
    
  • join : يربط عناصر القائمة بفاصل معين

    {{ items|join:", " }}
    

فلاتر التواريخ والأوقات

  • date : يعرض التاريخ بتنسيق معين

    {{ post.date|date:"Y-m-d" }}
    
  • time : يعرض الوقت

    {{ post.created_at|time:"H:i" }}
    
  • timesince : يحسب الزمن منذ تاريخ معين

    {{ post.created_at|timesince }}
    

فلاتر القيمة الافتراضية

  • default : يعرض قيمة بديلة إن كان المتغير فارغًا

    {{ username|default:"زائر" }}
    
  • default_if_none : يعرض قيمة بديلة فقط إن كان المتغير None

    {{ price|default_if_none:"غير محدد" }}
    

فلاتر منطقية

  • yesno : يعرض نصًا مختلفًا حسب قيمة المتغير (True / False / None)

    {{ is_active|yesno:"نعم,لا,غير محدد" }}
    

ملاحظات مهمة

  • يمكن دمج عدة فلاتر معًا

    {{ name|lower|truncatechars:5 }}
    
  • بعض الفلاتر تقبل وسيطًا، وبعضها لا يقبل

  • يمكنك إنشاء فلاترك الخاص باستخدام مكتبة template.Library


مثال تطبيقي للفلاتر

{% for product in products %}
    <li>
        {{ product.name|title }} - 
        {{ product.price|default:"غير محدد" }} ريال
        <small>إضافة منذ: {{ product.created_at|timesince }}</small>
    </li>
{% endfor %}

وراثة القوالب (Template Inheritance) في Django

وراثة القوالب من أقوى خصائص نظام Django Template.
تسمح لك بتصميم قالب رئيسي (base template) يحتوي على الهيكل العام للصفحات (مثل رأس الصفحة، قائمة التنقل، الفوتر...) ثم تقوم الصفحات الفرعية بتحديد الأجزاء التي ترغب بتغييرها فقط دون الحاجة إلى تكرار بقية المحتوى.


فكرة العمل

  1. إنشاء قالب رئيسي base.html

  2. تحديد أماكن المتغيرات باستخدام {% block %} و {% endblock %}

  3. القوالب الفرعية تستخدم {% extends 'base.html' %} وتحدد المحتوى داخل الـ block المطلوب


مثال تطبيقي

1. القالب الرئيسي: base.html

{% load static %}
<!DOCTYPE html>
<html lang="ar">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}موقعي{% endblock %}</title>
    <link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>
<body>

    <header>
        <img src="{% static 'images/logo.png' %}" alt="شعار الموقع">
        <nav>
            <a href="{% url 'home' %}">الرئيسية</a>
            <a href="{% url 'about' %}">عن الموقع</a>
        </nav>
    </header>

    <main>
        {% block content %}
        <!-- محتوى الصفحة سيوضع هنا -->
        {% endblock %}
    </main>

    <footer>
        <p>جميع الحقوق محفوظة © 2025</p>
    </footer>

</body>
</html>

شرح النقاط:

  • {% load static %}: لتحميل الملفات الثابتة

  • {% static '...' %}: مسار ملفات CSS أو صور أو JS

  • {% block title %}: يسمح للصفحات بتغيير عنوان الصفحة

  • {% block content %}: يحدد مكان محتوى الصفحة المتغير


2. القالب الفرعي: home.html

{% extends 'base.html' %}

{% block title %}الرئيسية{% endblock %}

{% block content %}
    <h1>مرحبًا بكم في الصفحة الرئيسية</h1>
    <p>هذا نص ترحيبي بالمستخدمين.</p>
{% endblock %}

3. القالب الفرعي: about.html

{% extends 'base.html' %}

{% block title %}عن الموقع{% endblock %}

{% block content %}
    <h1>عن الموقع</h1>
    <p>موقع تعليمي يهتم بشرح Django بطريقة مبسطة.</p>
{% endblock %}

كيفية استخدام ملفات static مع الوراثة

بما أن القالب الرئيسي base.html يقوم بتحميل ملفات CSS و الصور باستخدام {% static %}،
فجميع الصفحات الفرعية التي ترث منه ستستفيد تلقائيًا من هذه الموارد دون الحاجة لتعريفها من جديد.

مثال:

  • style.css

  • images/logo.png

بشرط أن تكون الملفات موجودة داخل مجلد static/ الخاص بالتطبيق أو المشروع.


مسار ملفات static

هيكل مجلد static النموذجي:

project/
    app_name/
        templates/
            base.html
            home.html
            about.html
        static/
            css/
                style.css
            images/
                logo.png

في إعدادات Django:

STATIC_URL = '/static/'

ملخص:

  • القالب الرئيسي يحتوي على تصميم عام وأماكن قابلة للتعديل باستخدام {% block %}

  • القوالب الفرعية تستخدم {% extends 'base.html' %} وتحدد فقط المحتوى داخل الـ {% block %}

  • ملفات static تُحمل مرة واحدة في base.html وتُستخدم في كل الصفحات الفرعية.

ممتاز جدًا — دعنا ننتقل الآن إلى

أهم الممارسات عند العمل مع Django Templates

عند بناء تطبيقات Django باستخدام نظام القوالب، هناك مجموعة من الممارسات والنصائح التي تساعد على كتابة قوالب نظيفة، منظمة، قابلة للصيانة، وأكثر أمانًا وأداءً. سأرتبها لك بشكل واضح:


1. استخدم قالب رئيسي موحّد (base.html)

  • أنشئ دائمًا قالبًا أساسيًا يحتوي على التصميم العام (الرأس، التنقل، الفوتر)

  • استخدم {% block %} لتحديد المناطق المتغيرة

  • اجعل كل القوالب الفرعية ترث منه باستخدام {% extends %}
    → هذا يقلل تكرار الكود ويجعل التعديلات لاحقًا أسهل


2. التحميل المسبق للـ static والوسوم

  • دائمًا اكتب {% load static %} في أعلى القالب الرئيسي

  • في حال وجود وسوم مخصصة (custom tags) استخدم {% load your_tags %}


3. تجنب المنطق البرمجي داخل القوالب

  • القوالب مخصصة للعرض فقط، فلا تُدرج منطقًا معقدًا مثل الحلقات المتداخلة، أو العمليات الحسابية الكبيرة

  • قم بتجهيز البيانات مسبقًا في الـ views وأرسلها إلى القالب بشكل جاهز للعرض


4. استغل الفلاتر والوسوم الجاهزة

  • استخدم فلاتر Django مثل date، length، default لتنسيق البيانات ببساطة

  • أنشئ وسوم مخصصة عند الحاجة بدلًا من إدخال منطق معقد داخل القالب


5. تنظيم الملفات الثابتة (static)

  • ضع ملفات CSS و JS و الصور داخل مجلد static/ لكل تطبيق أو في static/ عام للمشروع

  • قم بتحميلها في base.html مرة واحدة
    → مما يحافظ على سرعة التحميل وتوحيد تصميم الصفحات


6. استخدم {% url %} بدل الروابط الثابتة

  • لا تكتب الروابط كنصوص، بل استخدم {% url 'view_name' %}
    → حتى لا تتأثر الروابط عند تغيير المسارات في المشروع

مثال:

<a href="{% url 'home' %}">الرئيسية</a>

7. احرص على حماية القوالب من الثغرات

  • Django يقوم بتعقيم البيانات بشكل تلقائي (auto-escaping)
    → لكن تجنب استخدام safe إلا عند الضرورة القصوى وبعد التحقق من المحتوى

مثال:

{{ post.content|safe }}
  • لا تعرض بيانات المستخدم كما هي دون تنظيفها


8. تقسيم القوالب إلى مجلدات

  • نظم قوالب كل تطبيق داخل مجلد يحمل اسم التطبيق

  • استخدم أسماء ملفات واضحة
    مثال:

templates/
    app_name/
        base.html
        home.html
        about.html

9. استخدم التعليقات داخل القوالب

  • لتوثيق الأجزاء المهمة

{# هذا تعليق لن يظهر في الصفحة #}

10. تحسين الأداء بتقليل الاستعلامات داخل القوالب

  • لا تكتب حلقات على بيانات لم تتم معالجتها أو ترتيبها مسبقًا

  • في الـ views قم باستخدام:

    • select_related للعلاقات ForeignKey

    • prefetch_related للعلاقات ManyToMany


ملخص سريع:

الممارسةالسبب
قالب رئيسيتقليل التكرار
{% load static %}تحميل ملفات ثابتة
عدم كتابة منطق في القالبللفصل بين العرض والمعالجة
استخدام الفلاترلتنسيق بسيط
تنظيم staticلتحسين الأداء
{% url %}تجنب الروابط الثابتة
حماية القوالبمنع الثغرات
تنظيم مجلدات القوالبتسهيل الوصول
التعليقاتتوثيق الكود
تحسين الاستعلاماتتقليل عدد الطلبات لقاعدة البيانات

نظام القوالب في Django يقدم طريقة مرنة وفعالة لفصل منطق التطبيق عن العرض، مما يسهل تطوير واجهات استخدام نظيفة ومنظمة. من خلال اعتماد وراثة القوالب واستخدام الوسوم والفلاتر المدمجة في Django، يمكن توفير تجربة تطوير مرنة، وصيانة أسرع للمشاريع مع تقليل التكرار وتحسين الأداء.

لقد استعرضنا في هذا المقال:

  • كيفية إعداد قالب رئيسي (base.html)

  • آلية وراثة القوالب في Django

  • كيفية التعامل مع ملفات static داخل القوالب

  • أهم الممارسات والنصائح العملية التي تساعد على كتابة قوالب آمنة وفعالة وسهلة التوسعة

بتطبيق هذه الممارسات ستحافظ على كود واضح ومنظم، يسهل تعديله لاحقًا دون التأثير على بقية أجزاء المشروع.

إذا كنت ترغب بالتعمق أكثر، يمكنك الرجوع إلى التوثيق الرسمي:
وثائق قوالب Django

حول المحتوى:

تعرف في هذا الدليل الكامل على كيفية استخدام نظام القوالب في Django بشكل احترافي، مع شرح وراثة القوالب، التعامل مع ملفات static، وأهم الممارسات لكتابة قوالب نظيفة وآمنة وفعالة.