Django urls.py: Web Projenizin Trafik Kontrol Merkezi

Django'da urls.py, web uygulamanızın "trafik polisi" veya "resepsiyonu" gibidir. Gelen isteğin nereye gitmesi gerektiğini o belirler. Bu mekanizmayı iyi anlamak, sağlam bir Django projesi geliştirmenin temelidir.


Django'da bir kullanıcı web sitenizdeki bir sayfayı talep ettiğinde (örneğin: www.site.com/blog/makale-1/), Django'nun ilk baktığı yer URL yapılandırmasıdır. Bu rehberde, URL'lerin nasıl çalıştığını, dinamik yapıları ve en iyi pratikleri inceleyeceğiz.

1. Temel Mantık: URL Dispatcher (Yönlendirici)

Django'nun çalışma prensibi şöyledir:

  1. Kullanıcı bir istek (request) gönderir.

  2. Django, projenin ana urls.py dosyasına bakar.

  3. URL desenlerini (patterns) yukarıdan aşağıya doğru tarar.

  4. İlk eşleşen deseni bulduğunda durur ve isteği ilgili View (Görünüm) fonksiyonuna iletir.

  5. Eşleşme bulamazsa 404 Page Not Found hatası döndürür.

Basit Bir Örnek

Bir urls.py dosyası genellikle şöyle görünür:

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

urlpatterns = [
    path('', views.ana_sayfa, name='home'),
    path('hakkimizda/', views.hakkimizda, name='about'),
]
  • path(): URL tanımı yapan fonksiyon.

  • '': Boş string, ana sayfayı (root) temsil eder.

  • views.ana_sayfa: Bu URL çağrıldığında çalışacak Python fonksiyonu.

  • name='home': Bu URL'e verdiğimiz takma ad (buna ileride değineceğiz).


2. Dinamik URL'ler ve Path Converter'lar

Her sayfa için (örneğin 1000 tane blog yazısı için) tek tek URL yazamayız. Bunun yerine dinamik parametreler kullanırız. Django, URL içindeki değişkenleri yakalayıp view fonksiyonuna argüman olarak gönderir.

Sözdizimi: <tip:degisken_adi>

Python:
urlpatterns = [
    # Örnek: /urun/15/
    path('urun/<int:id>/', views.urun_detay, name='product_detail'),
    
    # Örnek: /profil/ahmet/
    path('profil/<str:username>/', views.profil_detay, name='profile'),
    
    # Örnek: /blog/django-rehberi/
    path('blog/<slug:slug>/', views.makale_detay, name='article_detail'),
]

Bu URL'ler tanımlandığında, view fonksiyonunuz şu şekilde parametre almalıdır:

Python:
# views.py
def urun_detay(request, id):
    # 'id' parametresi URL'den gelir (Tipi integer'dır)
    ...

Sık Kullanılan Converter Türleri

ConverterAçıklamaÖrnek Eşleşme
intSadece tam sayıları eşleştirir.1, 50, 123
str/ hariç tüm karakterleri eşleştirir (Varsayılan).merhaba, kullanici-1
slugHarf, sayı, tire ve alt çizgi içerir. SEO dostu URL'ler için idealdir.yeni-makale-basligi
uuidUUID formatındaki stringleri eşleştirir.a0eebc99-9c0b...

3. Proje ve Uygulama (App) Ayrımı: include()

Büyük projelerde tüm URL'leri tek bir urls.py dosyasına yazmak karmaşaya yol açar. Django'nun modüler yapısını kullanarak her uygulamanın (app) kendi urls.py dosyasını oluşturmalıyız.

Senaryo: Bir E-ticaret sitemiz var. blog ve magaza adında iki uygulamamız olsun.

Adım 1: Ana Proje Dosyası (proje/urls.py)

Burada trafiği ilgili uygulamalara dağıtırız.

Python:
from django.contrib import admin
from django.urls import path, include  # include'u import etmeyi unutmayın

urlpatterns = [
    path('admin/', admin.site.urls),
    path('blog/', include('blog.urls')),     # /blog/ ile başlayanlar buraya
    path('magaza/', include('magaza.urls')), # /magaza/ ile başlayanlar buraya
]

Adım 2: Uygulama Dosyası (blog/urls.py)

Burada sadece blog ile ilgili yollar tanımlanır.

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

