Everion Consulting
Everion Consulting
HomeBlogDjango Signals: İleri Seviye Kullanım

Django Signals: İleri Seviye Kullanım

Django Signals: İleri Seviye Kullanım
Gökçe Güler

Gökçe Güler

15 August 2025

Django

Önceki yazılarımdan biri olan Django Signals Nedir? Temel Kullanım Rehberi'nde Django Signals’ın temel mantığını anlatmıştık. O yazıda bir kapı zilini örnek alarak sinyallerin nasıl “olay bazlı” çalıştığını, sender–receiver–signal üçlüsünü ve “loose coupling” yani gevşek bağlılık ilkesinin neden bu kadar önemli olduğunu konuşmuştuk. Bu yapı projelerinizde modüllerin birbirine doğrudan bağımlı olmadan haberleşmesini sağlar ve bu sayede kod hem modüler hem de yeniden kullanılabilir hale gelir.

Bu yazıda ise temellerin ötesine geçiyoruz. Django Signals’ın ileri seviye kullanım yöntemlerini, gerçek hayatta karşılaşabileceğiniz senaryolar üzerinden hem kod örnekleriyle hem de açıklamalarla ele alacağız. Buradaki amacımız yalnızca “nasıl yapılır” sorusunu değil “ne zaman yapılmalı” ve “nasıl doğru yapılır” sorularını da cevaplamak.

Özel (Custom) Signal Tanımlama

Django post_save, pre_delete, m2m_changed gibi yaygın olaylar için hazır sinyaller sunar. Ancak bazen uygulamanıza özgü, tamamen yeni bir olay akışına ihtiyacınız olabilir. Örneğin bir siparişin “kargo hazır” durumuna geçmesiyle hem müşteri bilgilendirilmeli hem de stok yönetim sistemi tetiklenmelidir. Bu gibi durumlarda kendi özel sinyalinizi tanımlayabilirsiniz.

from django.dispatch import Signal
# Özel sinyal tanımı
order_ready_for_shipping = Signal()
# Bir noktada bu sinyali tetiklemek
order_ready_for_shipping.send(sender=None, order_id=123)

Custom sinyal tanımlamak size büyük esneklik sağlar çünkü bu olaya tepki verecek bileşenlerin kim olduğunu bilmek zorunda değilsiniz. Ancak bu özgürlüğün bir bedeli vardır: Gereksiz yere custom sinyal kullanmak projeyi karmaşıklaştırabilir. Eğer halihazırda var olan bir Django sinyali işinizi görebiliyorsa onu tercih etmek her zaman daha basit bir çözümdür.

Performans ve Gereksiz Tetiklemeler

Signals’ın cazibesi her olay gerçekleştiğinde otomatik devreye girmesidir. Fakat bu dikkat edilmezse performans sorunlarına yol açabilir. Örneğin post_save sinyali bir modelin her kaydedilişinde çalışır. Yani sadece yeni kayıt eklendiğinde değil her güncellemede de tetiklenir.

Bu yüzden signal fonksiyonlarını yazarken koşullu kontroller eklemek kritik önemdedir. Örneğin:

from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import Order
@receiver(post_save, sender=Order)
def notify_new_order(sender, instance, created, **kwargs):
    if created:
        print(f"Yeni sipariş oluşturuldu: {instance.id}")

Burada if created: kontrolü sayesinde sadece yeni kayıt oluşturulduğunda işlem yapıyoruz. Böylece gereksiz tetiklemelerin önüne geçmiş oluyoruz. Ayrıca ağır iş yüklerini (örneğin rapor oluşturma, e-posta gönderme) sinyal içinde doğrudan yapmak yerine Celery gibi bir task queue sistemine aktarmak performansı ciddi anlamda iyileştirir.

Test Ortamında Signals ile Çalışmak

Test süreçlerinde signals bazen beklenmedik yan etkiler doğurabilir. Örneğin post_save içinde e-posta gönderen bir fonksiyon test sırasında da tetiklenip gerçek e-posta göndermeye çalışabilir.

Bunu engellemek için iki yaklaşım kullanılabilir. Birincisi testlerde ilgili fonksiyonları mock ile devre dışı bırakmak. İkincisi ise disconnect() ile sinyalleri tamamen kapatmak:

from django.db.models.signals import post_save
# Test setup sırasında
post_save.disconnect(receiver=notify_new_order, sender=Order)

Bu yöntem sayesinde testleriniz hem daha izole hem de çok daha hızlı çalışır.

Büyük Projelerde Signal Mimarisini Yönetmek

Küçük projelerde sinyalleri models.py içinde tanımlamak sorun olmaz. Ancak proje büyüdükçe bu yapı, okunabilirlik ve bakım açısından sıkıntılı hale gelir. En iyi pratiklerden biri, tüm sinyalleri signals.py adında ayrı bir dosyada toplamak ve apps.py içinden import etmektir.

# apps.py
def ready(self):
    import myapp.signals

Bu yöntem hangi sinyalin nerede tanımlandığını kolayca bulmanızı sağlar ve kodun merkezi bir şekilde yönetilmesine yardımcı olur.

Signal mı, Direkt Fonksiyon Çağrısı mı?

Signals güçlüdür ama her zaman en iyi çözüm değildir. Eğer iki bileşen zaten doğal olarak birbirine bağlıysa örneğin bir form kaydının ardından log eklemek gibi doğrudan fonksiyon çağrısı yapmak daha basit ve okunabilir olur.

Signals özellikle gevşek bağlılık sağlamak istediğiniz durumlarda tercih edilmelidir. Yani tetikleyici taraf, alıcı tarafın kim olduğunu bilmemelidir. Bu kodunuzu gelecekte değiştirmeyi ve yeniden kullanılabilir hale getirmeyi kolaylaştırır.

Sonuç

Django Signals olay bazlı yazılım geliştirme yaklaşımının Django içindeki en güçlü araçlarından biridir. Ancak onu doğru senaryolarda bilinçli bir şekilde kullanmak gerekir. Gereksiz sinyal kullanımı hem performansı hem de kod okunabilirliğini olumsuz etkileyebilir.

Doğru kullanıldığında ise signals projenize esneklik, modülerlik ve sürdürülebilirlik katar. Bir sonraki aşamada signals ile asenkron işlemler yönetmeyi ve custom dispatcher yapıları oluşturmayı ele alacağız. Bu sayede büyük ve karmaşık uygulamalarda dahi olay bazlı yapının gücünden en yüksek verimi alabilirsiniz.

Kaynakça
Django Signals – Official Documentation