İçeriğe geç

Django Context Processors

Giriş.

Django ile geleneksel bir web uygulaması geliştiriyor iseniz, templatelerda kullanılmak üzere mutlaka context paslamış olmalısınız. Context kavramı template üzerinde erişilebilen, Django template language içerisinde anlamlı olan, key-value şeklinde Python sözlükleridir.

Kısa bir hatırlatma geçecek olursak;

from django.shortcuts import render
def home(request):
    return render(request, "index.html", context={"title": "Home"})

Yukarıdaki gibi bir view yazdığımız durumda, index.html içerisinde, pasladığımız contexti aşağıdaki gibi kullanabiliriz.

<h1>
    Hello you are on {{title}} page.
</h1>

Bazı durumlarda, proje genelinde bir çok template üzerinde kullanılacak olan contextlere ihtiyacımız olabilir. Bu gibi durumlarda, contextin kullanılacağı her templatei render eden viewa bunu açıkca belirtip, kendimizi tekrar etmektense context processor kullanabiliriz.

Context processor nedir?

Context processor kavramı, esasen Django Template Language içerisinde anlamlı olan ve templateler içerisinde kullanılabilecek olan nesneleri tutan Python sözlükleridir. Projenizin settings dosyasında TEMPLATES değişkeni içerisinde tanımlanır ve yeni bir Django projesinde varsayılan olarak aşağıdaki gibidir.

Django,  request-response döngüsünde, template render edilmeden hemen önce context processorler sırasıyla çalıştırılır, döndürdükleri nesne veya değerleri template içerisinde viewdan dönen context ile birleştirir ve kullanılabilir hale getirir.

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [str(BASE_DIR / "templates")],
        "APP_DIRS": True,
        "OPTIONS": {
            "context_processors": [
                "django.template.context_processors.debug",
                "django.template.context_processors.request",
                "django.contrib.auth.context_processors.auth",
                "django.contrib.messages.context_processors.messages",
            ],
        },
    },
]

Varsayılan contextler arasında en çok kullanılanlar, muhtemelen sizinde daha önce kullandığınız, gelen isteğe ulaşılan request ve tek seferlik mesaj gösterimi için bind edilen mesajları toplayan ve paslayan messages processor’idir.

Çalışma mantığını anladığımıza göre, kendimizi her viewda tekrar etmektense birden fazla yerde kullanılacak contexti döndüren bir processor yazmaya göz atalım.

Context processor’ler basit bir interface üzerine kurulu Python fonksiyonlarıdır.

Argüman olarak request nesnesini alırlar, ve geriye gerekli olan veriyi içeren bir Python sözlüğü döndürürler.

Proje içerisinde, herhangi bir pathte yaşayabilirler. Fakat anlamsal bir bütünlük sağlama ve tekrar kullanılabilirlik adına, bağlı olduğu uygulama içerisinde genellikle context_processors.py dosyasında tutulur.

Örneğin, uygulama versiyon tarihini, ve versiyon numarasını settings üzerinden okuyan ve döndüren bir processor yazalım. (Bu tarz processorler doğrudan projeyi ilgilendirdiğinden bir uygulama içine konulmadan ana proje dosyasında yaşayabilir.)

your_project/context_processors.py

from django.conf import settings
def app_info_constants(request):
    return {
        "APP_VERSION_DATE": settings.APP_VERSION_DATE,
        "APP_VERSION": settings.APP_VERSION,
    }

Gerekli olan processorı yazdık fakat, geçerli olması ve kullanılabilmesi için TEMPLATES değişkeni içerisinde kayıt etmeliyiz.

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [str(BASE_DIR / "templates")],
        "APP_DIRS": True,
        "OPTIONS": {
            "context_processors": [
                "django.template.context_processors.debug",
                "django.template.context_processors.request",
                "django.contrib.auth.context_processors.auth",
                "django.contrib.messages.context_processors.messages",
                "my_project.context_processors.app_info_constants"
            ],
        },
    },
]

Kayıt işlemi tamamlandıktan sonra, template içerisinde doğrudan aşağıdaki gib kullanılabilir.

Örneğin footer.html

 <footer>
  <p>App version: {{APP_VERSION}}</p>
  <p>Last version date {{APP_VERSION_DATE}} </p>
</footer> 

Daha sonra index.html içerisine veya kullanılacak tüm template’lere dahil edebiliriz.

<h1>
    Hello you are on {{title}} page.
</h1>
<br>
{% include 'footer.html' %}

Başka bir örnek;

Bir blog sistemi geliştiriyor ve gönderilerin bağlı olduğu etiketlerin urllerini birden fazla yerde kullanmak istiyor olabiliriz. posts uygulamamımızın olduğunu varsayarsak;

posts/context_processors.py
from .models import Tag
def tags_info(request):
    return {
        "tags_urls": [
            {"name": tag.name, "url": tag.get_absolute_url()}
            for tag in Tag.objects.only("name")
        ]
    }

get_absolute_url metodu hakkında bilgi almak isterseniz.

Kayıt işleminin ardından

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [str(BASE_DIR / "templates")],
        "APP_DIRS": True,
        "OPTIONS": {
            "context_processors": [
                "django.template.context_processors.debug",
                "django.template.context_processors.request",
                "django.contrib.auth.context_processors.auth",
                "django.contrib.messages.context_processors.messages",
                "my_project.context_processors.app_info_constants",
                "my_app.context_processors.tags_info"
            ],
        },
    },
]

Template içerisindeki kullanımı;

{% for tag in tags_urls %}
    
    <a href="{{tag.url}}">{{tag.name }}</a>
{% endfor %}

Sonuç.

2 örnekle context processorlerin nasıl çalıştığı, ve kendimizi tekrar etmeden bir template içine nasıl veri paslanabileceğini görmüş olduk. Olabildiğince basit ve anlaşılabilir tutmaya çalıştım ki umarım siz de benimle aynı düşüncedesinizdir. 🙂

Django ile gelen yerleşik context processorlere ise kesinlikle göz atmanızı öneriyorum.

İyi çalışmalar dilerim!

 

Tarih:Blog

İlk Yorumu Siz Yapın

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.

Göster
Gizle