IS231 · Lecture 07 · Django Templates

Django — Templates and Dynamic Pages

المحاضرة دي هي الجسر بين صفحة HTML ثابتة وبين Web Application حقيقي. هنفهم إزاي الـ View يجهز البيانات، يبعتها كـ context، والـ Template يعرضها باستخدام {{ variable }} و{% tag %} قبل ما المتصفح يستلم HTML النهائي.

12
شرح مرتب
7
Exam Q's
1
Mini Project
01

مكان الـ Template في Django MVT

Model View Template — مين بيعمل إيه؟

الفكرة الأساسية

Django مبني على نمط MVT: الـ Model مسؤول عن البيانات، الـ View مسؤول عن استقبال الـ Request وتجهيز البيانات، والـ Template مسؤول عن شكل العرض النهائي للمستخدم.

Browserيرسل Request
URLconfيختار View
Viewيبني context
Templateيعرض HTML
Responseيرجع للمتصفح
نقطة امتحانية الـ Template هو أقرب جزء للـ presentation layer. الـ View في Django مش هو شاشة العرض؛ هو Python function/class بيربط الطلب بالبيانات والـ template.

Model

بيمثل البيانات وقواعد التعامل مع الـ Database.

View

بيستقبل الـ Request، يجهز البيانات، ويرجع HttpResponse غالبا عن طريق render().

Template

ملف HTML فيه Django Template Language عشان يعرض البيانات بشكل Dynamic.

02

Static HTML vs Dynamic Template

ليه أصلا محتاجين Templates؟

Static HTML
  • المحتوى مكتوب ثابت داخل الملف.
  • لو فتحت الصفحة 100 مرة هتشوف نفس الكلام.
  • مناسب لصفحة بسيطة جدا، لكنه ضعيف مع Student Portal أو E-commerce.
  • لو عندك 100 طالب، مش منطقي تعمل 100 ملف HTML.
Django Template
  • HTML عادي لكن فيه placeholders زي {{ student_name }}.
  • بيستقبل values من الـ View من خلال context dictionary.
  • يقدر يعمل loop على قائمة records.
  • يقدر يظهر أو يخفي أجزاء باستخدام {% if %}.
المتصفح بيشوف إيه؟

المتصفح عمره ما بيشوف {{ name }} أو {% for %} كـ Django syntax. الـ Template بيتعمله processing على الـ Server، وبعدها المتصفح يستلم HTML جاهز.

final HTML received by browser
<h1>Welcome Mona</h1>
<p>Your academic level is 2</p>
03

Where Do We Store Templates?

تنظيم الملفات قبل ما الصفحة تكبر

الترتيب الآمن داخل الـ App

الطريقة الشائعة والأكثر أمانا هي إن كل app يبقى جواه folder اسمه templates، وجواه folder باسم الـ app نفسه. السبب: لو عندك أكتر من app وفيهم ملف اسمه list.html، Django ممكن يتلخبط بين الملفات.

recommended structure
students/
  templates/
    students/
      home.html
      list.html
      profile.html
قاعدة حفظ المسار students/templates/students/list.html أحسن من templates/list.html داخل app، لأنه بيمنع name collisions بين التطبيقات.
Project-level templates folder

أحيانا بنعمل folder عام اسمه templates على مستوى المشروع كله. وقتها لازم نضيفه في إعدادات TEMPLATES داخل settings.py.

settings.py
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates'],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
فخ امتحاني لما تعمل django-admin startproject، Django مش بيعمل لك templates file/folder جاهز تلقائيا؛ أنت اللي بتنظمه حسب مشروعك.
04

Using render() and URL Flow

إزاي الـ View يرجع Template؟

أول Template File

ملف الـ Template في البداية ممكن يكون HTML عادي جدا. الديناميكية هتيجي لما الـ View يبعتله data.

students/templates/students/home.html
<!DOCTYPE html>
<html>
<head>
  <title>Students Home</title>
</head>
<body>
  <h1>Welcome to the Students App</h1>
  <p>This page is rendered by Django.</p>
