Django Formları: Veri Doğrulama, Bootstrap ve Dosya Yükleme
Web uygulamalarında kullanıcıdan veri almak, bu veriyi doğrulamak ve güvenli bir şekilde işlemek en temel ihtiyaçlardan biridir. Django'nun Form yapısı, bu süreci hem çok güvenli hem de oldukça pratik bir hale getirir.
Web geliştirme dünyasında kullanıcı etkileşiminin en temel yolu formlardır. İster bir kullanıcı kayıt sayfası, ister bir iletişim formu, isterse sisteme yeni bir veri ekleme ekranı olsun; veriyi alır, doğrular ve işleriz.
Saf HTML ile form oluşturup, arka planda (backend) bu veriyi tek tek yakalamak, doğrulamak ve hataları kullanıcıya geri döndürmek oldukça zahmetli ve güvenlik açıklarına (örneğin CSRF veya SQL Injection) davetiye çıkaran bir süreçtir. İşte tam bu noktada Django Formları devreye girer.
Django Formları Neden Bu Kadar Güçlü?
Otomatik HTML Üretimi: Python kodunuzdan otomatik olarak HTML form etiketleri (input, select, textarea vb.) üretir.
Veri Doğrulama (Validation): Kullanıcının girdiği verinin kurallara (örneğin; e-posta formatı doğru mu? Şifre çok mu kısa?) uyup uymadığını otomatik denetler.
Güvenlik: Kötü niyetli veri girişlerine karşı veriyi temizler (cleaning) ve otomatik CSRF (Cross-Site Request Forgery) koruması sağlar.
Hata Yönetimi: Hatalı giriş yapıldığında, kullanıcının girdiği verileri kaybetmeden, hataları ilgili alanların yanında göstererek formu yeniden ekrana basar.
1. Temel Django Formu Oluşturmak (forms.Form)
Django'da formlar genellikle uygulamamızın dizini içinde oluşturduğumuz forms.py dosyası içinde tanımlanır. Basit bir iletişim formu tasarlayalım.
# forms.py
from django import forms
class IletisimFormu(forms.Form):
isim = forms.CharField(max_length=100, label='Adınız ve Soyadınız')
eposta = forms.EmailField(label='E-Posta Adresiniz')
konu = forms.CharField(max_length=200, label='Konu')
mesaj = forms.CharField(widget=forms.Textarea, label='Mesajınız')
Bu Python sınıfı, Django'ya "Bana bir metin kutusu, bir e-posta kutusu ve geniş bir metin alanı (textarea) ver" diyor.
2. Formu View (Görünüm) İçinde İşlemek
Oluşturduğumuz formu kullanıcıya göstermek ve form gönderildiğinde gelen veriyi yakalamak için views.py dosyamızı düzenleriz. Burada HTTP GET (formu ilk kez görüntüleme) ve HTTP POST (formu doldurup gönderme) isteklerini ayırmamız çok önemlidir.
# views.py
from django.shortcuts import render, redirect
from .forms import IletisimFormu
def iletisim_sayfasi(request):
# Kullanıcı formu GÖNDERDİYSE (POST isteği)
if request.method == 'POST':
form = IletisimFormu(request.POST) # Formu gelen verilerle doldur (Bound Form)
# Veriler kurallara uygun mu?
if form.is_valid():
# Temizlenmiş ve doğrulanmış verilere form.cleaned_data sözlüğünden ulaşırız
isim = form.cleaned_data['isim']
eposta = form.cleaned_data['eposta']
mesaj = form.cleaned_data['mesaj']
# Burada veritabanına kaydetme veya e-posta gönderme işlemleri yapılabilir
print(f"Yeni Mesaj: {isim} - {eposta}")
# İşlem başarılıysa başka bir sayfaya yönlendir
return redirect('basarili_sayfasi')
# Kullanıcı sayfaya İLK KEZ giriyorsa (GET isteği)
else:
form = IletisimFormu() # Boş bir form oluştur (Unbound Form)
return render(request, 'iletisim.html', {'form': form})
3. Formu Template (Şablon) Üzerinde Göstermek
Şimdi bu formu kullanıcıya nasıl sunacağımıza bakalım. iletisim.html dosyamızı aşağıdaki gibi hazırlıyoruz:
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<title>İletişim</title>
</head>
<body>
<h2>Bizimle İletişime Geçin</h2>
<form method="POST">
{% csrf_token %} {{ form.as_p }} <button type="submit">Gönder</button>
</form>
</body>
</html>
{% csrf_token %}: Django'nun form güvenliği için en kritik etiketidir. Formun başka bir siteden (kötü niyetli olarak) değil, gerçekten sizin sitenizden gönderildiğini doğrular.{{ form.as_p }}: Form elemanlarını alt alta paragraflar halinde düzgünce sıralar. İsteğe bağlı olarakas_tableveyaas_ulda kullanılabilir.
4. Veritabanı ile Mükemmel Uyum: ModelForm
Django'nun en büyük güçlerinden biri, veritabanı modellerinizle formları otomatik olarak bağlayabilmesidir. Eğer formunuz doğrudan veritabanına bir kayıt ekleyecekse, forms.Form yerine forms.ModelForm kullanmak kod tekrarını (DRY prensibi) engeller.
Diyelim ki şöyle bir modelimiz var:
# models.py
from django.db import models
class Ogrenci(models.Model):
ad = models.CharField(max_length=50)
soyad = models.CharField(max_length=50)
okul_numarasi = models.IntegerField(unique=True)
Bu model için bir form yazmak ModelForm ile saniyeler sürer:
# forms.py
from django import forms
from .models import Ogrenci
class OgrenciForm(forms.ModelForm):
class Meta:
model = Ogrenci
fields = ['ad', 'soyad', 'okul_numarasi']
# veya tüm alanlar için: fields = '__all__'
ModelForm kullandığınızda, views.py içerisinde veriyi kaydetmek tek satıra düşer:
form.is_valid() bloğunun içine sadece form.save() yazmanız, verinin veritabanına eklenmesi için yeterlidir!
5. Özel Veri Doğrulama (Custom Validation)
Bazen standart kurallar yetmez. Örneğin, okul numarasının sadece belirli bir aralıkta olmasını veya öğrenci adının "X" harfi ile başlamamasını isteyebilirsiniz. Bunun için clean_<alan_adi>() metotlarını kullanırız.
class OgrenciForm(forms.ModelForm):
# ... Meta class ayarları ...
def clean_okul_numarasi(self):
numara = self.cleaned_data.get('okul_numarasi')
if numara < 100 or numara > 9999:
raise forms.ValidationError("Okul numarası 100 ile 9999 arasında olmalıdır!")
return numara
Eğer kullanıcı kurala uymazsa, sayfa yeniden yüklenir ve Django bu hata mesajını tam da okul numarası kutusunun yanında gösterir.
📌 1. Django Form Nedir?
Formlar, kullanıcıdan veri almak için kullanılır.
Örnek:
Öğrenci kayıt formu
Giriş (login) formu
İletişim formu
Not ekleme formu
Django’da form kullanmanın avantajları:
✅ Otomatik HTML üretir
✅ Doğrulama (validation) yapar
✅ Güvenlidir (CSRF koruması vardır)
✅ Temiz ve düzenli kod sağlar
📌 2. Django’da Form Türleri
Django’da 2 ana form türü vardır:
| Tür | Açıklama |
|---|---|
forms.Form | Modelden bağımsız form |
forms.ModelForm | Veritabanı modeli ile bağlı form |
🎯 3. forms.Form Kullanımı (Model Bağımsız)
🔹 Adım 1: forms.py oluştur
Uygulama klasörüne forms.py dosyası oluştur:
from django import forms
class OgrenciForm(forms.Form):
ad = forms.CharField(max_length=100, label="Ad")
soyad = forms.CharField(max_length=100, label="Soyad")
yas = forms.IntegerField(label="Yaş")
🔹 Adım 2: views.py
from django.shortcuts import render
from .forms import OgrenciForm
def ogrenci_ekle(request):
if request.method == "POST":
form = OgrenciForm(request.POST)
if form.is_valid():
print(form.cleaned_data)
else:
form = OgrenciForm()
return render(request, "ogrenci.html", {"form": form})
🔹 Adım 3: Template (ogrenci.html)
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Kaydet</button>
</form>
🔍 Form Nasıl Çalışır?
GET isteğinde boş form gösterilir
POST isteğinde veri alınır
is_valid()ile doğrulama yapılırDoğruysa
cleaned_dataile temiz veri alınır
🧠 4. Form Alan Türleri
Django’da en sık kullanılan alanlar:
forms.CharField()
forms.EmailField()
forms.IntegerField()
forms.BooleanField()
forms.DateField()
forms.FileField()
forms.ChoiceField()
Örnek:
cinsiyet = forms.ChoiceField(
choices=[("E", "Erkek"), ("K", "Kadın")]
)
🔐 5. Form Validation (Doğrulama)
🔹 Otomatik Doğrulama
yas = forms.IntegerField(min_value=0, max_value=120)
🔹 Özel Doğrulama
def clean_ad(self):
ad = self.cleaned_data.get("ad")
if len(ad) < 3:
raise forms.ValidationError("Ad en az 3 harf olmalı!")
return ad
🔹 Genel Form Doğrulama
def clean(self):
cleaned_data = super().clean()
ad = cleaned_data.get("ad")
soyad = cleaned_data.get("soyad")
if ad == soyad:
raise forms.ValidationError("Ad ve soyad aynı olamaz!")
🎨 6. Widget Özelleştirme
Widget = HTML input tipini kontrol eder.
ad = forms.CharField(
widget=forms.TextInput(attrs={
"class": "form-control",
"placeholder": "Adınızı giriniz"
})
)
📦 7. ModelForm Kullanımı (Profesyonel Yöntem)
Eğer veritabanı modeli varsa ModelForm kullanılır.
🔹 models.py
from django.db import models
class Ogrenci(models.Model):
ad = models.CharField(max_length=100)
soyad = models.CharField(max_length=100)
yas = models.IntegerField()
🔹 forms.py
from django.forms import ModelForm
from .models import Ogrenci
class OgrenciModelForm(ModelForm):
class Meta:
model = Ogrenci
fields = "__all__"
🔹 views.py
def ogrenci_ekle(request):
if request.method == "POST":
form = OgrenciModelForm(request.POST)
if form.is_valid():
form.save()
else:
form = OgrenciModelForm()
return render(request, "ogrenci.html", {"form": form})
🎯 form.save() direkt veritabanına kaydeder.
📂 8. Dosya Yükleme (File Upload)
resim = forms.ImageField()
Template:
<form method="POST" enctype="multipart/form-data">
View:
form = FormClass(request.POST, request.FILES)
🔐 9. CSRF Koruması
Template içinde mutlaka:
{% csrf_token %}
Django otomatik güvenlik sağlar.
🎯 10. Bootstrap ile Şık Form
<form method="POST">
{% csrf_token %}
<div class="mb-3">
{{ form.ad.label_tag }}
{{ form.ad }}
</div>
<button class="btn btn-primary">Kaydet</button>
</form>
🧪 11. Form Hatalarını Gösterme
{% if form.errors %}
<div class="alert alert-danger">
{{ form.errors }}
</div>
{% endif %}
🧠 12. En Profesyonel Kullanım (Class Based View)
from django.views.generic.edit import CreateView
from .models import Ogrenci
class OgrenciCreateView(CreateView):
model = Ogrenci
fields = "__all__"
template_name = "ogrenci.html"
success_url = "/"
🎓 Özet
| Konu | Öğrendin mi? |
|---|---|
| forms.Form | ✅ |
| ModelForm | ✅ |
| Validation | ✅ |
| Widget | ✅ |
| Dosya yükleme | ✅ |
| Bootstrap entegrasyonu | ✅ |
| Class Based View | ✅ |
Django Formlarını Özelleştirme: Widget'lar ve Bootstrap Entegrasyonu
Django, form alanlarını HTML etiketlerine dönüştürürken varsayılan ayarları kullanır. Bir CharField otomatik olarak basit bir <input type="text"> etiketine dönüşür. Ancak modern web tasarımında bu etiketlere CSS sınıfları (örneğin Bootstrap'in form-control sınıfı), yer tutucu metinler (placeholder) veya özel ID'ler eklememiz gerekir.
Django'da HTML çıktılarına müdahale etmenin en temel yolu Widget (Araç) kullanımıdır.
1. Widget Nedir?
Widget, Django'nun bir form alanını (field) HTML'de nasıl çizeceğini (render) belirleyen sınıftır. Verinin doğrulanması (validation) Form Alanı'nın (Field) işiyken, verinin ekranda nasıl görüneceği Widget'ın işidir.
2. ModelForm İçinde Widget Kullanımı (Önerilen Yöntem)
Diyelim ki öğrenciler için bir proje kayıt sistemi geliştiriyorsunuz. Formun etkileşimli tahtalarda (örneğin ETAP sistemlerinde) veya mobil cihazlarda düzgün görünmesi için Bootstrap sınıflarını doğrudan Python kodumuzdan ekleyebiliriz.
Bunun için ModelForm içerisindeki Meta sınıfına bir widgets sözlüğü (dictionary) tanımlarız.
# forms.py
from django import forms
from .models import ProjeKayit
class ProjeKayitFormu(forms.ModelForm):
class Meta:
model = ProjeKayit
fields = ['ogrenci_ad', 'proje_konusu', 'sinif_sube']
# HTML etiketlerine CSS sınıfı ve özellik ekleme
widgets = {
'ogrenci_ad': forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Adınız ve Soyadınız'
}),
'proje_konusu': forms.Textarea(attrs={
'class': 'form-control',
'rows': 4,
'placeholder': 'Projenizin amacını kısaca anlatın...'
}),
'sinif_sube': forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Örn: 9-a'
}),
}
Bu kod sayesinde Django HTML üretirken şu çıktıyı verir:
<input type="text" name="sinif_sube" class="form-control" placeholder="Örn: 9-a" ...>
Böylece şablon (template) tarafında ekstra bir HTML/CSS karmaşasına girmeden, doğrudan Python üzerinden tasarımı yönetmiş oluruz.
3. Standart Formlarda (forms.Form) Widget Kullanımı
Eğer bir veritabanı modeli kullanmıyorsanız ve standart bir forms.Form oluşturuyorsanız, widget'ları doğrudan alanı tanımlarken parametre olarak geçersiniz:
# forms.py
from django import forms
class ArizaBildirimFormu(forms.Form):
baslik = forms.CharField(
max_length=100,
widget=forms.TextInput(attrs={'class': 'form-control mb-3', 'placeholder': 'Sorun Nedir?'})
)
detay = forms.CharField(
widget=forms.Textarea(attrs={'class': 'form-control mb-3', 'rows': 3})
)
4. Şablon (Template) Tarafında Manuel Render İşlemi
Bazen Python tarafında widget tanımlamak yerine, formun her bir elemanını HTML (Template) dosyasında tek tek, tam kontrole sahip olarak ekrana basmak isteyebilirsiniz.
{{ form.as_p }} kullanmak yerine, form elemanları üzerinde bir döngü kurarak kendi HTML yapınızı oluşturabilirsiniz:
<form method="POST">
{% csrf_token %}
{% for field in form %}
<div class="mb-3">
<label class="form-label fw-bold">{{ field.label }}</label>
{{ field }}
{% if field.errors %}
<div class="text-danger mt-1">
{{ field.errors.0 }}
</div>
{% endif %}
</div>
{% endfor %}
<button type="submit" class="btn btn-primary w-100">Projeyi Kaydet</button>
</form>
Bu yöntem, formun iskeletini tamamen Bootstrap'in ızgara (grid) sistemine veya kendi özel CSS tasarımınıza göre şekillendirmenize olanak tanır.
5. Alternatif ve Hızlı Çözüm: django-crispy-forms
Eğer projenizde çok sayıda form varsa ve hepsine tek tek widget yazmak veya for döngüsü kurmak yorucu geliyorsa, Django dünyasında çok popüler olan django-crispy-forms paketini kullanabilirsiniz. Bu paket, arka planda tüm Bootstrap sınıflarını formunuza otomatik olarak giydirir.
(Bu paket pip install django-crispy-forms ve pip install crispy-bootstrap5 komutlarıyla kurulup ayarlara eklenir. Sadece şablonda {{ form|crispy }} yazmanız mükemmel görünümlü bir form elde etmeniz için yeterlidir.)
Bu iki bölümlük seri ile Django'da formların hem mantıksal güvenliğini hem de görsel tasarımını tam anlamıyla kavramış oluyoruz.
Öğrencilerin projelerinde sadece metin girmeleri çoğu zaman yetmez. Kendi profil fotoğraflarını yüklemek, hazırladıkları bir ödev belgesini sisteme aktarmak veya Pardus ETAP 23 üzerindeki etkileşimli uygulamalara materyal eklemek isteyebilirler.
Django'da formlar aracılığıyla dosya (File) ve resim (Image) yüklemek oldukça sistemli bir şekilde ilerler. Ancak standart metin formlarına göre dikkat edilmesi gereken birkaç hayati kural vardır.
Django Formları ile Dosya ve Resim Yükleme (File & Image Upload)
Kullanıcıların sisteme yüklediği dosyalar Django terminolojisinde "Media Files" (Medya Dosyaları) olarak adlandırılır. Bu dosyalar, yazdığınız kodlardan (statik dosyalardan) ayrı bir klasörde güvenle saklanmalıdır.
1. Hazırlık Aşaması: Ayarlar ve Kütüphaneler
Resim ve dosya yükleme işlemlerine başlamadan önce Django'ya bu dosyaları sunucuda nereye kaydedeceğini söylememiz gerekir.
settings.py Ayarları:
Projenizin settings.py dosyasının en altına şu iki satırı ekleyin:
import os # Eğer dosyanın en üstünde yoksa ekleyin
# Tarayıcıda dosyaya ulaşmak için kullanılacak URL öneki
MEDIA_URL = '/media/'
# Dosyaların sunucuda fiziksel olarak kaydedileceği klasör
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
urls.py Ayarları:
Geliştirme (development) aşamasında, yüklenen bu dosyaları tarayıcıda görüntüleyebilmek için ana urls.py dosyanıza şu eklemeyi yapmalısınız:
from django.conf import settings
from django.conf.urls.static import static
from django.urls import path
urlpatterns = [
# ... mevcut url yollarınız ...
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Pillow Kütüphanesi:
Eğer ImageField (Resim yükleme alanı) kullanacaksanız, Python'un resim işleme kütüphanesi olan Pillow'u kurmanız zorunludur. Terminalinize şu komutu yazarak kurabilirsiniz:
pip install Pillow
2. Veritabanı Modeli ve Formun Hazırlanması
Öğrencilerin hazırladıkları bir projeyi sisteme yükleyecekleri bir model tasarlayalım. Bu modelde hem bir kapak fotoğrafı (ImageField) hem de projenin detaylarını içeren bir belge (FileField) olsun.
# models.py
from django.db import models
class OgrenciProjesi(models.Model):
proje_adi = models.CharField(max_length=200, verbose_name="Proje Adı")
kapak_fotografi = models.ImageField(upload_to='proje_kapaklari/', blank=True, null=True)
proje_dosyasi = models.FileField(upload_to='proje_belgeleri/')
def __str__(self):
return self.proje_adi
upload_toParametresi: DosyanınMEDIA_ROOTklasörü içinde hangi alt klasöre kaydedileceğini belirler (Örn:media/proje_kapaklari/).
Bu modelin formunu ModelForm ile oluşturmak, önceki metin formlarıyla tamamen aynıdır:
# forms.py
from django import forms
from .models import OgrenciProjesi
class ProjeYuklemeFormu(forms.ModelForm):
class Meta:
model = OgrenciProjesi
fields = ['proje_adi', 'kapak_fotografi', 'proje_dosyasi']
3. Görünüm (View) İçerisinde Dosyayı Yakalamak
Bir formda dosya varsa, request.POST verisinin yanında request.FILES verisini de almamız gerekir. En çok yapılan hata, view tarafında request.FILES parametresini unutmaktır.
# views.py
from django.shortcuts import render, redirect
from .forms import ProjeYuklemeFormu
def proje_yukle(request):
if request.method == 'POST':
# DİKKAT: Hem request.POST hem de request.FILES form'a gönderilmelidir!
form = ProjeYuklemeFormu(request.POST, request.FILES)
if form.is_valid():
form.save() # Dosyalar otomatik olarak 'upload_to' dizinlerine kaydedilir
return redirect('basarili_sayfasi')
else:
form = ProjeYuklemeFormu()
return render(request, 'proje_yukle.html', {'form': form})
4. Şablon (Template) Tarafındaki En Kritik Kural: enctype
Dosya yükleme işleminin HTML tarafında çalışabilmesi için <form> etiketine mutlaka enctype="multipart/form-data" özelliğini eklemelisiniz. Bu özellik olmadan, form gönderildiğinde dosyalar sunucuya asla ulaşmaz, sadece dosyanın adı metin olarak gider.
<h2>Yeni Proje Yükle</h2>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Projeyi Sisteme Yükle</button>
</form>
Özetle, dosya yüklerken üç altın kuralımız var:
settings.pyiçinde MEDIA ayarlarını yapmak.Form etiketine
enctype="multipart/form-data"eklemek.View içerisinde formu
request.POST, request.FILESşeklinde başlatmak.
Bu adımlarla formlar üzerinden veritabanına ve sunucu klasörlerine başarılı bir şekilde dosya altyapısını kurmuş olduk.
Form serimizin bu son bölümünde, sisteme başarıyla yüklediğimiz dosyaları nasıl sergileyeceğimizi göreceğiz. Öğrencilerinizin Pardus ETAP 23 üzerinde hazırladığı ve sisteme yüklediği projeleri akıllı tahtada sergilemek veya teknik bloglarınızdaki eğitim makalelerine eksiksiz bir final yapmak için bu adım çok önemlidir.
Bir önceki bölümde yüklediğimiz veriler veritabanına sadece bir metin (dosya yolu) olarak kaydedilir. Bu dosyaları ekranda göstermek veya indirtmek için o dosya yolunu doğru şekilde HTML'e aktarmamız gerekir.
İşte eğitim serimizin final bölümü:
Django'da Yüklenen Medya Dosyalarını (Resim ve Belge) Görüntüleme
Veritabanına kaydedilen bir ImageField veya FileField, doğrudan HTML içine yazdırılamaz. Django'ya "Bu dosyanın URL adresini (bağlantısını) bana ver" dememiz gerekir. Bunu yapmak için şablonlarımızda dosya alanının sonuna .url ekini kullanırız.
1. Verileri Görünüm (View) Üzerinden Çekmek
Öncelikle, sisteme yüklenen projeleri veritabanından alıp şablonumuza gönderecek basit bir görünüm hazırlayalım.
# views.py
from django.shortcuts import render
from .models import OgrenciProjesi
def proje_listesi(request):
# Veritabanındaki tüm projeleri alıyoruz
projeler = OgrenciProjesi.objects.all()
return render(request, 'proje_listesi.html', {'projeler': projeler})
2. Şablonda (Template) Resimleri Göstermek
Bir resmi ekranda göstermek için standart HTML <img> etiketini kullanırız. Ancak src (kaynak) niteliğine doğrudan veritabanı alanını değil, onun URL'sini vermeliyiz.
<img src="{{ proje.kapak_fotografi }}">
<img src="{{ proje.kapak_fotografi.url }}" alt="{{ proje.proje_adi }}">
3. Şablonda Dosya İndirme Linki Oluşturmak
Bir PDF, Word belgesi veya zip dosyasını indirtmek için HTML'in bağlantı etiketi olan <a> kullanılır. href niteliğine yine dosyamızın URL'sini veririz.
<a href="{{ proje.proje_dosyasi.url }}" download>Proje Dosyasını İndir</a>
(İpucu: download özelliği, tarayıcıya bu dosyayı açmak yerine doğrudan indirmesini söyler.)
4. Hayati Kural: Boş Dosyaları Kontrol Etmek (if Kullanımı)
Eğer modelinizi oluştururken bir resim veya dosya alanına blank=True, null=True (yani zorunlu değil) özelliği verdiyseniz, çok dikkatli olmalısınız.
Öğrenci projeye bir kapak fotoğrafı yüklemediyse ve siz şablonda {{ proje.kapak_fotografi.url }} yazarsanız, Django olmayan bir dosyanın URL'sini bulmaya çalışacağı için hata verir ve sayfa çöker.
Bunu önlemek için şablonda her zaman bir {% if %} bloğu ile dosyanın var olup olmadığını kontrol etmeliyiz:
{% if proje.kapak_fotografi %}
<img src="{{ proje.kapak_fotografi.url }}" alt="Kapak Resmi">
{% else %}
<p>Bu proje için kapak resmi yüklenmemiştir.</p>
{% endif %}
5. Tüm Parçaları Birleştirelim (Bootstrap Kart Yapısı ile)
Öğrenci projelerini yan yana güzel kartlar (cards) halinde listelemek için tüm bu bilgileri birleştiren tam bir HTML şablonu örneği:
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<title>Öğrenci Projeleri</title>
</head>
<body>
<div class="container mt-5">
<h2>Sisteme Yüklenen Projeler</h2>
<div class="row">
{% for proje in projeler %}
<div class="col-md-4 mb-4">
<div class="card">
{% if proje.kapak_fotografi %}
<img src="{{ proje.kapak_fotografi.url }}" class="card-img-top" alt="{{ proje.proje_adi }}">
{% endif %}
<div class="card-body">
<h5 class="card-title">{{ proje.proje_adi }}</h5>
{% if proje.proje_dosyasi %}
<a href="{{ proje.proje_dosyasi.url }}" class="btn btn-success" download>
📁 Dosyayı İndir
</a>
{% endif %}
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</body>
</html>
Bu son adımla birlikte Django Formları eğitim serimizi tamamlamış olduk! Veri almaktan doğrulamaya, tasarımdan dosya yükleme ve sergilemeye kadar tam bir akışı kurguladık.
Yorumlar
Yorum Gönder