Django URL Yapısı: Reverse, Redirect ve Namespace Kullanımı

Django'da URL yönetimi, uygulamanızın hem güvenliği hem de kullanıcı deneyimi (UX) için kritik öneme sahiptir. Kodun içine URL'leri "hardcoded" (el ile sabit) yazmak yerine, Django'nun sunduğu reverse ve redirect araçlarını kullanmak işleri çok daha esnek hale getirir.


1. Django reverse Nedir?

reverse, Django'nun URL tersine çözümleme (URL reversing) mekanizmasıdır. Basitçe ifade etmek gerekirse: Siz Django'ya URL'nin ismini (name) verirsiniz, o size o isme karşılık gelen URL yolunu (string) verir.

Neden Kullanırız?

Eğer projenizde /blog/makale-detay/5/ şeklinde bir URL yapısı varsa ve ileride bunu /icerik/detay/5/ olarak değiştirmeye karar verirseniz, projenin her yerinde tek tek arama yapmanıza gerek kalmaz. Sadece urls.py içinde değişikliği yaparsınız, reverse otomatik olarak yeni yolu bulur.

Kullanım Şekli:

Python:
from django.urls import reverse

# Basit kullanım
url = reverse('home') # Çıktı: '/'

# Dinamik (Argümanlı) kullanım
url = reverse('post-detail', args=[5]) # Çıktı: '/post/5/'

# Keyword (Anahtar Kelime) ile kullanım
url = reverse('archive', kwargs={'year': 2024, 'month': 'february'})

2. Django redirect Nedir?

redirect, kullanıcıyı bir HTTP yanıtı (HttpResponseRedirect) ile başka bir sayfaya yönlendirmek için kullanılır.

redirect fonksiyonu aslında arka planda reverse fonksiyonunu da kullanabilir. Yani ona bir URL ismi verdiğinizde, o önce yolu bulur, sonra kullanıcıyı oraya gönderir.

Kullanım Senaryoları:

  • Kullanıcı bir formu başarıyla doldurduğunda "Teşekkürler" sayfasına göndermek.

  • Giriş yapmamış bir kullanıcıyı "Login" sayfasına yönlendirmek.

Kullanım Şekli:

Python:
from django.shortcuts import redirect

def my_view(request):
    # ... işlemler ...
    return redirect('home') # URL ismine yönlendirme

3. reverse ve redirect Arasındaki Farklar

Birçok yeni geliştirici bu ikisini karıştırır. Aralarındaki temel fark şudur:

Özellikreverseredirect
Döndürdüğü DeğerBir string (Örn: "/hakkimizda/")Bir HttpResponse (Yönlendirme yanıtı)
Kullanım AmacıURL yolunu hesaplamak/bulmak.Kullanıcıyı başka bir sayfaya fiilen göndermek.
Nerede Kullanılır?View'lar içinde, modellerde (get_absolute_url) veya testlerde.Sadece View (Görünüm) fonksiyonlarının sonunda return ile.

4. Uygulamalı Örnek: Bir Form İşleme

Diyelim ki bir blog yazısı oluşturma sayfanız var:

Python:
from django.shortcuts import render, redirect
from django.urls import reverse
from .models import Post

def create_post(request):
    if request.method == 'POST':
        # Formun kaydedildiğini varsayalım
        new_post = Post.objects.create(title=request.POST.get('title'))
        
        # 1. Senaryo: redirect kullanımı (En yaygın olan)
        # Kullanıcıyı detay sayfasına gönderiyoruz
        return redirect('post-detail', pk=new_post.pk)
    
    return render(request, 'create_post.html')

def delete_post(request, pk):
    # 2. Senaryo: reverse kullanımı
    # Bazen URL'yi sadece bir değişkene atayıp başka bir yerde kullanmak istersiniz
    success_url = reverse('home')
    Post.objects.get(pk=pk).delete()
    return redirect(success_url)

5. İleri Seviye İpucu: Modellerde get_absolute_url

Django'da en iyi pratiklerden biri, modelin kendi içine reverse kullanarak bir metod tanımlamaktır. Bu sayede redirect(post_nesnesi) dediğinizde Django nereye gideceğini otomatik anlar.