urlpatterns = [
    path('', views.index, name='index'),          # Erişim: site.com/blog/
    path('<int:id>/', views.detay, name='detail'),# Erişim: site.com/blog/5/
]

Önemli Not: include kullanıldığında, ana URL'deki önek (prefix) kesilir ve kalan kısım alt urls.py dosyasına gönderilir.


4. URL İsimlendirme (Reverse Resolution)

URL'leri hard-code olarak (elle yazarak) kullanmak çok büyük bir hatadır.

  • ❌ Kötü: <a href="/blog/makale/5/">

  • ✅ İyi: <a href="{% url 'detail' 5 %}">

URL'lere name parametresi vererek, daha sonra URL yapısı değişse bile kodunuzun çalışmaya devam etmesini sağlarsınız.

Template (HTML) içinde kullanımı:

HTML:
<a href="{% url 'product_detail' id=15 %}">Ürünü İncele</a>

View (Python) içinde kullanımı:

Python:
from django.shortcuts import redirect, reverse

def satin_al(request):
    # İşlemler...
    return redirect('success_page') 
    # veya
    url = reverse('product_detail', kwargs={'id': 15})

5. Namespace (İsim Alanları)

Projenizde blog uygulamasında bir detail sayfası var, magaza uygulamasında da bir detail sayfası var. {% url 'detail' %} dediğinizde Django hangisine gidecek? Bu çakışmayı önlemek için Namespace kullanırız.

blog/urls.py içine şunu ekleyin:

Python:
app_name = 'blog' # Uygulama adı tanımlama
urlpatterns = [
    path('<int:id>/', views.detay, name='detail'),
]

Kullanımı:

Artık URL'leri çağırırken uygulama adını da belirtirsiniz:

  • Template: {% url 'blog:detail' 5 %}

  • Python: reverse('blog:detail', args=[5])


6. Regex (Düzenli İfadeler) ile re_path

Standart path converter'lar yetersiz kaldığında (örneğin karmaşık bir ID yapısı veya eski URL'leri desteklemek için), Regular Expression kullanabilirsiniz.

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

urlpatterns = [
    # Yıl (4 rakam) ve Ay (2 rakam) ile eşleşen bir arşiv URL'i
    # Örnek: /arsiv/2023/12/
    re_path(r'^arsiv/(?P<yil>[0-9]{4})/(?P<ay>[0-9]{2})/$', views.arsiv_view),
]

Not: Yeni projelerde path kullanılması önerilir, re_path sadece zorunlu hallerde kullanılmalıdır.


7. Class-Based Views (Sınıf Tabanlı Görünümler)

Eğer fonksiyon yerine Class-Based View (CBV) kullanıyorsanız, URL tanımında .as_view() metodunu çağırmanız gerekir.

Python:
from .views import MakaleListView

urlpatterns = [
    path('makaleler/', MakaleListView.as_view(), name='makale_listesi'),
]

8. Hata Yönetimi (Custom 404/500)

Django'nun varsayılan hata sayfaları yerine kendi özel sayfalarınızı göstermek isterseniz, ana urls.py dosyasında handler tanımlayabilirsiniz.

Python:
# proje/urls.py (Ana dosya)

handler404 = 'my_app.views.custom_404_view'
handler500 = 'my_app.views.custom_500_view'

(Bunun çalışması için settings.py içinde DEBUG = False olmalıdır.)


Özet: En İyi Pratikler (Best Practices)

  1. Her zaman name kullanın: URL'leri asla elle yazmayın, isimlendirmeyi kullanın.

  2. Sondaki Slash (/): Django standart olarak URL'lerin sonuna / koyar. Tanımlarınızı path('hakkimizda', ...) yerine path('hakkimizda/', ...) şeklinde yapın.

  3. App urls.py: Tüm URL'leri ana dosyaya yığmayın, include kullanarak modüler yapıyı koruyun.

  4. Mantıklı Sıralama: Django yukarıdan aşağıya tarar. Özel durumları (blog/yeni/) genel durumlardan (blog/<slug>/) önce yazın. Aksi takdirde "yeni" kelimesini bir slug zannedip detay sayfasına yönlendirebilir.


Bu yapı, temiz, bakımı kolay ve ölçeklenebilir bir Django projesi için en önemli adımlardan biridir.


📌 Django urls.py

1️⃣ urls.py Nedir?