</body>
</html>
views.py

دالة render() بتاخد request واسم الـ template، وترجع HttpResponse جاهز.

views.py
from django.shortcuts import render

def home(request):
    return render(request, 'students/home.html')
urls.py

الـ URLconf هو اللي بيستقبل path من المتصفح ويقرر أي View يتنفذ.

urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='home'),
]
ترتيب مهم الـ Browser ما بيفتحش الـ Template مباشرة. المسار الطبيعي هو: Request → URLconf → View → Template → Response.
05

Context and Template Variables

إرسال values من Python إلى HTML

ما هو الـ context؟

الـ context هو dictionary: الـ keys هي الأسماء اللي هتستخدمها داخل الـ Template، والـ values هي البيانات الحقيقية. في الـ Template بنطبع قيمة variable باستخدام double curly braces: {{ variable_name }}.

views.py
from django.shortcuts import render

def welcome(request):
    context = {
        'student_name': 'Ali',
        'level': 2,
    }
    return render(request, 'students/welcome.html', context)
welcome.html
<h1>Welcome {{ student_name }}</h1>
<p>Your academic level is {{ level }}</p>
ملاحظات دقيقة على Variables
  • اسم الـ variable داخل template لازم يطابق key موجود في الـ context dictionary.
  • لو variable مش موجود، Django غالبا يعرض empty output بدل ما يطبع error واضح في الصفحة.
  • ممكن تبعت String أو Number أو List أو Object أو Model Instance.
  • الـ Template بيعرض البيانات، لكن الحسابات الثقيلة وقرارات الـ business logic مكانها الـ View أو Model.
خد بالك: المفتاح 'student_name' في الـ context هو اللي بيظهر في HTML كـ {{ student_name }}. اسم Python variable نفسه مش شرط يكون هو نفس الاسم.
06

Lists, for Loops, and empty

عرض records كتير بدل قيمة واحدة

Sending a List to the Template

معظم الصفحات الواقعية بتعرض list: courses, students, messages, notifications, comments. بنبعت الـ list في context عادي، وبعدها نستخدم {% for %} جوه الـ Template.

views.py
def course_list(request):
    courses = ['Python', 'Database', 'AI', 'Networks']
    return render(request, 'students/courses.html', {'courses': courses})
Template for Loop
courses.html
<h2>Registered Courses</h2>
<ul>
  {% for course in courses %}
    <li>{{ course }}</li>
  {% endfor %}
</ul>

الـ block بين {% for %} و{% endfor %} بيتكرر مرة لكل item في الـ list.

Handling an Empty List
if + for
<h2>Registered Courses</h2>
{% if courses %}
  <ul>
    {% for course in courses %}
      <li>{{ course }}</li>
    {% endfor %}
  </ul>
{% else %}
  <p>No courses found.</p>
{% endif %}
الأقوى: {% empty %}

داخل for في Django تقدر تستخدم {% empty %} كـ fallback لو الـ list فاضية.

for empty
<ul>
  {% for course in courses %}
    <li>{{ course }}</li>
  {% empty %}
    <li>No courses found.</li>
  {% endfor %}
</ul>
امتحاني جدا syntax بداية الـ loop هو {% for x in y %}، ولازم تقفله بـ {% endfor %}.
07

if Tag and Template Logic

إظهار أو إخفاء أجزاء من الصفحة

Template if Tag

الـ {% if %} بيخلي الـ Template يعرض HTML معين حسب condition. ممكن تستخدم {% elif %} و{% else %}، ولازم تقفل بـ {% endif %}.

result.html
<h2>Student Result</h2>

{% if mark >= 50 %}
  <p>Passed</p>
{% else %}
  <p>Failed</p>
{% endif %}
Logic in View vs Logic in Template
Good in the ViewGood in the Template
Database queriesDisplay variables
Complex calculationsSimple display conditions
Business rulesLoops for rendering lists
Preparing context dataFormatting output with filters
قاعدة مهمة الـ Template مش مكان نحط فيه logic تقيل. خليه readable: اعرض، كرر، اخفي/اظهر، وformat بس.
08