Python:
from django.db import models
from django.urls import reverse

class Post(models.Model):
    title = models.CharField(max_length=100)

    def get_absolute_url(self):
        return reverse('post-detail', kwargs={'pk': self.pk})

# View içinde artık sadece bunu yapmanız yeterlidir:
# return redirect(post_instance)

Özetle:

  • URL'nin ismini biliyorsunuz ama string haline (yoluna) ihtiyacınız varsa: reverse kullanın.

  • Kullanıcının tarayıcısını başka bir sayfaya uçurmak istiyorsanız: redirect kullanın.


Django Redirect ve reverse

(URL Yönetimi ve Yönlendirme Rehberi)

1. Giriş: Neden Redirect ve reverse?

Django projelerinde:

  • Bir form gönderildikten sonra başka bir sayfaya gitmek

  • URL’leri sabit yazmak yerine merkezi ve güvenli şekilde yönetmek

  • URL değiştiğinde tüm projeyi bozmamak

için redirect ve reverse kullanılır.

🎯 Amaç: URL’leri koddan bağımsız, sürdürülebilir ve güvenli hale getirmek


2. redirect Nedir?

redirect, kullanıcıyı başka bir URL’ye yönlendirmek için kullanılır.

📦 Bulunduğu yer:

from django.shortcuts import redirect

3. redirect Kullanım Türleri

3.1 Sabit URL’ye Redirect

def home(request):
    return redirect('/login/')

📌 Dezavantaj:
URL değişirse tüm kodlar bozulur ❌


3.2 URL Name (Önerilen Kullanım)

def home(request):
    return redirect('login')

📌 Avantaj:

  • URL değişse bile çalışır

  • Django’nun en iyi pratiği ✅


3.3 Parametreli Redirect

def profile_redirect(request):
    return redirect('profile', username='nuri')

URL yapısı:

path('profile/<str:username>/', views.profile, name='profile')

3.4 Model Nesnesi ile Redirect

def post_detail(request, id):
    post = Post.objects.get(id=id)
    return redirect(post)

Model içinde:

def get_absolute_url(self):
    return reverse('post_detail', args=[self.id])

4. reverse Nedir?

reverse, URL name → gerçek URL dönüşümü yapar.

📦 Bulunduğu yer:

from django.urls import reverse

5. reverse Kullanımı

5.1 Basit reverse

url = reverse('login')

Çıktı:

/login/

5.2 Parametreli reverse

reverse('profile', kwargs={'username': 'nuri'})

Çıktı:

/profile/nuri/

5.3 redirect + reverse Birlikte

def go_profile(request):
    return redirect(reverse('profile', kwargs={'username': 'nuri'}))

📌 Not:
redirect() zaten reverse işlemi yaptığı için genelde gerekmez.


6. reverse_lazy Nedir?

Class Based View (CBV) kullanırken lazy (gecikmeli) URL çözümü gerekir.

from django.urls import reverse_lazy

Kullanım:

class LoginView(FormView):
    success_url = reverse_lazy('home')

📌 reverse() burada hata verir ❌
📌 reverse_lazy() güvenlidir ✅


7. redirect vs reverse Karşılaştırması

Özellikredirectreverse
Yönlendirme yapar    
URL üretir    
View içinde kullanılır    
CBV uyumlu    reverse_lazy
Kullanıcıyı taşır    

8. Template (HTML) İçinde reverse

Template’lerde {% url %} etiketi kullanılır.

<a href="{% url 'profile' username='nuri' %}">
  Profil
</a>

📌 Bu yapı reverse’in template karşılığıdır.


9. Gerçek Hayat Senaryosu (Form Sonrası Redirect)

def register(request):
    if request.method == 'POST':
        # kayıt işlemleri
        return redirect('login')
    return render(request, 'register.html')

🎯 Amaç:

  • Sayfa yenilenince tekrar POST olmasın

  • PRG Pattern (Post → Redirect → Get)


10. En İyi Uygulamalar (Best Practices)