urls.py, Django’da URL yönlendirme (routing) işlemlerinin yapıldığı dosyadır.

🌐 Tarayıcıdan gelen bir isteğin
hangi view (fonksiyon / class) tarafından karşılanacağını belirler.

📌 Kısaca:

URL  →  urls.py  →  view  →  response

2️⃣ Django URL Mantığı (Büyük Resim)

Django’da iki seviyede URL vardır:

SeviyeDosya
Proje URL’leriproject/urls.py
Uygulama URL’leriapp/urls.py

📂 Örnek yapı:

myproject/
│
├── myproject/
│   └── urls.py
│
├── blog/
│   ├── views.py
│   └── urls.py

3️⃣ Proje Seviyesi urls.py

🔹 Varsayılan hali

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

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

Açıklama:

KodAnlamı
path()        URL tanımlar
'admin/'        Tarayıcıdan girilen yol
admin.site.urls        Admin paneline yönlendirir

4️⃣ Basit URL → View Eşleştirme

views.py

from django.http import HttpResponse

def home(request):
    return HttpResponse("Ana Sayfa")

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.home),
]

📌 Sonuç:

http://127.0.0.1:8000/  →  Ana Sayfa

5️⃣ path() Fonksiyonunu Derinlemesine İnceleme

path(route, view, kwargs=None, name=None)
ParametreAçıklama
route        URL yolu
view        Çalışacak fonksiyon / class
kwargs        Ek parametreler
name        URL adı (çok önemli!)

6️⃣ URL Parametreleri (Dynamic URLs)

🔹 Integer parametre

path('post/<int:id>/', views.post_detail)

views.py

def post_detail(request, id):
    return HttpResponse(f"Post ID: {id}")

📌 Örnek URL:

/post/5/

🔹 String parametre

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

🔹 Desteklenen Türler

TürAçıklama
int        Tam sayı
str        Metin
slug        URL dostu metin
uuid        UUID
path        Slash dahil her şey



7️⃣ include() ile App URL’lerini Ayırmak (Best Practice)

🔹 Proje urls.py

from django.urls import path, include

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

🔹 App urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.blog_home),
    path('post/<int:id>/', views.post_detail),
]

📌 Sonuç:

/blog/
/blog/post/3/

8️⃣ URL Name Kullanımı (ÇOK ÖNEMLİ)

urls.py

path('login/', views.login_view, name='login')

templates

<a href="{% url 'login' %}">Giriş</a>

views.py

from django.shortcuts import redirect

return redirect('login')

🎯 Avantaj:

  • URL değişse bile kod bozulmaz

  • Temiz ve sürdürülebilir yapı


9️⃣ Class-Based Views (CBV) ile URLs

from django.urls import path
from .views import HomeView

urlpatterns = [
    path('', HomeView.as_view(), name='home'),
]

📌 .as_view() zorunludur.


🔟 Regex ile URL (re_path)

from django.urls import re_path

re_path(r'^post/(?P<id>[0-9]+)/$', views.post_detail)

📌 Güncel Django’da çoğu zaman gerekmez, path() yeterlidir.


1️⃣1️⃣ Hatalı URL Senaryoları (Öğretici)

❌ Yanlış:

path('post/<id>/', views.post_detail)

✔ Doğru:

path('post/<int:id>/', views.post_detail)

1️⃣2️⃣ 404 ve URL Debug

  • Yanlış URL → 404 Not Found

  • DEBUG=True iken detaylı hata sayfası

  • python manage.py show_urls (django-extensions)


1️⃣3️⃣ Güvenlik ve İyi Uygulamalar

✅ URL’leri sade tut
include() kullan
name parametresini ihmal etme
❌ View logic’i URL’ye koyma


1️⃣4️⃣ Gerçek Hayat Örneği

urlpatterns = [
    path('', views.home, name='home'),
    path('login/', views.login_view, name='login'),
    path('logout/', views.logout_view, name='logout'),
    path('profile/<slug:username>/', views.profile, name='profile'),
]

1️⃣5️⃣ Özet

  • urls.py = Django’nun yol haritası

  • path() → %90 yeterli

  • include() → büyük projelerde şart

  • name → profesyonel Django kodu


Django Orta–İleri Seviye URL Tasarım Prensipleri

1️⃣ URL = API Sözleşmesi Gibi Düşün