Objects, Dot Notation, and Filters

عرض attributes وتنسيق القيم

Displaying Object Attributes

لو بعتت object أو Model Instance باسم student، تقدر توصل للـ attributes باستخدام dot notation: {{ student.name }}. Django Template Language بيسهل الوصول للبيانات بدون Python parentheses.

profile.html
<h2>Student Profile</h2>
<p>Name: {{ student.name }}</p>
<p>Level: {{ student.level }}</p>
<p>Department: {{ student.department }}</p>
Looping Over Objects
students.html
<ul>
  {% for student in students %}
    <li>{{ student.name }} - Level {{ student.level }}</li>
  {% endfor %}
</ul>

كل iteration بيطلع object واحد من students، وتقدر تعرض attributes بتاعته.

Template Filters

الـ Filter بيغير طريقة عرض القيمة فقط، من غير ما يغير البيانات الأصلية. syntax بتاعه هو pipe: {{ value|filter }}.

FilterExampleUse
upper{{ name|upper }}تحويل النص لـ uppercase.
lower{{ name|lower }}تحويل النص لـ lowercase.
title{{ department|title }}أول حرف من كل كلمة capital.
length{{ students|length }}عدد الحروف أو عناصر list.
default{{ email|default:"No email" }}fallback لو القيمة empty.
truncatechars{{ text|truncatechars:20 }}اختصار النص بعد عدد characters.
date{{ created_at|date:"Y-m-d" }}تنسيق التاريخ.
join{{ courses|join:", " }}دمج عناصر list في string.
safe{{ content|safe }}اعتبار المحتوى HTML آمن، ويستخدم بحذر شديد.
escape{{ content|escape }}منع HTML rendering وعرضه كنص.
Security note لا تستخدم safe مع user input غير موثوق؛ ممكن يفتح باب XSS. الافتراضي في Django هو escaping لحماية الصفحة.
09

Template Inheritance and include

تقليل التكرار وبناء layout قابل لإعادة الاستخدام

The Problem of Repetition

لو كل صفحة فيها نفس navbar وfooter وHTML structure، أي تعديل بسيط هيتكرر في كل الملفات. Django بيحل المشكلة بـ template inheritance: ملف parent اسمه غالبا base.html، وصفحات child بتعمل {% extends %} وتملأ blocks.

base.html
students/base.html
<!DOCTYPE html>
<html>
<head>
  <title>{% block title %}Students App{% endblock %}</title>
</head>
<body>
  <header>Students Portal</header>

  {% block content %}
  {% endblock %}

  <footer>Faculty of Computers and AI</footer>
</body>
</html>
child template
students/courses.html
{% extends 'students/base.html' %}

{% block title %}Courses{% endblock %}

{% block content %}
  <h2>Registered Courses</h2>
  <p>This content replaces the content block.</p>
{% endblock %}
Rules of Template Inheritance
  • استخدم أسماء blocks واضحة زي title, content, sidebar, scripts.
  • حط {% extends %} في أعلى child template.
  • خلي base.html عام وقابل لإعادة الاستخدام، من غير تفاصيل page-specific.
  • أي content خارج blocks في child غالبا مش هيظهر بالطريقة اللي متوقعها.
Using include for Reusable Pieces

{% include %} بيستخدم لما تحب تدخل template صغير جوه template تانية، زي navbar.html أو alert.html أو student_card.html. الفرق: extends لهيكل الصفحة الكامل، وinclude لقطعة صغيرة قابلة لإعادة الاستخدام.

base.html
<body>
  {% include 'students/navbar.html' %}
  {% block content %}{% endblock %}
</body>
10

Static Files, url Tag, and csrf_token

إكمال بناء الصفحة الحقيقية

Loading Static Files

الـ Static files زي CSS, JavaScript, images مش بنكتب path كامل من جهازنا. بنستخدم نظام Django static: أول حاجة {% load static %}، وبعدها {% static 'path/file.css' %}.