✅ URL’leri asla sabit yazma
✅ Her zaman name= kullan
✅ CBV → reverse_lazy
✅ Template → {% url %}
/login/ gibi hard-coded URL kullanma


11. Sık Yapılan Hatalar

❌ URL name yanlış yazmak
❌ Parametre eksik vermek
❌ reverse yerine string URL kullanmak
❌ CBV’de reverse kullanmak


12. Özet

  • redirect → Kullanıcıyı başka sayfaya götürür

  • reverse → URL name’den gerçek URL üretir

  • reverse_lazy → CBV için güvenli çözümdür

  • Django’da URL yönetiminin bel kemiğidir


Aşağıda redirect & reverse konularını birebir gösteren, küçük ama öğretici bir Mini Django Örnek Proje bulacaksın. (Bu proje özellikle ders anlatımı, yazılı sınav ve Pardus laboratuvarı için uygundur.)


Mini Django Projesi

Login → Dashboard Yönlendirmesi (redirect & reverse)

🎯 Amaç

  • reverse ile URL üretmek

  • redirect ile kullanıcıyı yönlendirmek

  • POST → Redirect → GET mantığını görmek

Framework: Django


1️⃣ Proje Yapısı

redirect_project/
│
├── manage.py
├── redirect_project/
│   ├── settings.py
│   ├── urls.py
│
└── accounts/
    ├── views.py
    ├── urls.py
    └── templates/
        └── accounts/
            ├── login.html
            └── dashboard.html

2️⃣ Proje ve App Oluşturma

django-admin startproject redirect_project
cd redirect_project
python manage.py startapp accounts

settings.py içine ekle:

INSTALLED_APPS = [
    ...
    'accounts',
]

3️⃣ URL Yapısı

📄 redirect_project/urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('accounts.urls')),
]

📄 accounts/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('login/', views.login_view, name='login'),
    path('dashboard/', views.dashboard, name='dashboard'),
]

📌 Buradaki name alanları reverse & redirect’in kalbidir


4️⃣ Views (redirect & reverse burada)

📄 accounts/views.py

from django.shortcuts import render, redirect
from django.urls import reverse

def login_view(request):
    if request.method == 'POST':
        username = request.POST.get('username')

        # reverse → URL üretir
        dashboard_url = reverse('dashboard')

        # redirect → kullanıcıyı taşır
        return redirect(dashboard_url)

    return render(request, 'accounts/login.html')


def dashboard(request):
    return render(request, 'accounts/dashboard.html')

📌 Burada olan şey:

URL name → reverse → gerçek URL → redirect → yönlendirme

5️⃣ Template Dosyaları

📄 login.html

<!DOCTYPE html>
<html>
<head>
    <title>Login</title>
</head>
<body>
    <h2>Giriş Yap</h2>

    <form method="post">
        {% csrf_token %}
        <input type="text" name="username" placeholder="Kullanıcı Adı">
        <button type="submit">Giriş</button>
    </form>
</body>
</html>

📄 dashboard.html

<!DOCTYPE html>
<html>
<head>
    <title>Dashboard</title>
</head>
<body>
    <h1>Hoş Geldin 🎉</h1>

    <a href="{% url 'login' %}">Çıkış</a>
</body>
</html>

📌 {% url %}template içindeki reverse


6️⃣ Çalışma Akışı (Çok Önemli)

/login/ (GET)
   ↓
Form Gönderilir (POST)
   ↓
reverse('dashboard')
   ↓
redirect('/dashboard/')
   ↓
/dashboard/ (GET)

🎯 PRG Pattern (Post → Redirect → Get)
➡️ Sayfa yenilendiğinde form tekrar gönderilmez


7️⃣ redirect vs reverse Nerede Kullanıldı?

YerKullanım
urls.pyname='dashboard'
views.pyreverse('dashboard')
views.pyredirect(dashboard_url)
template{% url 'login' %}

8️⃣ Öğretmen / Ders İçin Bonus Görevler

🧠 Öğrenciye sorulabilecek sorular:

  1. reverse neden string URL yerine kullanılır?

  2. redirect('/dashboard/') yazarsak ne kaybederiz?

  3. Template’te {% url %} neyin karşılığıdır?

  4. Bu projede PRG hangi satırda uygulanıyor?


