27 Mart 2015 Cuma

Django FlatPages Kullanımı

flatpages Django'nun kendisi ile birlikte gelen dinamik sayfalar oluşturulmasını sağlayan bir uygulamadır. Bu yazımızda nasıl kullanıldığından bahsedeceğiz. Bunun için ilk önce uygulamayı projemize dahil etmemiz gerekiyor.
INSTALLED_APPS = (
    ....
    'django.contrib.sites',
    'django.contrib.flatpages',
)
Burada dikkat etmeniz gereken flatpages uygulaması sites uygulamasını kullandığı için sites uygulamasının da projeye dahil edilmiş olması gerekmektedir. Dikkat edilmesi gereken bir diğer nokta ise sites uygulaması için şu satırı settings.py dosyasını eklememiz gerektiğidir.
SITE_ID = 1
Bu işlemden sonra MIDDLEWARE_CLASSES'a şu satırı ekliyoruz.
MIDDLEWARE_CLASSES = (
     ....
    'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',
)
Url yapılandırmamızı yapalım.
urlpatterns = patterns('',
    url(r'^admin/', include(admin.site.urls)),
    url(r'^pages/', include('django.contrib.flatpages.urls')),
)
flatpages uygulamasının url dosyasını içe aktarmış olduk. Bundan sonra yapmamız veritabanı oluşturarak admin panelinden bir sayfa oluşturmak.
python manage.py syncdb
Artık dinamik bir sayfa oluşturmaya hazırız. Admin panelini açtığınız zaman Flat pages alanını göreceksiniz. Tıklayarak yeni birtane oluşturalım. Oluşturduğumuz url'e /pages/lorem-ipsum/ diye gitmeye çalışırsak flatepages/default.html bulunmadı gibi bir hata alırız. Bunun için templates dizini altında flatepages/default.html oluşturuyoruz. Ve içerisine şunları yazıyoruz.
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>{{ flatpage.title }}</title>
</head>
<body>
{{ flatpage.content }}
</body>
</html>
Şimdi tekrardan http://localhost:8000/pages/lorem-ipsum/ adresine gitmeye çalışırsanız sayfanın açıldığını göreceksiniz. Sayfayı oluştururken template name alanını boş bıraktığımız flatepages/default.html şablonunu aramaktadır.
Bir başka kullanım yöntemi ise şu şekildedir. Url tanımlamasını şu şekilde yapabilmekteyiz.
urlpatterns = patterns('',
    ...
    url(r'/lorem-ipsum/$', 'django.contrib.flatpages.views.flatpage', kwargs={'url': '/lorem-ipsum/'}, name='lorem_ipsum'),
)
Daha önceki url tanımlamasını silerseniz. Bu url tanımlamasından sonra http://localhost:8000/lorem-ipsum/ adresi ile tarayıcıdan yine ulaşabilirsiniz. Admin panelinden Flat Plage girerken Advanced Options kısmındaki Template Name alanına eğer herhangi bir isim girerseniz artık bu sayfa girdiğiniz şablona yönlendirilecektir.
Url tanımlasını şu şekilde de yapabiliriz.
urlpatterns += patterns('django.contrib.flatpages.views',
    (r'^pages/(?P<url>.*/)$', 'flatpage'),
)
Aşağıdaki html çıktısı ile, flatpages sayfalarını listeleyebilirsiniz.
{% load flatpages %}
{% get_flatpages as flatpages %}
<ul>
    {% for page in flatpages %}
        <li><a href="{{ page.url }}">{{ page.title }}</a></li>
    {% endfor %}
</ul>
Kaynakça

16 Mart 2015 Pazartesi

Pdb ile Python Debugging

Pdb, Python scriptleri üzerinde debug işlemi yapabilmenize olanak sağlayan bir kütüphanedir. Bu yazıda çok basit bir şekilde kullanımından bahsedeceğiz.
Yazdığımız bir python scriptini debug etmek için komut satırından şu şekilde çalıştırabiliriz.
python -m pdb t.py 
Bu şekilde çalıştırıldığında script debug işlemi kodların en başından başlayacaktır.
Gördüğünüz gibi scripti çalıştırdığımızda bizi doğrudan pdb kabuğuna düşürdü. Burada artık debug işlemimize başlayabiliriz. Tabi bu işlem ile gördüğünüz gibi ilk satırdan itibaren debug işlemine başlamış olduk. Bu şekil de kullanmak yerine herhangi bir satırda bu işlemin başlamısını isteyebiliriz. Bunun için ise script içerisinde herhangi bir satıra şu kodu yazabiliriz.
import pdb; pdb.set_trace()
Bu kodu yazdığımız satıra kadar programımız yorumlanacak ve bu satırdan sonra bizi Pdb kabuğuna düşürecektir. Şimdi yazdığımız basit kodu şu hale getiriyoruz ve ardından komut satırından normal bir şekilde - pdb kullanmadan - çalıştırıyoruz.
def deneme(a):
 print "Bu bir fonksiyon"