base.html
{% load static %}

<link rel="stylesheet" href="{% static 'students/css/style.css' %}">
<img src="{% static 'students/images/logo.png' %}" alt="Logo">
خطأ متكرر نسيان {% load static %} قبل استخدام {% static %}.
Linking Pages with url Tag

{% url %} بيستخدم route name من urls.py بدل hard-coded path. لو path اتغير واسم route ثابت، اللينك يفضل شغال.

template links
<a href="{% url 'home' %}">Home</a>
<a href="{% url 'student_list' %}">Students</a>
<a href="{% url 'student_detail' student.id %}">View Profile</a>
csrf_token in Forms

أي form في Django يستخدم POST غالبا لازم يحتوي على {% csrf_token %} للحماية من Cross-Site Request Forgery.

form.html
<form method="post">
  {% csrf_token %}
  <input type="text" name="name">
  <button type="submit">Save</button>
</form>
Template Tags Cheat Sheet
Tagالغرضمثال
{% extends %}يرث من parent template.{% extends 'base.html' %}
{% block %}يحدد جزء child template يقدر يغيره.{% block content %}
{% include %}يدخل template صغيرة داخل أخرى.{% include 'navbar.html' %}
{% if %}condition لعرض HTML معين.{% if user.is_authenticated %}
{% for %}loop على list أو QuerySet.{% for student in students %}
{% empty %}ينفذ لو loop list فاضية.{% empty %}
{% load static %}تحميل static template library.{% load static %}
{% url %}يبني URL من route name.{% url 'home' %}
{% csrf_token %}حماية POST forms.{% csrf_token %}
{# comment #}تعليق لا يظهر في الـ rendered output.{# hidden note #}
11

Mini Project: Student List Page

تطبيق عملي يجمع render + context + loop + inheritance

Goal

هنفترض إن عندنا صفحة تعرض list of student dictionaries. لاحقا في محاضرات الـ Models، نفس الفكرة هتيجي من Database بدل hard-coded list.

1
Create base.html
فيه layout العام وblocks.
2
Create students/list.html
يعمل extends من base ويعرض list.
3
Write the View
يبني students list ويبعته كـ context.
4
Connect URL
route باسم student_list.
Mini Project View
views.py
from django.shortcuts import render

def student_list(request):
    students = [
        {'name': 'Ali', 'level': 2},
        {'name': 'Mona', 'level': 2},
        {'name': 'Omar', 'level': 3},
    ]
    return render(request, 'students/list.html', {'students': students})
Mini Project Template
students/list.html
{% extends 'students/base.html' %}

{% block title %}Students{% endblock %}

{% block content %}
  <h2>Students List</h2>
  <ul>
    {% for student in students %}
      <li>{{ student.name }} - Level {{ student.level }}</li>
    {% empty %}
      <li>No students found.</li>
    {% endfor %}
  </ul>
{% endblock %}
Simple CSS Reminder

الـ CSS بيحسن شكل العرض، لكنه مش بيخلي الصفحة Dynamic لوحده. الديناميكية جاية من Django rendering والـ context.

style.css
body{
  font-family: Arial, sans-serif;
}

li{
  margin-bottom: 8px;
  padding: 6px;
  background-color: #f4f7fb;
}
12

Common Errors, Debugging, and Best Practices

أغلب مشاكل الـ Templates صغيرة لكن بتوقف الصفحة

Common Template Errors
Errorالسبب المعتادراجع إيه؟
TemplateDoesNotExistpath غلط أو الملف في folder غلط.templates/app_name/file.html وTEMPLATES settings.
Empty outputvariable مش موجود في context.أسماء keys في context dictionary.
TemplateSyntaxErrorناقص %} أو }} أو closing tag.{% endfor %}, {% endif %}, {% endblock %}.
Static file not loadingنسيان {% load static %} أو path غلط.static folder structure وtemplate tag.
NoReverseMatch{% url %} باسم route غلط أو parameters ناقصة.urls.py route name والـ arguments المطلوبة.
Broken Template Activity