9️⃣ Mini Geliştirme Önerileri

  • 🔐 Login kontrolü ekle

  • 🧩 reverse_lazy ile CBV versiyonunu yaz

  • 🎨 Bootstrap ekle

  • 🚫 Giriş yapmadan dashboard’a girişi engelle


10️⃣ Özet

reverse → URL üretir
redirect → kullanıcıyı taşır
Template {% url %} → reverse’in HTML hali
✅ Bu mini proje → konuyu tam öğretir


Hazırladığımız Mini Django projesine, Django’nun yerleşik Authentication (login–logout) sistemini adım adım, eğitim + proje mantığıyla ekliyorum.

Framework: Django


Mini Projeye Auth (Login – Logout) Ekleme

(redirect & reverse ile tam uyumlu)

🎯 Hedefler

  • Django auth kullanarak gerçek kullanıcı girişi

  • Login sonrası dashboard’a redirect

  • Logout sonrası login sayfasına redirect

  • Giriş yapılmadan dashboard’a erişimi engellemek


1️⃣ Django Auth Hazır mı?

Evet ✅
Django kuruluysa şu paketler zaten hazırdır:

django.contrib.auth
django.contrib.sessions

settings.py içinde kontrol et:

INSTALLED_APPS = [
    ...
    'django.contrib.auth',
    'django.contrib.sessions',
]

2️⃣ URLs – Login & Logout

📄 accounts/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('login/', views.login_view, name='login'),
    path('logout/', views.logout_view, name='logout'),
    path('dashboard/', views.dashboard, name='dashboard'),
]

3️⃣ Views – Gerçek Auth İşlemleri

📄 accounts/views.py

from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.urls import reverse