print "Pdb'den once"
import pdb; pdb.set_trace()
print "Fonksiyon cagirilmadan once"
deneme(5)
print "Fonskiyon cagirildiktan sonra"
Gördüğünüz gibi program pdb satırına gelene kadar normal bir şekilde yorumlandı ve o satıra geldikten sonra bizi pdb kabuğuna düşürdü. Debug işlemi için yapmamız gereken bu kadar. Şimdi Pdb kabuğuna düştükten sonra neler yapabileceğimize bakalım. Daha önceden dikkatinizi çeti ise l ifadesini kullandım.
  • l(ist) : Yazdığımız kodu listelememizi sağlar.
  • w(here) : Programın olduğu satırı yazar.
  • c(ontinue : Programın kaldığı yerden yorumlanmaya devam etmesini sağlar.
  • b(reak) SatirNumarasi : Satır Numarasına Break Point koyar.
  • tbreak SatirNumarasi : Geçici olarak break point koyar. Birinci işlemden sonra break point silinir.
  • q(uit) : Debug işleminden çıkar.
  • c(lear) : Break pointleri temizlemek için kullanılır. Sorulan soruya y(es) cevabı verilirse break pointler silinir.
  • commands BreakPointNumarasi Girilen Break Point numarasına gidilirken istenilen komutlarında çalışmasını sağlar. Kullanılışı şu şekildedir. Command'ten çıkmak için end ifadesi kullanılır.
  • s(tep) : Bir sonraki satıra geçer.
  • n(ext) : Bir sonraki satıra geçer.
  • İkisi arasındaki fark; Step ile bir fonksiyona girildiği zaman adım adım işlerken n(ext) fonksiyonu işler ve çıkar.
  • j(ump) SatirNumarasi : Yazılan satır numarasına atlar.
  • a(rgs) : Varsayılan fonksiyonun argümanlarını verir.
  • p a : a değişkenin değerini ekrana yazdırır.
  • run : Debug edilen programı yeniden başlatır.

9 Mart 2015 Pazartesi

Merhabalar bu yazıda bir Virtualenv oluşturmayı, ardından oluşturduğumuz Virtualenv içerisinde bir django projesi oluşturmayı, oluşturmuş olduğumuz bu projemizi nasıl Gunicorn üzerinde koşturacağımızı. Koşturduğumuz bu projemizi Nginx ile nasıl konuşturacağımızı ve en son olarak Gunicorn'u yönetim işlemini nasıl Supervisor'a devredeceğimizden bahsedeceğiz.
Yazımıza geçmeden önce şu komutları sırası ile çalıştırarak sistemimiz güncelleyelim.
sudo apt-get update
sudo apt-get upgrade
Python Virtualenv
Pyton Virtualenv bize özel bir python çalışma alanı yaratır. Ve yüklediğimiz kütüphaneler sadece bu alana yüklenerek sistemin genelini etkilemez. Yaptığımız kurulumların sadece burada geçerli olmasını sağlıyoruz. Bunun ne gibi avantajları var derseniz. En basitinden tek bir sistem altında farklı Django sürümleri ile 1.6 ve 1.7 gibi geliştirilmiş projeleri rahat bir şekilde yayınlayabilirsiniz. İlk önce şu komutu vererek Virtualenv'yi sistemimize kuruyoruz.
sudo apt-get install python-virtualenv
Kurulum ardından kendimize özel bir Virtualenv oluşturalım.
virtualenv django-virt
Oluşturma işleminin ardından dizin içerisini inceleyebilirsiniz. Oluşturduğumuz dizin içerisine girelim ve aktif edelim.
cd django-virt/
source bin/activate
Bu işlemden sonra komut satırının başının değiştiğini göreceksiniz. Artık kuracağımız kütüphaneler bu virtualenv içerisine kurulacaktır.
(django-virt)massumo@ubuntu:~/django/django-virt$
Django Kurulumu
(django-virt)massumo@ubuntu:~/django/django-virt$ pip install django
komutunu çalıştırarak djangoyu oluşturmuş olduğumuz sanal çalışma alanımıza kuruyoruz.
Nginx Kurulumu
Sistemimize Nginx'i kuralım. Bunun için ilk önce aşağıdaki komutu çalıştırarak virtualenv içerisinden çıkalım. Ardından Nginx kurulumu için gerekli olan komutu verelim.
(django-virt)massumo@ubuntu:~/django/django-virt$ deactivate
sudo apt-get install nginx
Gunicorn Kurulumu
Gunicorn çok güçlü bir Python WSGI HTTP Server'dır. Şimdi tekrar virtualenv içerisine girerek Gunicorn'u kuracağız.
$ source bin/activate
(django-virt)massumo@ubuntu:~/django/django-virt$ pip install gunicorn
Django Projesi Oluşturmak
Gunicornu başarılı bir şekilde kurduktan sonra django projesi oluşturabiliriz.
(django-virt)massumo@ubuntu:~/django/django-virt$ django-admin.py startproject django_project
(django-virt)massumo@ubuntu:~/django/django-virt$ cd django_project
(django-virt)massumo@ubuntu:~/django/django-virt/django_project$ python manage.py runserver
Not : Burada komut satırlarının tamamını yazmamın sebebi sizin o an bulunduğumuz dizini ve çalışma alanınızı takip edebilmenizi kolaylaştırmaktır.
Projemiz başarılı bir şekilde ayağa kalktı. Şimdi projeyi Gunicorn ile ayağa kaldıralım.
(django-virt)massumo@ubuntu:~/django/django-virt/django_project$ gunicorn_django --workers=3 --bind localhost:8000
Eğer oluşturduğunuz django projesi 1.7 ve üzeri ise bu komutu çalıştırdığınız da şu şekilde bir hata alacaksınız.
...
    from django.core.management.validation import get_validation_errors
ImportError: No module named validation
Bu hatanın sebebi Django 1.7ile itibaren bazı sınıfların kaldırılması veya yerlerinin değiştirilmesi. Burada da aynı sorun söz konusu. Bu hatanın ortadan kalkması için yapmanız gereken virtualenv içerisine kurmuş olduğumuz gunicorn içerisindeki django_wsgi.py dosyasını düzenlemek. Bu dosyayı şuradan açın
/django-virt/lib/python2.7/site-packages/gunicorn/app/
Bu dizin altındaki django_wsgi.py dosyasını açın ve eski halinden yeni haline getirin.
##Eski hali 
...
##Bu satiri silin
from django.core.management.validation import get_validation_errors
...
def make_wsgi_application():
    # validate models
    s = StringIO()
    if get_validation_errors(s):
        s.seek(0)
        error = s.read()
        msg = "One or more models did not validate:\n%s" % error
        print(msg, file=sys.stderr)
        sys.stderr.flush()
        sys.exit(1)

    translation.activate(settings.LANGUAGE_CODE)
    if django14:
        return get_internal_wsgi_application()
    return WSGIHandler()
...

##Yeni Hali
...
def make_wsgi_application():
    # validate models
    s = StringIO()
    import django
    from django.core.management.base import BaseCommand
    django.setup()
    cmd = BaseCommand()
    import sys
    cmd.stdout, cmd.stderr = sys.stdout, sys.stderr
    cmd.check()
    translation.activate(settings.LANGUAGE_CODE)
    if django14:
        return get_internal_wsgi_application()
    return WSGIHandler()
...
Bu düzeltme işlemini yaptıktan sonra aynı komutu tekrar çalıştırıyoruz.
(django-virt)massumo@ubuntu:~/django/django-virt/django_project$ gunicorn_django --workers=3 --bind localhost:8000
Şimdi hatasız bir şekilde çalıştı. Tarayıcıdan localhost:8000 yazarak çalıştığını görebilirsiniz. Buradaki workers değerini değiştirebilirsiniz. Şimdi gunicorn için bir config dosyası için bir dosya oluşturalım. Ardından ayarlarımızı bu dosya içerisine yazarak bu dosya üzerinden projemizi koşturalım. Virtualenv'nin ana dizinine gunicorn_config.py adında bir dosya oluşturuyoruz ve içerisine şu satırları ekliyoruz.
command = '/home/massumo/django/django-virt/bin/gunicorn'
pythonpath = '/home/massumo/django/django-virt/django_project'
bind = '127.0.0.1:8000'
workers = 3
Bunun ardından bu dosya üzerinden projemizi şu şekilde çalıştırıyoruz.
(django-virt)massumo@ubuntu:~/django/django-virt$ gunicorn -c gunicorn_config.py django_project.wsgi
Projemiz sıkıntısız bir şekilde çalıştı.
Nginx Ayarlamaları
Nginx'i daha önce kurmuştuk. Şimdi ayarlamalarını yaparak projemizi Nginx üzerinde koşturacağız. İlk önce Nginx'i başlatalım.
#service nginx start
Daha sonra /etc/nginx/sites-available dizini içerisine girerek bir conf dosyası oluşturuyoruz.
#####Dosya adı 'myproject'
server {
        server_name localhost;
        access_log off;
 listen 80;
        location /static/ {
                alias /home/massumo/django-virt/django_project/static/;
        }

        location / {
                proxy_pass http://127.0.0.1:8000;
                proxy_set_header X-Forwarded-Host $server_name;
                proxy_set_header X-Real-IP $remote_addr;
                add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"';
        }
}
Burada dikkatinizi çekmiştir. Nginx bizim Gunicorn ile 8000 portta ayağa kaldırdığımız projeyi dinliyor. Eğer siz az önce komut satırından çalıştırdığımız projeyi CTRL+C vb bir işlem kapattıysanız. Nginx aracılığı ile projeyi koşturamazsınız. O yüzden onu kapatmadan başka bir terminal açarak bu işlemleri yapın. Yani burada nginx bir nevi tünelleme görevi görüyor. Bizim Gunicorn ile ayağa kaldırdığımız projeyi dinleyerek kullanıcıya gösteriyor. Şimdi işlemlerimize devam edelim.
Oluşturduğumuz config dosyasını /etc/nginx/sites-available dizini içerisinde oluşturduk. Oysa nginx ana config dosyası içerisinde aktarma işlemi yaparken /etc/nginx/sites-enabled dizini içerisindeki dosyaları aktarır. Bunu /etc/nginx/nginx.conf dosyasını inceleyerek görebilirsiniz. Bizde bundan dolayı oluşturduğumuz dosyayı ../sites-enabled dizini içerisine linkleyeceğiz. Bunun için siz de şu komutu çalıştırın.
massumo@ubuntu:/etc/nginx/sites-available$ sudo ln myproject ../sites-enabled/myproject
$sudo service nginx restart
Tarayıcıdan localhost yazarsanız projenin çalıştığını görebilirsiniz. Eğer bir hata oluşursa işlemlerinizi kontrol edin.
Supervisor Kurulumu ve Ayarlamaları
Buraya kadar projemizi gunicorn aracılığı ile nginx üzerinde koşturduk. Ama sizde fark etmişsinizdir ki burada bir eksik var. Projemizi terminalde gunicorn üzerinden şu komutla çalıştırmamız gerekiyor ki nginx üzerinden erişilebilsin.
/django-virt$ gunicorn -c gunicorn_config.py django_project.wsgi
Yani bizim bunun kontrolünü sürekli takip etmemiz gerekiyor. Eğer bilgisayarı kapatıp açarsak bu işlemi tekrar yapmamız gerekiyor. İşte bu kontrolleri bizim yerimize Supervisor yapacak. İlk önce kuralım. Virtaulenv içerisinden çıktıktan sonra şu komutu çaıştırın.
sudo apt-get install supervisor
Kurulumu yaptıktan sonra /etc/supervisor/conf.d dizinin açıyoruz ve config dosyası oluşturuyoruz.
##dosya adı 'django_project.conf'

[program:project]
command = /home/massumo/django/django-virt/bin/gunicorn -c /home/massumo/django/django-virt/gunicorn_config.py django_project.wsgi
Config dosyasını Supervisor'a göstermek için şu komutları sırası ile çalıştırın.
sudo supervisorctl reread
sudo supervisorctl update
İşlemlerimiz başarılı bir şekilde gerçekleşti. Artık tarayıcıdan gelerek gunicorn komutunu çalıştırmamıza gerek yok. Supervisor bu işlemi bizim için halledecek. Şuan bilgisayarınızı yeniden başlatsanız bile Nginx üzerinde koşan bir uygulama olması gerekmektedir. Tarayıcıdan http://localhost yazarak ulaşabilirsiniz.