المثال ده فيه missing brace وunclosed tag. دي أخطاء واقعية جدا في اللاب.

broken template
<ul>
  {% for student in students %}
    <li>{{ student.name } - Level {{ student.level }}</li>
  {% endfor %
</ul>
fixed template
<ul>
  {% for student in students %}
    <li>{{ student.name }} - Level {{ student.level }}</li>
  {% endfor %}
</ul>
Debugging Checklist
  • ابدأ بالـ template path في render().
  • راجع folder structure: app/templates/app/file.html.
  • اطبع أو راجع context keys في الـ View.
  • اقرأ traceback؛ غالبا هيقولك اسم الملف والسطر.
  • اختبر بنسخة أبسط من الـ Template لو المشكلة مش واضحة.
Best Practices
  • استخدم variable names واضحة: student_name, course_list, total_marks.
  • استخدم inheritance بدل copy-paste للـ layout.
  • استخدم include للقطع الصغيرة المتكررة.
  • خلي الـ Template بسيط، والـ View يجهز البيانات.
  • شغل python manage.py runserver وجرب صفحة واحدة في كل مرة.
Q

Lecture 07 — Exam Questions

أسئلة من امتحانات 2021 و2024 و2025، مرتبة حسب ترتيب الشرح.

Q1 Final 2024 — Q1 + Final 2021 — Q30
Django is based on which framework?
A
MVC
B
MVVM
C
MVT
D
None of the previous
الإجابة: C — MVT
Django بيستخدم Model View Template. وده مهم جدا في المحاضرة دي لأن الـ Template هو جزء العرض اللي بيستقبل data من الـ View.
Q2 Final 2025 — T/F Q5
Django views represents the presentation layer of Django. True or False?
A
True
B
False
الإجابة: B — False
في Django MVT، الـ Template هو الأقرب للـ presentation layer. الـ View بيستقبل request ويجهز context ويختار template.
Q3 Final 2021 — Q33
What does the architecture of Django consist of?
A
Views
B
Models
C
Templates
D
All of the Above
الإجابة: D — All of the Above
architecture بتاعة Django بتجمع Models وViews وTemplates. المحاضرة دي مركزة على الـ Templates ودورها في عرض البيانات.
Q4 Final 2025 — T/F Q29
When you create a Django project on your computer, you will get a folder for your project with a specific content including templates file. True or False?
A
True
B
False
الإجابة: B — False
django-admin startproject بيعمل ملفات المشروع الأساسية زي settings.py وurls.py، لكن مش بيعمل template file تلقائيا. أنت بتنظم templates folder بنفسك.
Q5 Final 2021 — Q31
What does {{ name }} mean in Django Templates?
A
{{ name }} will be the output.
B
It will be displayed as name in HTML.
C
The name will be replaced with values of Python variable.
D
None of the above.
الإجابة: C
{{ name }} معناها إن Django هيستبدل placeholder بقيمة name القادمة من الـ context. المتصفح يستلم القيمة النهائية، مش الـ Django syntax.
Q6 Final 2024 — Q4
To perform programming logic in Django templates, you can use 'template tags', what is a correct syntax to start a 'for' loop?
A
(for x in y)
B
<% for x in y %>
C
{% for x in y %}
D
None of the previous
الإجابة: C — {% for x in y %}
الـ for في Django Template Tag بيتكتب بين {% و%}، ولازم يتقفل بـ {% endfor %}.
Q7 Final 2021 — Q32
Which of the following is a valid forloop attribute of Django Template System?
A
forloop.reverse
B
forloop.lastitem
C
forloop.counter
D
forloop.index()
الإجابة: C — forloop.counter
داخل Django loop تقدر تستخدم {{ forloop.counter }} عشان تعرض رقم iteration يبدأ من 1. مفيش parentheses في template variable؛ يعني نكتب forloop.counter مش forloop.counter().