def login_view(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')

        user = authenticate(request, username=username, password=password)

        if user is not None:
            login(request, user)
            return redirect('dashboard')
        else:
            return render(request, 'accounts/login.html', {
                'error': 'Kullanıcı adı veya şifre hatalı'
            })

    return render(request, 'accounts/login.html')


@login_required(login_url='login')
def dashboard(request):
    return render(request, 'accounts/dashboard.html')


def logout_view(request):
    logout(request)
    return redirect('login')

📌 Burada neler var?

  • authenticate() → kullanıcıyı doğrular

  • login() → session başlatır

  • logout() → session kapatır

  • @login_required → yetkisiz erişimi engeller

  • redirect('dashboard') → reverse + redirect birlikte


4️⃣ Template – Login Sayfası

📄 login.html

<!DOCTYPE html>
<html>
<head>
    <title>Login</title>
</head>
<body>

<h2>Giriş Yap</h2>

{% if error %}
    <p style="color:red;">{{ error }}</p>
{% endif %}

<form method="post">
    {% csrf_token %}
    <input type="text" name="username" placeholder="Kullanıcı Adı" required>
    <br><br>
    <input type="password" name="password" placeholder="Şifre" required>
    <br><br>
    <button type="submit">Giriş</button>
</form>

</body>
</html>

5️⃣ Template – Dashboard (Auth Kontrollü)

📄 dashboard.html

<!DOCTYPE html>
<html>
<head>
    <title>Dashboard</title>
</head>
<body>

<h1>Hoş Geldin {{ request.user.username }} 🎉</h1>

<p>Burası sadece giriş yapan kullanıcılar içindir.</p>

<a href="{% url 'logout' %}">Çıkış Yap</a>

</body>
</html>

📌 request.user → auth sistemi tarafından otomatik gelir


6️⃣ Kullanıcı Oluşturma (Admin)

python manage.py createsuperuser

➡️ Kullanıcı adı & şifre belirle
➡️ Bu bilgilerle login ol


7️⃣ Çalışma Akışı (Çok Önemli)

/login/
   ↓
authenticate()
   ↓
login()
   ↓
redirect('dashboard')
   ↓
/dashboard/  (korumalı)

Çıkış:
logout()
   ↓
redirect('login')

🎯 Gerçek hayattaki tüm Django projelerinin temeli


8️⃣ Güvenlik & Best Practice

@login_required kullan
✅ URL’leri name= ile yönet
✅ redirect + reverse tercih et
❌ Şifreyi manuel kontrol etme
❌ Session’ı kendin yazma


9️⃣ Öğrenci / Yazılı Soruları (Hazır)

  1. authenticate() ne yapar?

  2. login() ile session arasındaki ilişki nedir?

  3. @login_required neden önemlidir?

  4. Logout işleminden sonra neden redirect yapılır?

  5. {% url 'logout' %} neyin karşılığıdır?


🔟 Bu Proje Artık Ne Oldu?

✅ Gerçek login–logout sistemi
✅ Yetkilendirme (authorization)
✅ redirect & reverse uygulamalı
✅ Pardus / ders / sınav uyumlu
✅ Gerçek Django projelerine %100 geçiş yapılabilir


Django projeleri büyüdükçe, farklı uygulamalar (apps) içinde aynı isimde URL'ler tanımlamanız kaçınılmaz hale gelir. Örneğin, hem bir blog uygulamanız hem de bir video uygulamanız varsa, her ikisinde de bir detail (detay) sayfası olabilir.

İşte burada Namespace (İsim Alanı) devreye girer. Bu, URL'lerinizi paketleyerek birbirleriyle karışmasını önleyen bir "soyadı" sistemi gibidir.


1. Namespace Neden Gereklidir?

Eğer iki farklı urls.py dosyasında da name='detail' tanımı varsa, Django en son yüklenen URL'yi baz alır. Bu da blog:detail yerine yanlışlıkla video:detail sayfasına gitmenize neden olur. Namespace kullanarak "Blog uygulamasındaki detay sayfasına git" demiş olursunuz.


2. Namespace Nasıl Tanımlanır?

Namespace tanımlamanın en yaygın ve doğru yolu, ana urls.py dosyasında include fonksiyonunu kullanırken namespace parametresini belirtmektir.

Ana urls.py (Proje Dizini)

Python:
from django.urls import path, include

urlpatterns = [
    path('blog/', include('blog.urls', namespace='blog')),
    path('videolar/', include('video.urls', namespace='video')),
]

Uygulama urls.py (blog/urls.py)

Uygulama düzeyinde de bir app_name değişkeni tanımlamak en iyi pratiktir:

Python:
from django.urls import path
from . import views

app_name = 'blog' # Bu satır kritik!

urlpatterns = [
    path('<int:pk>/', views.post_detail, name='detail'),
]

3. Namespace ile reverse ve redirect Kullanımı

Artık URL isminin önüne uygulama adını ve iki nokta üst üste (:) işaretini eklemeniz gerekir.

Python Kodunda (View'lar içinde):

Python:
from django.shortcuts import redirect
from django.urls import reverse

def some_view(request):
    # Reverse ile kullanımı
    blog_url = reverse('blog:detail', kwargs={'pk': 5})
    
    # Redirect ile kullanımı
    return redirect('blog:detail', pk=10)

HTML Şablonlarında (Template):

HTML
<a href="{% url 'blog:detail' pk=post.id %}">Yazıyı Oku</a>

4. Gerçek Hayat Senaryosu: "Aynı İsimli View" Karmaşası

Diyelim ki bir e-ticaret siteniz var:

  • products:index (Ürün listesi)

  • orders:index (Sipariş listesi)

Eğer namespace kullanmasaydınız, her iki uygulama için de name='index' tanımlayacaktınız. Django hangisini çağıracağını şaşıracak ve muhtemelen her zaman en son tanımlanan uygulamaya yönlendirecekti. Namespace sayesinde bu belirsizlik ortadan kalkar.


5. Dinamik Instance Namespace (Gelişmiş)

Bazen aynı uygulamayı iki farklı URL altında çalıştırmak isteyebilirsiniz (Örneğin; hem /blog/ hem de /haberler/ aynı blog uygulamasını kullansın ama farklı içerik göstersin). Bu durumda include içindeki namespace değeri dinamikleştirilebilir. Ancak standart projelerde yukarıdaki app_name yöntemi %99 oranında yeterlidir.

Özet:

  • app_name: Uygulamanın içindeki urls.py'da tanımlanır.

  • namespace: Ana urls.py'da include edilirken verilir.

  • Kullanım: 'uygulama_adı:url_adı' formatındadır.

Harika! get_absolute_url, Django’nun en zarif ve "pro" özelliklerinden biridir. Bu metod, bir model nesnesinin "kendi URL'sini bilmesini" sağlar. Namespace yapısıyla birleştiğinde ise tadından yenmez.

Neden buna ihtiyaç duyarız? Çünkü projenin her yerinde (şablonlar, view'lar, admin paneli) URL'yi manuel oluşturmak yerine, nesneye "senin adresin neresi?" diye sormak çok daha güvenlidir.


1. Modelde get_absolute_url Tanımlama

Diyelim ki bir Post (Yazı) modeliniz var ve bu model blog namespace'i altında çalışıyor.

Python:
from django.db import models
from django.urls import reverse

class Post(models.Model):
    title = models.CharField(max_length=200)
    slug = models.SlugField(unique=True)

    def __str__(self):
        return self.title

    # Sihirli metodumuz burada:
    def get_absolute_url(self):
        # Namespace: blog, URL Name: detail
        return reverse('blog:detail', kwargs={'slug': self.slug})

2. Neden Namespace ile reverse Kullandık?

Buradaki reverse('blog:detail', ...) kullanımı sayesinde:

  1. Hata Payı Sıfırlanır: URL yapısını urls.py içinde değiştirseniz bile (örneğin /yazi/ yerine /makale/ yapsanız da), bu metod doğru linki üretmeye devam eder.

  2. Okunabilirlik Artar: Kodun içinde karmaşık URL stringleri dolaşmaz.


3. Kullanım Alanları (İşte Asıl Kolaylık Burada!)

get_absolute_url tanımladığınızda Django size üç büyük avantaj sağlar:

A. Şablonlarda (Template) Kullanım

Artık uzun uzun {% url ... %} yazmanıza gerek kalmaz. Sadece nesnenin metodunu çağırırsınız:

HTML:
<a href="{% url 'blog:detail' slug=post.slug %}">Oku</a>

<a href="{{ post.get_absolute_url }}">Oku</a>

B. View İçinde redirect ile Kullanım

Django'nun redirect fonksiyonu çok akıllıdır. Eğer ona bir model nesnesi verirseniz, o nesnenin get_absolute_url metodu olup olmadığına bakar. Varsa, kullanıcıyı otomatik o adrese gönderir.

Python:
from django.shortcuts import redirect

def post_create_view(request):
    # ... form işlemleri ...
    if form.is_valid():
        new_post = form.save()
        # Sadece nesneyi veriyoruz, gerisini Django hallediyor!
        return redirect(new_post) 

C. Django Admin Paneli

Bu metodu tanımladığınızda, Django Admin panelinde yazı detayına girdiğinizde sağ üst köşede "Sitede Görüntüle" (View on site) butonu belirir. Bu buton sizi doğrudan yazının canlı sayfasına götürür.


4. Namespace + get_absolute_url Akış Şeması

Bu yapıyı kurduğunuzda projenizdeki veri akışı şu şekilde olur:

  1. Veritabanı: Post nesnesi (ID: 5, Slug: 'django-dersi')

  2. Model Metodu: post.get_absolute_url() çağrılır.

  3. Reverse: Django blog:detail ismine bakar, urls.py'dan /blog/django-dersi/ sonucunu üretir.

  4. Sonuç: Kullanıcı veya şablon doğru adresi alır.


Küçük Bir İpucu: redirect İçin Kestirme Yollar

Unutmayın, redirect şu üçünü de kabul eder:

  • Model nesnesi: redirect(my_post) (Metod tanımlıysa)

  • URL ismi: redirect('blog:detail', slug='test')

  • Ham URL: redirect('/blog/test/')

Her zaman ilk iki seçeneği tercih etmek, projenizin bakımını (maintenance) inanılmaz kolaylaştıracaktır.

Yorumlar

Bu blogdaki popüler yayınlar

Pardus Üzerine Django Kurulumu

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