Django’da Statik ve Medya Dosyalarının Sunulma Mantığı

0
13

Günümüzde en çok kullanılan programlama dillerinden olan Python’un web geliştirme çatısı Django‘yu duyanlarınız olmuştur. Django’ya yeni başladıysanız statik dosyaların çalışma mantığı size biraz karmaşık gelebilir. İlk olarak şundan bahsedelim. Django production ortamında hiçbir şekilde statik dosyaları sunmaz. Bu statik dosyaları sunabilmek için Apache ve Nginx gibi web serverlara ihtiyacınız vardır. Django’yu sunacak şekilde yapılandırmanız da doğru bir yaklaşım değildir. Django sadece ilgili python dosyalarını Gunicorn ya da uWSGI gibi python app sunucularla Nginx ya da Apache ile proxy bağlantı kurarak sunar. Statik dosyalar Django’nun ya da Gunicorn’un işi değildir. Zaten development ortamında Gunicorn ya da uWSGI ile de işiniz olmayacak. Çünkü Django, python manage.py runserver komutuyla çalışan basit bir sunucuyu bize sunmaktadır.

Bu mantığı anladıktan sonra statik dosyaların serve edilmesini daha kolay anlayacaksınız. Çoğu zaman production’a çıkıldığında sitenizdeki css, js ve imaj dosyaları ulaşılmaz hale gelir. Vereceğim bilgiler ile bu sorunların önüne geçebilirsiniz.

Django eğer Debug=True olarak ayarlanmışsa kendini development ortamında, False olarak ayarlanmışsa da production ortamında sanar. Development ortamında, runserver ile Django sunucusunu çalıştırdığınızda, Django ilgili statik dosyaları bulur ve başarılı şekilde sunar. False olarak ayarlanmışsa da dediğim gibi statik dosyalara karışmaz.

İlk olarak setting.py dosyasında bulunan ya da eklenmesi gereken sabitleri tanıyalım.

STATIC_URL = ‘/static/’
STATIC_ROOT’taki dosyalara erişim için referans urldir. <script src=”{% static “app.js” %}”></script> olarak ekliyse <script src=”http://www.example.com/static/app.js”></script> olarak çıkar. Değiştirilmesi genelde soruna yol açmaz.

STATIC_ROOT = os.path.join(BASE_DIR, ‘static/’)
Fiziki olarak statik dosyaların bulunduğu yerdir. python manage.py collectstatic yazılınca tüm applere ve STATICFILES_DIRS‘e eklenen lokasyonlar altında bulunan statik dosyaları ilgili klasöre yani proje ana dizinindeki static/‘e toplar. Canlıya çıkılmadan önce yapılması gereklidir.

MEDIA_URL = ‘/media/’
Media roottaki dosyalara erişim için referans urldir. <img src=”{% get_media_prefix %}uploads/1.jpg”> olarak ekliyse <img src=”http://www.example.com/media/uploads/1.jpg”> olarak çıkar. Değiştirilmesi genelde soruna yol açmaz.

MEDIA_ROOT = os.path.join(BASE_DIR, ‘media/’)
Fiziki olarak media dosyaların bulunduğu yerdir. collectstatic komutu medyaları otomatik toplamaz.

Development ve production senaryoları

  • Django, setting.py dosyasındaki INSTALLED_APPS kısmında ‘django.contrib.staticfiles‘ eklenmişse, runserver komutuyla applerin içinde bulunan statik dosyaları otomatik olarak algılayıp serve eder. Yani dev serveri applerin altında bulunan project/app/static/app/.. kısmından dosyaları sunar. Bu development ortamı için geçerlidir. Debug=False denmişse runserver komutuyla çalıştırılsa bile Django statik dosyaları serve etmez.
  • django.contrib.staticfilesINSTALLED_APPS kısmına ekli değil ve debug true olarak ayarlanmışsa: Django dev serveri applerin altındaki statik dosyaları serve etmez. Çünkü INSTALLED_APPS olmadığından oradakinleri algılamaz.  Production ortamında gibi python manage.py collectstatic komutu çalıştırılıp ilgili statik STATIC_ROOT içine toplanır. Ana urls.py dosyasına aşağıdaki ekleme yapılmamışsa yine hiçbir statik files’ı yine görmez. Aşağıdaki kod satırlarını ana urls.py dosyasına ekleme yapmanız gerekir. (sadece development için)
 

  • django.contrib.staticfiles‘  INSTALLED_APPS kısmına ekli ve debug false olarak ayarlanmışsa; Django dev. serveri hiçbir şekilde statik dosyaları serve etmez. Bir önceki maddede yapıldığı gibi ilgili root urllerini urls.py’a eklesek de serve etmez. Çünkü Debug =False‘dir, Django statikler benim işim değil demiştir. İlk olarak collectstatic çalıştırılıp STATIC_ROOT lokasyonuna applerin içinde dağınık bulunan statik dosyalar kopyalanır. Bu dosyalar Nginx ya da Apache üzerinden serve edilir. Bu nedenle STATIC_ROOT ve MEDIA_ROOT klasörü ilgili webserver configin location kısmına eklenmiş olmalıdır.
  • Medya dosyalarını (yani upload edilmişler) applerin altında değil daha çok projenin ana dizininde bulunduklarından dolayı INSTALLED_APPS kısmında ‘django.contrib.staticfiles’ ekli olması ve debug true olması durumunda bile Django dev serveri bu medya dosyalarını sunmaz. Bu dosyalara erişebilmek için statik dosyalarda yaptığımız gibi (django.contrib.staticfiles ekli olmadığı senaryodaana urls.py’a “static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)” eklenmesi gerekir. (2 madde önce paylaşılan kod bloğunu eklediyseniz gerek yoktur). Fakat Debug=False durumunda yine hiçbir şekilde medya dosyaları Django tarafından sunulmaz. Kısaca Debug=False ise hiçbir şekilde serve etmez, Debug=True ise ve urls.py’da yeri belirtilmişse serve eder. INSTALLED_APPS’de ‘django.contrib.staticfiles’ satırının olup olmaması medya dosyalarını etkilemez. Çünkü Django medya dosyalarını statik dosya olarak görmez.

Bu bilgiler ışığında statik ve medya dosyalarının sunulma mantığını anlamışsanız, çalışma ortamı değiştirdiğinizde 404 hatalarının önüne geçmiş olacaksınız. Yine anlamadığınız yer olduysa yorum kısmına yazabilirsiniz.