Model–View–Template (MVT) Yapısında Template Katmanı
Django’nun Template (Şablon) sistemi, backend tarafındaki veriyi (Python nesneleri) kullanıcıya gösterilecek olan HTML dosyalarıyla harmanlayan güçlü bir yapıdır. Django, "DRY" (Don't Repeat Yourself) prensibini HTML dosyalarınızda da uygulamanıza olanak tanır.
1. Django Template Sistemi Nedir?
Django, mantık (Logic) ile sunumu (Presentation) birbirinden ayırmak için MTV (Model-Template-View) mimarisini kullanır. View fonksiyonu veriyi hazırlar ve bu veriyi bir "Context" (sözlük yapısı) içinde Template'e gönderir.
2. Kurulum ve Ayarlar
Bir projede template kullanmak için önce settings.py dosyasındaki TEMPLATES ayarını kontrol etmelisiniz. Genellikle uygulama dizinindeki templates klasörünü otomatik görmesi için APP_DIRS: True ayarı kullanılır.
# settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'], # Proje genelindeki klasör
'APP_DIRS': True, # Uygulama içindeki 'templates' klasörlerini tara
...
},
]
3. Temel Sözdizimi (Syntax)
Django template dilinde (DTL) üç temel yapı vardır:
A. Değişkenler {{ variable }}
View'dan gönderilen veriyi ekrana basmak için kullanılır. Nokta (.) operatörü ile sözlük anahtarlarına veya nesne özelliklerine erişebilirsiniz.
Örnek:
Merhaba {{ user.first_name }}
B. Etiketler (Tags) {% tag %}
Döngüler, mantıksal sorgular veya dış dosya yüklemeleri gibi "mantık" işlemlerini yapar.
if/else: Şartlı durumlar.
for: Liste içinde dönmek.
C. Filtreler {{ value|filter }}
Veriyi ekrana basmadan önce modifiye etmek için kullanılır.
{{ name|lower }}-> İsmi küçük harfe çevirir.{{ date|date:"D d M Y" }}-> Tarihi formatlar.
4. Template Miras Alma (Inheritance)
Bu, Django'nun en güçlü özelliğidir. Her sayfada tekrar eden header, footer gibi alanları tek bir ana dosyada tutup diğer sayfalarda "miras" alabilirsiniz.
ana_taslak.html (Base Template)
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}Sitem{% endblock %}</title>
</head>
<body>
<nav>Menü Burada</nav>
<main>
{% block content %}
{% endblock %}
</main>
<footer>Alt Bilgi</footer>
</body>
</html>
index.html (Child Template)
{% extends "ana_taslak.html" %}
{% block title %}Ana Sayfa{% endblock %}
{% block content %}
<h1>Hoş Geldiniz!</h1>
<p>Bu içerik ana taslağın içine yerleşir.</p>
{% endblock %}
5. View İçinde Kullanım
Bir View fonksiyonundan template'e nasıl veri gönderilir?
from django.shortcuts import render
def urun_listesi(request):
urunler = ["Laptop", "Mouse", "Klavye"]
context = {
'kategori': 'Teknoloji',
'urunler': urunler,
}
return render(request, 'urunler.html', context)
6. Önemli Template Etiketleri ve İpuçları
| Etiket | Açıklama |
{% url 'view_name' %} | Statik link vermek yerine Django'nun URL sistemini kullanmanızı sağlar. |
{% static 'path' %} | CSS, JS veya resim dosyalarını çağırmak için kullanılır. |
{% csrf_token %} | Formlarda güvenlik (Cross-Site Request Forgery) için zorunludur. |
{% include "parca.html" %} | Küçük bir HTML parçasını (örn: sidebar) başka bir yere dahil eder. |
7. Statik Dosyalarla Çalışmak
Resim veya CSS dosyalarınızı kullanmak için template'in en üstüne {% load static %} eklemelisiniz.
{% load static %}
<link rel="stylesheet" href="{% static 'css/style.css' %}">
<img src="{% static 'images/logo.png' %}" alt="Logo">
Özetle;
Django Template sistemi, kod tekrarını önleyerek dinamik web sayfaları oluşturmanızı sağlar. Karmaşık mantık işlemlerini View içinde halledip, Template içinde sadece veriyi nasıl göstereceğinize odaklanmanız en iyi yaklaşımdır.
1️⃣ Django Template Nedir?
Django Template,
Django
framework’ünde HTML ile Python kodunu birbirinden ayırmak için kullanılan özel bir şablon (template) sistemidir.
Amaç:
Arka plan (backend) mantığı → views.py
Ön yüz (frontend) görünümü → template (.html)
Bu ayrım sayesinde:
Kod okunabilirliği artar
Tasarımcı–geliştirici ayrımı mümkün olur
Proje bakımı kolaylaşır
2️⃣ Template Dosyalarının Konumu
📁 Önerilen Klasör Yapısı
project/
│
├── app/
│ ├── views.py
│ └── templates/
│ └── app/
│ ├── base.html
│ └── index.html
🔑 Önemli:
Template klasörünüapp/templates/app/şeklinde oluşturmak çakışmaları önler.
3️⃣ İlk Template Örneği
🔹 views.py
from django.shortcuts import render
def index(request):
return render(request, "app/index.html")
🔹 index.html
<!DOCTYPE html>
<html>
<head>
<title>Django Template</title>
</head>
<body>
<h1>Merhaba Django!</h1>
</body>
</html>
4️⃣ Template Değişkenleri (Variables)
🔹 views.py
def index(request):
context = {
"isim": "Nuri",
"yas": 14
}
return render(request, "app/index.html", context)
🔹 index.html
<h1>Merhaba {{ isim }}</h1>
<p>Yaş: {{ yas }}</p>
📌 {{ }} → değişken yazdırma
5️⃣ Template Etiketleri (Tags)
🔁 if – koşul yapısı
{% if yas >= 18 %}
<p>Reşitsiniz</p>
{% else %}
<p>Reşit değilsiniz</p>
{% endif %}
🔁 for – döngü
<ul>
{% for ders in dersler %}
<li>{{ ders }}</li>
{% endfor %}
</ul>
context = {
"dersler": ["Matematik", "Fen", "Bilişim"]
}
6️⃣ Template Filtreleri (Filters)
{{ isim|upper }}
{{ metin|lower }}
{{ yazi|length }}
{{ aciklama|truncatewords:5 }}
📌 Filtreler | (pipe) işareti ile kullanılır.
7️⃣ Template Kalıtımı (Template Inheritance)
🔹 base.html
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}Site{% endblock %}</title>
</head>
<body>
<header>
<h1>Site Başlığı</h1>
</header>
{% block content %}
{% endblock %}
<footer>
<p>Tüm Hakları Saklıdır</p>
</footer>
</body>
</html>
🔹 index.html
{% extends "app/base.html" %}
{% block title %}Ana Sayfa{% endblock %}
{% block content %}
<p>Burası ana sayfa</p>
{% endblock %}
📌 Bu yapı gerçek projelerde olmazsa olmazdır.
8️⃣ static Dosyalar (CSS – JS – Görsel)
📁 Yapı
static/
└── app/
├── style.css
└── logo.png
🔹 base.html
{% load static %}
<link rel="stylesheet" href="{% static 'app/style.css' %}">
<img src="{% static 'app/logo.png' %}">
9️⃣ URL Kullanımı (url Tag)
<a href="{% url 'anasayfa' %}">Ana Sayfa</a>
path("", views.index, name="anasayfa")
📌 Hard-coded URL yazmaktan kurtarır.
🔟 Güvenlik: Otomatik Escape
{{ kullanici_girdisi }}
Django otomatik olarak HTML escape yapar
XSS saldırılarına karşı koruma sağlar
{{ veri|safe }}
⚠️ Dikkatli kullan!
1️⃣1️⃣ Sık Yapılan Hatalar
❌ {{ if ... }} kullanmak
✔️ {% if ... %}
❌ Template içinde Python kodu yazmak
✔️ Mantık → views.py
❌ Tüm HTML’i tek dosyada toplamak
✔️ base.html + extends
1️⃣2️⃣ Eğitim ve Sınıf İçin Önerilen Mini Projeler
📌 Öğrenci Not Görüntüleme Sayfası
📌 Günün Ayeti / Hadisi Template’i
📌 Login – Register arayüzü
📌 Blog Listeleme Sayfası
🎯 Özet
| Özellik | Açıklama |
|---|---|
{{ }} | Değişken |
{% %} | Etiket |
extends | Kalıtım |
block | Alan tanımı |
static | CSS / JS |
url | Dinamik link |
Bir Blog Listeleme Sayfası hazırlayalım. Bu örnekte hem veritabanından gelen verileri döngüye sokacağız hem de "eğer yazı yoksa" gibi mantıksal kontrolleri kullanacağız.
Senaryomuzda bir Post modelimiz olduğunu ve View katmanından tüm yazıları gönderdiğimizi varsayıyoruz.
1. Adım: View (Görünüm) Hazırlığı
Önce Python tarafında veriyi paketleyip gönderelim.
# views.py
from django.shortcuts import render
def blog_listesi(request):
yazilar = [
{
'baslik': 'Django ile Web Geliştirme',
'icerik': 'Django, Python tabanlı bir frameworktür...',
'yazar': 'Ahmet',
'tarih': '2024-05-10',
'okunma_sayisi': 150
},
{
'baslik': 'Template Miras Alma',
'icerik': 'DRY prensibi ile kodunuzu temiz tutun.',
'yazar': 'Ayşe',
'tarih': '2024-05-12',
'okunma_sayisi': 85
}
]
return render(request, 'blog/liste.html', {'postlar': yazilar})
2. Adım: Template Tasarımı (liste.html)
Şimdi bu veriyi kullanıcıya şık bir şekilde sunalım.
{% extends "base.html" %}
{% block title %} Blog Yazıları {% endblock %}
{% block content %}
<h1 class="mb-4">Son Paylaşılan Yazılar</h1>
<div class="blog-container">
{% for post in postlar %}
<article class="post-card" style="border: 1px solid #ddd; padding: 15px; margin-bottom: 10px;">
<h2>{{ post.baslik|upper }}</h2> <p>
<small>Yazar: <strong>{{ post.yazar }}</strong> | Tarih: {{ post.tarih }}</small>
</p>
<p>{{ post.icerik|truncatewords:10 }}</p> {% if post.okunma_sayisi > 100 %}
<span style="color: red;">🔥 Popüler Yazı!</span>
{% endif %}
<br>
<a href="#">Devamını Oku...</a>
</article>
{% empty %}
<p>Henüz hiç yazı paylaşılmamış. Lütfen daha sonra tekrar geliniz.</p>
{% endfor %}
</div>
{% endblock %}
Bu Örnekte Neler Öğrendik?
{% for ... in ... %}: Veritabanından gelen listeyi tek tek dönmeyi.{{ post.baslik|upper }}: Filtre kullanarak veriyi anlık manipüle etmeyi (Büyük harfe çevirme).{% if ... %}: Belirli şartlara göre (örn: okunma sayısı) HTML içinde farklı alanlar göstermeyi.{% empty %}: Liste boş olduğunda kullanıcıya "boş sayfa" yerine anlamlı bir mesaj vermeyi.|truncatewords:10: Uzun metinleri özet haline getirmeyi.
Küçük Bir İpucu: safe Filtresi
Eğer veritabanındaki içerik HTML etiketleri içeriyorsa (örneğin bir zengin metin editöründen geliyorsa), Django güvenlik gereği bunları düz metin olarak basar. HTML olarak yorumlanması için şunu kullanmalısınız:
{{ post.icerik|safe }}
Harika! O zaman bu blog sayfasını hem görsel olarak güzelleştirelim (Statik Dosyalar) hem de kullanıcıların yazı aramasına olanak tanıyan bir Arama Formu ekleyelim.
1. Statik Dosyaları (CSS/JS/Resim) Bağlama
Django'da CSS, JavaScript ve resimler "Static Files" olarak adlandırılır. Bunları template içinde kullanmak için belirli bir düzen takip edilir.
Klasör Yapısı
Projenizde şu yapıyı oluşturun:
uygulama_adi/static/css/style.css
Template İçinde Kullanım
base.html dosyanızın en üstüne {% load static %} eklemelisiniz.
{% load static %}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>
<body>
<img src="{% static 'images/logo.png' %}" alt="Site Logosu">
{% block content %}{% endblock %}
</body>
</html>
2. Arama Formu (Search Form) Entegrasyonu
Bir blog sitesinde en çok ihtiyaç duyulan özelliklerden biri aramadır. Bunu yapmak için HTML <form> yapısını Django'nun GET metoduyla birleştireceğiz.
A. Template Tarafı (Form Tasarımı)
Bu formu genellikle base.html veya nav.html içine koyarız ki her sayfada görünsün.
<form action="{% url 'blog_listesi' %}" method="get">
<input type="text" name="q" placeholder="Yazılarda ara..." value="{{ request.GET.q }}">
<button type="submit">Ara</button>
</form>
B. View Tarafı (Arama Mantığı)
View fonksiyonumuzu, gelen arama sorgusunu (q) yakalayacak ve veritabanını filtreleyecek şekilde güncelliyoruz.
from django.shortcuts import render
# Modelinizin olduğunu varsayıyoruz: from .models import Post
def blog_listesi(request):
sorgu = request.GET.get('q') # Formdaki 'name="q"' kısmını yakalar
if sorgu:
# Başlıkta sorgu kelimesi geçenleri filtrele (icontains = büyük/küçük harf duyarsız)
yazilar = Post.objects.filter(baslik__icontains=sorgu)
else:
# Sorgu yoksa tüm yazıları getir
yazilar = Post.objects.all()
return render(request, 'blog/liste.html', {'postlar': yazilar})
3. Formlarda Güvenlik: CSRF Token
Eğer arama formu gibi sadece veri okuyan (GET) değil de, veri gönderen (POST - örneğin yorum yapma veya giriş yapma) bir form oluşturuyorsanız, Django güvenliği sağlamak için bir token (jeton) zorunlu tutar.
Not: Eğer
{% csrf_token %}eklemezseniz, Django "403 Forbidden" hatası verir.
<form method="post" action="/yorum-yap/">
{% csrf_token %} <textarea name="yorum"></textarea>
<button type="submit">Gönder</button>
</form>
Özet İpuçları 💡
{% load static %}: Statik dosyaları kullanabilmek için her sayfanın en başında olmalıdır.request.GET.q: Template içinde kullanıcının ne arattığını ekranda tekrar göstermek için (örn: "Sonuçlar: 'Django' için bulundu") çok kullanışlıdır.Dinamik URL: Formun
actionkısmına/blog/yazmak yerine{% url 'view_adı' %}yazmak, yarın bir gün URL yapısını değiştirirseniz sizi tek tek dosya gezmekten kurtarır.
🧩 Infografik / Diyagram
🔷 1. Genel Akış Diyagramı
KULLANICI (Tarayıcı)
│
▼
URLS.PY
│
▼
VIEWS.PY
(Veri & Mantık)
│
▼
CONTEXT (dict)
│
▼
TEMPLATE (.html)
({{ }} / {% %})
│
▼
HTML ÇIKTI
│
▼
KULLANICIYA GÖSTERİLİR
📌 Bu yapı Django’nun temel çalışma mantığını özetler.
🔷 2. Template Dosya Yapısı Diyagramı
project/
│
├── app/
│ ├── views.py
│ ├── urls.py
│ │
│ ├── templates/
│ │ └── app/
│ │ ├── base.html
│ │ ├── index.html
│ │ └── detail.html
│ │
│ └── static/
│ └── app/
│ ├── style.css
│ ├── script.js
│ └── images/
🟢 Yeşil alan: Görünüm (HTML)
🔵 Mavi alan: Mantık (Python)
🟡 Sarı alan: Statik dosyalar
🔷 3. Template Kalıtımı (Inheritance) Diyagramı
base.html
┌────────────────────────┐
│ <head> │
│ {% block title %} │
│ {% endblock %} │
│ │
│ {% block content %} │
│ {% endblock %} │
│ │
│ footer │
└───────────┬────────────┘
│
┌───────┴────────┐
│ index.html │
│ {% extends %} │
│ block content │
└────────────────┘
📌 Gerçek projelerde %90 bu yapı kullanılır.
🔷 4. Template Sözdizimi (Syntax) Haritası
{{ değişken }}
│
├── Filtreler
│ ├── |upper
│ ├── |lower
│ ├── |length
│ └── |truncatewords
│
{% etiket %}
│
├── if / elif / else
├── for
├── block
├── extends
├── load static
└── url
🔷 5. View → Template Veri Aktarımı
views.py
────────
context = {
"isim": "Ali",
"dersler": [...]
}
│
▼
index.html
──────────
{{ isim }}
{% for ders in dersler %}
🧠 Kural:
Template hesap yapmaz, sadece gösterir
🔷 6. Static Dosya Kullanımı Diyagramı
STATIC DOSYALAR
│
├── CSS → Tasarım
├── JS → Etkileşim
└── IMG → Görseller
base.html
─────────
{% load static %}
<link href="{% static 'app/style.css' %}">
🔷 7. Sık Hatalar – Doğru Kullanım Karşılaştırması
| ❌ Yanlış | ✅ Doğru |
|---|---|
{{ if }} | {% if %} |
| Template içinde Python | Mantık → views.py |
| Tek HTML dosyası | base + extends |
| Hard-coded URL | {% url %} |
🎯 Tek Sayfalık Poster Özeti (ETAP / Sınıf İçin)
Django Template =
HTML + {{ Değişken }} + {% Etiket %}
✔ Temiz Kod
✔ Güvenli
✔ Modüler
✔ Profesyonel
Aşağıda baştan sona, template ağırlıklı, ders + mini proje formatında hazırlanmış
🎯 tam bir Django Mini Proje bulacaksın.
(Bu içerik sınıfta anlatılabilir, ETAP 23’te uygulanabilir ve öğrenci seviyesine uygundur.)
🧩 Django Mini Proje
📚 “Duyuru & Bilgi Paylaşım Sitesi”
(Template Ağırlıklı)
📌 Amaç:
Django Template sistemini
extendsblockfor / ifstaticurl
odaklı gerçek bir proje içinde öğretmek
1️⃣ Proje Özeti
| Özellik | Var mı |
|---|---|
| base.html | ✅ |
| Template inheritance | ✅ |
| Dinamik veri | ✅ |
| Static CSS | ✅ |
| URL tag | ✅ |
| for / if | ✅ |
| Öğrenci dostu | ✅ |
2️⃣ Proje Yapısı
duyuru_site/
│
├── manage.py
├── duyuru_site/
│ ├── settings.py
│ ├── urls.py
│
├── duyuru/
│ ├── views.py
│ ├── urls.py
│ ├── templates/
│ │ └── duyuru/
│ │ ├── base.html
│ │ ├── home.html
│ │ └── detail.html
│ │
│ └── static/
│ └── duyuru/
│ └── style.css
duyuru_site/
│
├── manage.py
├── duyuru_site/
│ ├── settings.py
│ ├── urls.py
│
├── duyuru/
│ ├── views.py
│ ├── urls.py
│ ├── templates/
│ │ └── duyuru/
│ │ ├── base.html
│ │ ├── home.html
│ │ └── detail.html
│ │
│ └── static/
│ └── duyuru/
│ └── style.css
3️⃣ Uygulama Oluşturma
django-admin startproject duyuru_site
cd duyuru_site
python manage.py startapp duyuru
django-admin startproject duyuru_site
cd duyuru_site
python manage.py startapp duyuru
settings.py
INSTALLED_APPS = [
...
'duyuru',
]
INSTALLED_APPS = [
...
'duyuru',
]
4️⃣ URL Yapısı
duyuru_site/urls.py
from django.urls import path, include
urlpatterns = [
path("", include("duyuru.urls")),
]
from django.urls import path, include
urlpatterns = [
path("", include("duyuru.urls")),
]
duyuru/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.home, name="home"),
path("duyuru/<int:id>/", views.detail, name="detail"),
]
from django.urls import path
from . import views
urlpatterns = [
path("", views.home, name="home"),
path("duyuru/<int:id>/", views.detail, name="detail"),
]
5️⃣ views.py (Veri Mantığı)
from django.shortcuts import render
DUYURULAR = [
{"id": 1, "baslik": "Python Kursu", "icerik": "Python dersi başlıyor"},
{"id": 2, "baslik": "Django Eğitimi", "icerik": "Template sistemi anlatılacak"},
{"id": 3, "baslik": "ETAP 23", "icerik": "Uygulamalı ders yapılacak"},
]
def home(request):
return render(request, "duyuru/home.html", {
"duyurular": DUYURULAR
})
def detail(request, id):
secilen = None
for d in DUYURULAR:
if d["id"] == id:
secilen = d
return render(request, "duyuru/detail.html", {
"duyuru": secilen
})
from django.shortcuts import render
DUYURULAR = [
{"id": 1, "baslik": "Python Kursu", "icerik": "Python dersi başlıyor"},
{"id": 2, "baslik": "Django Eğitimi", "icerik": "Template sistemi anlatılacak"},
{"id": 3, "baslik": "ETAP 23", "icerik": "Uygulamalı ders yapılacak"},
]
def home(request):
return render(request, "duyuru/home.html", {
"duyurular": DUYURULAR
})
def detail(request, id):
secilen = None
for d in DUYURULAR:
if d["id"] == id:
secilen = d
return render(request, "duyuru/detail.html", {
"duyuru": secilen
})
📌 Bilerek veriler listeden verildi → Template odaklı öğretim için.
6️⃣ base.html (Template Kalbi)
{% load static %}
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}Duyuru Sitesi{% endblock %}</title>
<link rel="stylesheet" href="{% static 'duyuru/style.css' %}">
</head>
<body>
<header>
<h1>Django Duyuru Sistemi</h1>
<nav>
<a href="{% url 'home' %}">Ana Sayfa</a>
</nav>
</header>
<main>
{% block content %}
{% endblock %}
</main>
<footer>
<p>© 2026 Django Mini Proje</p>
</footer>
</body>
</html>
{% load static %}
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}Duyuru Sitesi{% endblock %}</title>
<link rel="stylesheet" href="{% static 'duyuru/style.css' %}">
</head>
<body>
<header>
<h1>Django Duyuru Sistemi</h1>
<nav>
<a href="{% url 'home' %}">Ana Sayfa</a>
</nav>
</header>
<main>
{% block content %}
{% endblock %}
</main>
<footer>
<p>© 2026 Django Mini Proje</p>
</footer>
</body>
</html>
7️⃣ home.html (for + url)
{% extends "duyuru/base.html" %}
{% block title %}Ana Sayfa{% endblock %}
{% block content %}
<h2>Duyurular</h2>
<ul>
{% for d in duyurular %}
<li>
<a href="{% url 'detail' d.id %}">
{{ d.baslik }}
</a>
</li>
{% endfor %}
</ul>
{% endblock %}
{% extends "duyuru/base.html" %}
{% block title %}Ana Sayfa{% endblock %}
{% block content %}
<h2>Duyurular</h2>
<ul>
{% for d in duyurular %}
<li>
<a href="{% url 'detail' d.id %}">
{{ d.baslik }}
</a>
</li>
{% endfor %}
</ul>
{% endblock %}
8️⃣ detail.html (if kontrolü)
{% extends "duyuru/base.html" %}
{% block title %}Duyuru Detayı{% endblock %}
{% block content %}
{% if duyuru %}
<h2>{{ duyuru.baslik }}</h2>
<p>{{ duyuru.icerik }}</p>
{% else %}
<p>Duyuru bulunamadı</p>
{% endif %}
{% endblock %}
{% extends "duyuru/base.html" %}
{% block title %}Duyuru Detayı{% endblock %}
{% block content %}
{% if duyuru %}
<h2>{{ duyuru.baslik }}</h2>
<p>{{ duyuru.icerik }}</p>
{% else %}
<p>Duyuru bulunamadı</p>
{% endif %}
{% endblock %}
9️⃣ static/style.css
body {
font-family: Arial;
background: #f5f5f5;
}
header {
background: #2c3e50;
color: white;
padding: 10px;
}
a {
text-decoration: none;
color: #2980b9;
}
body {
font-family: Arial;
background: #f5f5f5;
}
header {
background: #2c3e50;
color: white;
padding: 10px;
}
a {
text-decoration: none;
color: #2980b9;
}
🔟 Öğrenilen Template Konuları (Özet)
| Konu | Nerede |
|---|---|
| extends | home / detail |
| block | base.html |
| for | home.html |
| if | detail.html |
| static | base.html |
| url | Menü & liste |
🎯 Sınıf / ETAP 23 İçin Etkinlik Önerileri
🧪 Etkinlik 1
Öğrenci base.htmle yan menü eklesin
Öğrenci base.htmle yan menü eklesin
🧪 Etkinlik 2
for döngüsüne numaralandırma eklesin
for döngüsüne numaralandırma eklesin
🧪 Etkinlik 3
CSS ile kart tasarımı yaptırsın
CSS ile kart tasarımı yaptırsın
🚀 Geliştirme Ödevleri
🔹 Duyuru tarihi ekle
🔹 Önemli duyuruları renklendir (if)
🔹 “Hakkımızda” template’i ekle
🔹 Dark / Light tema
🔹 Duyuru tarihi ekle
🔹 Önemli duyuruları renklendir (if)
🔹 “Hakkımızda” template’i ekle
🔹 Dark / Light tema
🧠 Bu Proje Neden İdeal?
✔ Template odaklı → hedefe uygun
✔ Gerçek site hissi
✔ Kademeli geliştirilebilir
🧪 Django LAB Etkinliği
🎯 Konu: Template Akışı & Kalıtımı
(Template Infografiği Uyumlu)
📌 Framework: Django
📌 Seviye: Başlangıç → Orta
📌 Süre: 40–45 dk
📌 Ortam: Bilgisayar LAB / ETAP 23
1️⃣ LAB Kazanımları
Öğrenci bu LAB sonunda:
✅ Template–View–URL akışını kavrar
✅ base.html → extends mantığını uygular
✅ {{ }} ve {% %} farkını öğrenir
✅ for / if / url / static etiketlerini kullanır
✅ Infografikteki diyagramı koda dönüştürür
2️⃣ LAB Ön Hazırlık (Öğretmen – 5 dk)
Öğretmen sınıfa şu diyagramı gösterir:
KULLANICI → URL → VIEW → CONTEXT → TEMPLATE → HTML
🔹 “Bugün bu okları tek tek kodlayacağız” açıklaması yapılır.
3️⃣ LAB Görevi (Ana Senaryo)
🎯 Senaryo:
“Okul duyurularını gösteren basit bir web sayfası oluştur.”
📌 Kurallar:
Veritabanı kullanılmayacak
Template yapısı zorunlu
CSS static’ten gelecek
4️⃣ Adım 1 – Template Klasörü (5 dk)
📁 Öğrenci oluşturur:
duyuru/templates/duyuru/
├── base.html
├── home.html
└── detail.html
🧠 Infografik eşleşmesi:
Template Dosya Yapısı Diyagramı
5️⃣ Adım 2 – base.html (Kalıtım Merkezi) (7 dk)
🔧 Görev:
Sayfa iskeletini oluştur
block titleveblock contentekleMenüye “Ana Sayfa” linki koy
🎯 Beklenen Kod Parçaları:
{% block title %}{% endblock %}
{% block content %}{% endblock %}
🧠 Infografik eşleşmesi:
Template Inheritance Diyagramı
6️⃣ Adım 3 – home.html (for + url) (8 dk)
🔧 Görev:
extendskullanDuyuruları listele
Her duyuruya tıklanabilir link ver
🎯 Beklenen Yapılar:
{% extends %}
{% for %}
{% url %}
🧠 Infografik eşleşmesi:
Template Sözdizimi Haritası
7️⃣ Adım 4 – detail.html (if kontrolü) (5 dk)
🔧 Görev:
Seçilen duyuru varsa göster
Yoksa “Bulunamadı” mesajı yaz
🎯 Beklenen:
{% if duyuru %}
{% else %}
{% endif %}
🧠 Infografik eşleşmesi:
View → Template Veri Aktarımı
8️⃣ Adım 5 – views.py (Veri Akışı) (7 dk)
🔧 Öğrenciye Verilen Veri:
DUYURULAR = [
{"id": 1, "baslik": "Python Kursu"},
{"id": 2, "baslik": "Django Template"},
]
🔧 Görev:
home→ tüm duyurulardetail→ id’ye göre tek duyuru
🧠 Infografik eşleşmesi:
Context → Template Okları
9️⃣ Adım 6 – static CSS (5 dk)
🔧 Görev:
static/duyuru/style.cssoluşturHeader’a renk ver
Linkleri stillendir
🎯 Beklenen:
{% load static %}
<link rel="stylesheet" href="{% static %}">
🧠 Infografik eşleşmesi:
Static Dosya Diyagramı
🔟 LAB Kontrol Listesi (Değerlendirme)
| Kriter | Puan |
|---|---|
| base.html kullanımı | 20 |
| extends / block | 20 |
| for / if | 20 |
| url tag | 20 |
| static CSS | 20 |
| Toplam | 100 |
🧪 Ek Görevler (Hızlı Bitirenler İçin)
⭐ Duyuruya önem durumu ekle
⭐ if ile önemli duyuruları renklendir
⭐ Footer’a yıl ekle
⭐ “Hakkımızda” template’i oluştur
🎯 LAB Çıkış Sorusu (Kapanış)
🧠 Soru:
“Template içinde Python yazmak neden önerilmez?”
📌 Beklenen Cevap:
Template sadece gösterim, mantık views.py’de olmalıdır.
🧩 Öğretmen Notu
Bu LAB:
✔ Diyagram → Kod dönüşümü sağlar
✔ Django Template mantığını kalıcı öğretir
✔ Veritabanı karmaşası olmadan öğrenme sunar
✔ ETAP 23 ve 11. sınıf düzeyine uygundur
Aşağıda Django Template–View veri akışını 🎯 tek bakışta anlaşılır, sınıfta anlatıma uygun, infografik / diyagram formatı
Template – View Veri Akış Diyagramı
📌 Framework: Django
1️⃣ Büyük Resim: Uçtan Uca Akış
👤 KULLANICI (Tarayıcı)
│ HTTP GET
▼
🌐 URLS.PY
(path eşleşmesi)
│
▼
🧠 VIEWS.PY
(Veri + Mantık)
│
│ context = { ... }
▼
🧩 TEMPLATE (.html)
{{ değişken }} / {% etiket %}
│
▼
📄 HTML RESPONSE
│
▼
👤 KULLANICIYA GÖSTERİLİR
👤 KULLANICI (Tarayıcı)
│ HTTP GET
▼
🌐 URLS.PY
(path eşleşmesi)
│
▼
🧠 VIEWS.PY
(Veri + Mantık)
│
│ context = { ... }
▼
🧩 TEMPLATE (.html)
{{ değişken }} / {% etiket %}
│
▼
📄 HTML RESPONSE
│
▼
👤 KULLANICIYA GÖSTERİLİR
🎯 Ana fikir:
View veriyi hazırlar, Template sadece gösterir
2️⃣ Kodla Eşleşen Akış (Adım Adım)
🔹 1. URL → View
path("", views.home, name="home")
path("", views.home, name="home")
🧠 Açıklama:
Tarayıcı isteği URL’ye gelir
Django doğru view fonksiyonunu bulur
🔹 2. View → Context
def home(request):
context = {
"duyurular": DUYURULAR
}
return render(request, "duyuru/home.html", context)
views.py
────────
DUYURULAR ──▶ context
def home(request):
context = {
"duyurular": DUYURULAR
}
return render(request, "duyuru/home.html", context)
views.py
────────
DUYURULAR ──▶ context
🧠 Açıklama:
Python verisi hazırlanır
Template’e dict olarak gönderilir
🔹 3. Context → Template
<ul>
{% for d in duyurular %}
<li>{{ d.baslik }}</li>
{% endfor %}
</ul>
context["duyurular"]
│
▼
{{ duyurular }}
<ul>
{% for d in duyurular %}
<li>{{ d.baslik }}</li>
{% endfor %}
</ul>
context["duyurular"]
│
▼
{{ duyurular }}
🧠 Açıklama:
{{ }}→ veri yazdırma{% %}→ kontrol yapıları
3️⃣ Detay Akış Diyagramı (Infografik Tipi)
request
│
▼
URL Resolver
│
▼
View Function
│
├─ Veriyi hazırla
│
├─ context = {}
│
▼
Template Engine
│
├─ {{ variable }}
├─ {% for %}
├─ {% if %}
│
▼
Rendered HTML
request
│
▼
URL Resolver
│
▼
View Function
│
├─ Veriyi hazırla
│
├─ context = {}
│
▼
Template Engine
│
├─ {{ variable }}
├─ {% for %}
├─ {% if %}
│
▼
Rendered HTML
4️⃣ Hatalı vs Doğru Veri Akışı
❌ Yanlış
{{ for d in duyurular }}
❌ Template içinde Python:
{{ duyurular.append(...) }}
✅ Doğru
{% for d in duyurular %}
{{ d.baslik }}
{% endfor %}
🧠 Kural:
Template hesap yapmaz, veri üretmez
5️⃣ Static Dosyalar Akışa Nasıl Dahil?
TEMPLATE
│
├── {% load static %}
│
└── CSS / JS / IMG
<link rel="stylesheet" href="{% static 'duyuru/style.css' %}">
TEMPLATE
│
├── {% load static %}
│
└── CSS / JS / IMG
<link rel="stylesheet" href="{% static 'duyuru/style.css' %}">
📌 Static dosyalar veri değil, görselleştirme katmanıdır
6️⃣ Template Kalıtımı Akışa Nasıl Girer?
base.html
▲
│ {% extends %}
child.html
VIEW
│
▼
child.html
│
▼
base.html
│
▼
HTML
base.html
▲
│ {% extends %}
child.html
VIEW
│
▼
child.html
│
▼
base.html
│
▼
HTML
🎯 View her zaman child template’i render eder.
7️⃣ LAB / Ders İçin Tek Cümlelik Özet
URL yönlendirir →
View veriyi hazırlar →
Template gösterir →
HTML kullanıcıya gider
URL yönlendirir →
View veriyi hazırlar →
Template gösterir →
HTML kullanıcıya gider
Öğretmen İpucu
Bu diyagramı anlatırken:
✔ Okları tek tek çiz
✔ “Burada Python var / burada yok” diye vurgula
✔ Template’in pasif olduğunu özellikle belirt
Yorumlar
Yorum Gönder