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ü?

  1. Otomatik HTML Üretimi: Python kodunuzdan otomatik olarak HTML form etiketleri (input, select, textarea vb.) üretir.

  2. 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.

  3. Güvenlik: Kötü niyetli veri girişlerine karşı veriyi temizler (cleaning) ve otomatik CSRF (Cross-Site Request Forgery) koruması sağlar.

  4. 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.

Python:
# 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.

Python:
# 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:

HTML
<!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ı olarak as_table veya as_ul da 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:

Python:
# 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:

Python
# 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.

Python:
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ürAçıklama
forms.FormModelden bağımsız form
forms.ModelFormVeritabanı 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?

  1. GET isteğinde boş form gösterilir

  2. POST isteğinde veri alınır

  3. is_valid() ile doğrulama yapılır

  4. Doğruysa cleaned_data ile 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.

Python
# 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:

Python
# 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:

HTML
<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:

Python
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:

Python
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.

Python
# 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_to Parametresi: Dosyanın MEDIA_ROOT klasö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:

Python
# 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.

Python
# 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.

HTML
<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:

  1. settings.py içinde MEDIA ayarlarını yapmak.

  2. Form etiketine enctype="multipart/form-data" eklemek.

  3. 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.

Python
# 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.

HTML
<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.

HTML
<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:

HTML
{% 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:

HTML
<!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

Bu blogdaki popüler yayınlar

Pardus Üzerine Django Kurulumu

Python ile Web Geliştirme: Django App Oluşturma