URL’ler rastgele string’ler değil, dış dünyaya verdiğin bir sözdür.

❌ Kötü:

/getUserDataById/5/
/do_login_now/

✅ İyi:

/users/5/
/login/

📌 Kural:
URL → ne olduğu söyler, nasıl yapıldığını söylemez


2️⃣ Fiil Değil, İsim Kullanın (REST Mantığı)

❌ Yanlış:

/create-post/
/delete-user/5/

✅ Doğru:

/posts/
/users/5/

👉 İşlemi view yapar, URL nesneyi temsil eder.


3️⃣ URL’lerde Hiyerarşi Kur

URL yapısı, veri modelini zihinde canlandırmalı.

/users/
/users/5/
/users/5/posts/
/users/5/posts/12/

📌 Okuyan kişi:

“Bir kullanıcının bir postuna gidiyorum” demeli


4️⃣ include() ile Modüler Mimari (ŞART)

❌ Tek dosya cehennemi

# project/urls.py
path('blog/post/...')
path('blog/comment/...')
path('auth/login/...')

✅ Profesyonel yapı

path('blog/', include('blog.urls'))
path('accounts/', include('accounts.urls'))

📌 Büyük projelerde include() kullanmamak teknik borçtur.


5️⃣ URL Namespace Kullan (İleri Seviye)

app/urls.py

app_name = 'blog'

urlpatterns = [
    path('', views.index, name='index'),
]

Template:

{% url 'blog:index' %}

🎯 Avantaj:

  • Aynı name çakışmaz

  • Büyük projelerde netlik


6️⃣ URL Name = Tek Doğru Referans

❌ Template içinde:

<a href="/login/">Giriş</a>

✅ Doğru:

<a href="{% url 'login' %}">Giriş</a>

📌 URL değişir, hiçbir şey bozulmaz.


7️⃣ Slug Kullanımı (SEO + Okunabilirlik)

/post/17/

/post/django-urls-egitimi/

URL

path('post/<slug:slug>/', views.post_detail)

📌 Blog, haber, içerik siteleri için olmazsa olmaz.


8️⃣ Class-Based View + URL Uyumu

❌ Mantıksız:

path('create-post/', PostDetailView.as_view())

✅ Mantıklı:

path('posts/<slug:slug>/', PostDetailView.as_view())

📌 URL → nesne
📌 View → işlem


9️⃣ Çok Fazla Parametre Koyma

❌ Aşırı:

/post/5/user/3/comment/7/type/full/

✅ Temiz:

/posts/5/comments/7/

🎯 Okunabilirlik > Her şeyi URL’ye koymak


🔟 URL Versiyonlama (İleri / API Mantığı)

Web app + API varsa:

/api/v1/posts/
/api/v2/posts/

📌 Gelecekte geriye dönük uyumluluk sağlar.


1️⃣1️⃣ URL Güvenlik Prensipleri

❌ Hassas bilgi:

/reset-password/12345/

✅ Token bazlı:

/reset-password/<uuid:token>/

📌 ID ≠ Güvenlik


1️⃣2️⃣ re_path() Kullanman Gereken Nadir Durumlar

Sadece gerçekten regex gerekiyorsa:

re_path(r'^files/(?P<path>.*)$', views.files)

📌 %90 projede gerekmez


1️⃣3️⃣ URL Yapısı Test Edilebilir Olmalı

İyi URL:

  • Kısa

  • Tahmin edilebilir

  • Ezberlenebilir

👀 Test:

“Bu URL’yi bir öğrenci yazabilir mi?”


1️⃣4️⃣ Gerçek Hayat Profesyonel Örnek

# project/urls.py
path('', include('pages.urls')),
path('accounts/', include('accounts.urls')),
path('blog/', include(('blog.urls', 'blog'), namespace='blog')),
# blog/urls.py
urlpatterns = [
    path('', views.PostListView.as_view(), name='list'),
    path('<slug:slug>/', views.PostDetailView.as_view(), name='detail'),
]

1️⃣5️⃣ Altın Kurallar (Özet)

✅ URL sade olmalı
include() + namespace kullan
name olmadan URL yazma
✅ Slug → SEO
❌ Fiil kullanma
❌ Mantığı URL’ye taşıma



Yorumlar

Bu blogdaki popüler yayınlar

Pardus Üzerine Django Kurulumu

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