31 Ağustos 2015 Pazartesi

Django Translation

Merhaba, Djangoda translation işlemine bakacağız. Bunun için django ile birlikte gelen translation kütüphanesinin nasıl kullanıldığından bahsedeceğiz. Hemen işe koyulalım. İlk önce settings.py dosyası içerisinde ayarlamalar yapacağız. İlk önce MIDDLEWARE_CLASSES değişkenini düzenleyeceğiz.
MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
)
Daha sonra yine settings.py dosyası içerisinde hangi dilleri kullanacağımızın listesini ve dil dosyalarının ana dizinini belirteceğiz.
from django.utils.translation import ugettext_lazy as _

LOCALE_PATHS = (os.path.join(BASE_DIR, "locale"),)

LANGUAGES = (
    ('tr', _('Turkish')),
    ('en', _('English')),
)
İki dil tanımlaması yaptık. Dikkatinizi çekmiştir, ugettext_lazy adında bir fonksiyon kullandık. İleride bu fonskiyonu açıklayacağız. Settings dosyasındaki ayarlarımız bu kadar. Şimdi isterseniz django aracılığı ile dil dosyalarımızı oluşturalım. Projemizin ana dizinine locale adında bir dizin oluşturuyoruz ve şu komutları çalıştırıyoruz.
django-admin.py makemessages -l tr
django-admin.py makemessages -l en
locale dizini altında django.po adındaki dosyalarımızın oluştuğunu göreceksiniz. Django bizim için bulduğu stringleri bile ekledi. Dosyanın en başında
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-09-01 02:57+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
Gibi bir ifade göreceksiniz. Bu dosyanın ayarlarını içermektedir. Kendinize göre düzenleyebilirsiniz. Ardından burada bilmemiz gereken;
msgid "Mesaj ID'si"
msgstr "Mesaj içeriği"
şeklinde bir yapı olduğudur. msgid ile gösterdiğimiz kısmı metnimizi çağırırken kullanacağız. Bu kısım her dil dosyasında aynı olmalıdır. msgstr kısmı ise dillere göre değişkenlik gösterecek kısımdır. Burada msgid kısmını yazarken de cümle kuruyormuş gibi yazabilirsiniz. Değişken tanımlar gibi hissetmenize gerek yoktur kendinizi. en ve tr dillerini tanımladığımız için locale dizini içerisinde en ve tr adında iki farklı dizin oluştu. Bu dizinler içerisinde ise django.po dosyası bulunmakta. Şimdi bir kaç tanımlama yapalım.
#tr dizini içerisindeki django.po
msgid "Test metni"
msgstr "Test metni"

#en dizini içerisindeki django.po
msgid "Test metni"
msgstr "Test text"
Dosyalarımı oluşturdaktan sonra sıra geldi compile işlemine bunun için projemizin ana dizininde şu komutu çalıştırıyoruz.
django-admin.py compilemessages
Bu komuttan sonra dil dosyalarımız compile edilecek ve aynı dizinler içerisinde django.mo dosyaları oluşacaktır. Dil dosyalarını oluşturma ve compile etme işlemi bu kadar. Şimdi bunları nasıl kullancağımıza bakalım. Örneğin views içerisinde bir değişkeninizin değerinin dil seçimine göre değişmesini istiyorsak, şu şekilde kullanabiliriz.
from django.utils.translation import ugettext as _
from django.http import HttpResponse

def my_view(request):
    output = _("Test metni")
    return HttpResponse(output)
Buradaki output değişkenine gelen değer dil seçimine göre Test metni veya Test text olacaktır. Birazdan dil seçiminin nasıl yapılacağını göstereceğiz. Şimdi aynı işlemi formlar için uygulayalım.
from django.utils.translation import ugettext_lazy as _
class RegistrationForm(UserCreationForm):
    username = CharField(label=_("Test metni"))
Gördüğünüz gibi kullanımı oldukça basit. Burada ugettext_lazy kullandığımıza dikkat edin.
from django.db import models
from django.utils.translation import ugettext_lazy as _

class MyThing(models.Model):
    name = models.CharField(help_text=_('This is the help text'))
Model dosyası içerisinde de bu şekilde kullanabilirsiniz. Metin alanı olarak kullanacağınız tüm alanlarda bu şekilde translate işlemi yapabilirsiniz. Modeller içerisindeki verbose_name, help_text formlar içerisindeki label, error_messages gibi. Template(şablon) içerisindeki kullanımını görelim.
{% load i18n %}
{% trans "This is the title." %}
{% trans myvar %}
Gördüğünüz gibi kullanımı gerçekten basit. Bu şekilde django bizim için değerleri dil dosyaları içerisinden çekecektir. Template içerisinde aktif olan file şu şekilde erişebilirsiniz.
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
Veya view içerisinde şu şekilde erişebilirsiniz.
from django.utils import translation
def cur_lang(language):
    cur_language = translation.get_language()
    ....
Ve son olarak bir dili aktif etmeyi görelim. Yukarıda metinlerimizi hep translate edicek şekilde çağırdık. Hangi dil aktif ise o dile göre metinler getirilicektir.
def language(request, lang_code):
    translation.activate(lang_code)
    request.session[translation.LANGUAGE_SESSION_KEY] = lang_code
    return HttpResponseRedirect('/')
Çok basit hali dil seçimi yapan bir view yazdık. Kullanıcıdan alınan lang_code değerini aktif ediyor ve ardından session ataması yaparak kalıcı hale getiriyoruz. Django'da translation işlemi en basit haliyle bu şekilde. Daha fazla bilgiye bu sayfadan erişebilirsiniz.
Kaynakça

6 Ağustos 2015 Perşembe

Django ile Database Taşıma

Projenizi sqlite database kullanarak hayata geçirdiniz ve bir süre sonra size sqlite yetmez oldu. Database'inizi mysql veya postgresql gibi databaselere taşımak istiyorsunuz. Bu işlemi yapmak django ile oldukça kolay. Zaten ORM yapısını kullandığınız için kodlarınızda herhangi bir değişiklik olmaz. Sadece settings.py dosyası içerisinde database konfigürasyonlarınızı değiştirmelisiniz. Bu yazının konusu sadece database içerisindeki dataları taşımak olduğu için bu konfigürasyon konularına değinmeyeceğiz. Yapmamız gereken ilk önce varolan projemizde aşağıdaki komutu çalıştırmaktır.
$ python manage.py dumpdata > dump.json
Bu komut ile database'in json formatında dumpını almış olduk. Ardından konfigürasyonumuzu değiştirdikten sonra artık database değişmiş oldu ve eski datalarımızı kaybettik. Örneğin sqlite database kullanırken mysql'e geçmek istedik. Konfigürasyonu mysql olarak ayarladıktan sonra aşağıdaki komutları sırası ile çalıştırıyoruz.
$ python manage.py migrate
$ python manage.py loaddata dump.json
İşte Django aracılığı ile database değişikliği yapmak bu kadar kolay.

10 Haziran 2015 Çarşamba

Celery, Python'da dağıtık iş kuyruğu oluşturmanızı sağlayan oldukça kullanışlı bir kütüphane. Bu yazımızda bu kütüphanenin basit bir şekilde django üzerinde nasıl kullanıldığından bahsedeceğiz. Ve tahmin ediyorum ki bu kütüphaneyi daha önce duymamış olan arkadaşar yazıdan sonra kullanmaya başlayacaktır. Size şöyle bir örnek ile açıklayalım. Örneğin sisteme kullanıcı kaydı alıyorsunuz ve kayıt alırken de her kullanıcı kayıt olduğunda sistem bana mail olarak bunu bildirsin dediniz. İşte bu noktada eğer kodunuz şu tarz ise;
kullanıcı verilerini al
doğruluğunu kontrol et
kaydet
mail at
sonuç dön
Bildiğiniz gibi mail atma işlemi biraz zaman alan bir işlem olduğu için bu yapıda kullanıcıyı sistemin mail atması için gereksiz yere bekletmiş olacaksınız ve kullanılabilirlik düşmüş olacaktır. İşte Celery tam bu noktada devreye gire bir kütüphane. Burada mail için bir kuyruk oluşturuyorsunuz ve mail atma işlemi ile artık Celery ilgileniyor. Siz kullanıcıya sonucu direk dönerken Celery arka tarafta mail atma işlemini tamamlıyor. Hemen django ile kullanımına geçelim.
Broker
İş kuyruğu olarak broker seçmemi gerekiyor. Yani bizim iş kuyruğu oluşturmamızı sağlayan asıl yapı olacak. Bunun için RabbitMQ veya Redis seçilebilir. Biz RabbitMQ kullanacağız. Kurulumu :
 sudo apt-get install rabbitmq-server
Eğer ubuntu kullanıyorsanız komut ile kurabilirsiniz. Kurulduktan sonra kendisi servis olarak ayağa kalkacaktır. Kurulum için ayrıntılı bilgiyi buradan ulaşabilirsiniz. Şimdi Celery kütüphanesini kuralım.
 
pip install celery
proje adında bir projemiz olduğunu düşünürsek görünümü şu şekilde olacaktır.
proje
├── manage.py
└── proje
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py
İlk önce yapmamız gereken projemizin ayar dizinine celery.py dosyası oluşturmak ve içerisine şu komutları yazmak.
proje/proje/celery.py
from __future__ import absolute_import

import os

from celery import Celery

#celery için django default settings dosyasını gösteriyoruz
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proje.settings')

from django.conf import settings

#celery app oluşturuyoruz
app = Celery('proje')

app.config_from_object('django.conf:settings')
#bu fonksiyon sayesinde projemizde her uygulama içerisindeki tasks.py içeriği celery tarafından yorumlanacaktır.
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)


@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))
Şimdi aynı dizindeki __init__.py dosyasını düzenlememiz gerekiyor.
proje/proje/__init__.py
from __future__ import absolute_import

from .celery import app as celery_app
Artık task oluşturabiliriz. Bunun için ilk önce bir uygulama oluşturalım. ve içerisine tasks.py adında tasklarımızı yazacağımız bir dosya oluşturalım.
#python2.7 manage.py startapp uygulama
#tree proje
../proje
├── manage.py
├── proje
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── settings.py
│   ├── settings.pyc
│   ├── urls.py
│   └── wsgi.py
└── uygulama
    ├── __init__.py
    ├── admin.py
    ├── migrations
    │   └── __init__.py
    ├── models.py
    ├── tasks.py
    ├── tests.py
    └── views.py
Şimdi tasks.py dosyasının içeriğini dolduralım.
from __future__ import absolute_import

from celery import shared_task


@shared_task
def mail_gonder():
    mail() # mail gonder fonksiyonu oldugu kabul edilmiştir.
Celery ile fonksiyon oluşturmak bu kadar basit. Bu fonksiyonu views.py dosyası içerisinde şu şekilde kullanabiliriz.
from uygulama.tasks import mail_gonder
def index(request)
    ....
    mail_gonder.delay()
    ....
Kullanımı da oldukça basittir. Burada fonksiyonu doğrudan adıyla değilde delay(/) fonskiyonu ile çağırdığımıza dikkat edin. Eğer doğrudan adı ile çağırırsanız, normal bir fonksiyondan bir farkı olmaz ve işlenmesi beklenir. Burada artık bu satır işlendiği anda fonksiyon iş kuyruğuna atılacak ve hiç bekleme yapmadan kod satırları işlenmeye devam edilecektir. Rabbitmq serverımız kurduk ve çalışır bir vaziyetteyse celeryi ayağa kaldırabiliriz demektir. Eğer RabbitMQ ayakta değilse ilk önce onu ayağa kaldırmalısınız.
service rabbitmq-server start
Daha sonra proje ana dizinine giderek Celery'i ayağa kaldırmalıyız.
celery -A proje worker -l info
Bu komutu verdikten sonra Celery ayağa kalkacak ve herşey kullanıma hazır demektir. Zaten komut çıktısını incelerseniz yazmış olduğunuz taskların kullanıma hazır olduğu çıktısını görebilirsiniz. index fonksiyonu çağrıldığı anda da komut satırında taskların düzgün bir şekilde düştüğünü izleyebilirsiniz. Tabi gördüğünüz gibi Celery'i komut satırında çalıştırdık. Bu durumun böyle olmaması ve her zaman çalışabilmesi için Supervisor'ı kullanacağız.
Supervisor
sudo pip install supervisor
Supervisor config dosyasını şu şekilde oluşturalım.
/etc/supervisor/config.d/proje.conf
[program:proje-celery]
command=celery --app=proje.celery:app worker --loglevel=INFO
directory=proje_path/proje
user=user_name
numprocs=1
stdout_logfile=/log_path/logs/celery-worker.log
stderr_logfile=/log_path/logs/celery-worker.log
autostart=true
autorestart=true
startsecs=10


stopwaitsecs = 600


killasgroup=true


priority=998
Supervisor işleme alması için şu komutları çalıştıralım.
# supervisorctl reread
# supervisorctl reload 
Artık her şey kullanıma hazır. Mail atmak istediğimiz zaman mail işlemi celery tarafından kuyruğu alınacaktır ve kuyrukta işlenecektir.
Kaynakça

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.

23 Ocak 2015 Cuma

Django Admin Panel Resim Thumbnail

Django'da model içerisinde imagefield kullandığınız zaman admin panelinde form içerisinde bu resmi göremiyoruz. Sadece resmin adı görünmektedir. Bu yazıda bu resmi küçük bir şekilde nasıl görebiliriz ondan bahsedeceğiz. İlk önce model oluşturalım.
#models.py
from django.db import models

class Image(models.Model):
    name = models.CharField(max_length=255)
    image = models.ImageField(upload_to="image")

İlk önce listeleme sayfasında resimleri gösterelim. Bildiğiniz gibi admin sayfasında elemanları listelerken list_display özelliği ile istediğimiz alanları ve istediğimiz herhangi bir fonksiyondan dönen değeri yazdırabiliyoruz. Şimdi model içerisinde bir fonksiyon oluşrulım ve bu fonksiyon bize resmi döndürsün.
class Image(models.Model):
    name = models.CharField(max_length=255)
    image = models.ImageField(upload_to="image")

    def image_thumb(self):
        return '<img src="%s" height="200" width="300"/>' % (self.image.url)
    image_thumb.short_description = 'Resim'
    image_thumb.allow_tags = True
Daha sonra admin.py içerisine şu kodları yazıyoruz.
from django.contrib import admin

class ImageAdmin(admin.ModelAdmin):
    list_display = ['name', 'image_thumb']

admin.site.register(Image, ImageAdmin)
Artık model satıları listelenirken resimleri görebiliyoruz.
Bu işlemden sonra resmin içeriğini görmek için tıklarsanır şöyle bir çıktı alacaksınız.
Gördüğünüz gibi resim görünmemekte sadece resmin yolu görünmektedir. Şimdi burada da resmi gösterelim. Yapmamız gereken admin.py dosyasına şu kodları eklemek.
from django.contrib.admin.widgets import AdminFileWidget
from django.utils.safestring import mark_safe


class ImageWidget(AdminFileWidget):
    def render(self, name, value, attrs=None):
        output = []
        if value and hasattr(value, "url"):
            output.append(('<a target="_blank" href="%s">'
                           '<img src="%s" height="100" title="%s"/></a> '
                           % (value.url, value.url, value.name)))
        output.append(super(AdminFileWidget, self).render(name, value, attrs))
        return mark_safe(u''.join(output))
Burada özel bir widget ekliyoruz. Bu widget aldığı alan için bir geri değer döndürecek. Son olarak yapmamız gereken ise image alanımıza bu widgetı tanımlamak bunun için yine admin.py dosyasında az önce yazdığımız ImageAdmin sınıfını değiştirmek.
class ImageAdmin(admin.ModelAdmin):
    list_display = ['name', 'image_thumb']
    def formfield_for_dbfield(self, db_field, **kwargs):
        if db_field.name == 'image':
            request = kwargs.pop("request", None)
            kwargs['widget'] = ImageWidget
            return db_field.formfield(**kwargs)
        return super(ImageAdmin, self).formfield_for_dbfield(db_field, **kwargs)


admin.site.register(Image, ImageAdmin)
Artık resmi düzenleme sayfasında da görebiliyoruz.
Siz burada kendinize göre biraz daha özelleştirebilirsiniz.

15 Ocak 2015 Perşembe

Bu yazıda basit bir şekilde google'ın captcha uygulamalarını sitemize nasıl import edebileceğimizden bahsedeceğiz.
reCAPTCHA
İlk önce https://www.google.com/recaptcha/intro/index.html adresinden kendimiz için bir recaptcha oluşturuyoruz. Buradaki Get reCAPTCHA butonuna tıkladığınızda size Site key ve Secret key oluşturacaktır. Bunları projemizde kullanacağız.
Bu işlemi yaptıktan sonra https://github.com/praekelt/django-recaptcha adresinden uygulamayı indiriyoruz. İndirdikten sonra
cd Downloads/django-recaptcha-develop/
sudo python setup.py install
komutlarını sırası ile çalıştırıyoruz. Kurduktan sonra settings.py dosyasında INSTALLED_APPS değişkenine uygulamayı eklemeliyiz.
INSTALLED_APPS = (
.....
    'captcha',
)
Daha sonra şu satırları settings.py dosyasına ekliyoruz.
RECAPTCHA_PUBLIC_KEY = 'Googledan aldığınız Site Key'
RECAPTCHA_PRIVATE_KEY = 'Googledan aldığınız Secret Key'
RECAPTCHA_USE_SSL = True
Son satır reCAPTCHA'nın SSL kullanması ile ilgili. Eğer isterseniz bu satırı kaldırabilirsiniz. reCAPTCHA'yı kullanmak için artık her şey hazır. Şimdi basitçe kullanalım. İlk basit bir form oluşturuyoruz.
from django import forms
from captcha.fields import ReCaptchaField

class reCAPTCHAForm(forms.Form):
    captcha = ReCaptchaField()
Şimdi bu formu kullanalım. Basit bir view oluşturalım.
from django.shortcuts import render
from go.forms import reCAPTCHAForm
# Create your views here.
def go(request):
 if request.method == "POST":
     form = reCAPTCHAForm(request.POST)
     if form.is_valid():
  """ Form başarılı ise yapılacaklar """
 else:
     form = reCAPTCHAForm() 
 return render(request, 'index.html', locals())
Bu viewa ait olan index.html şablonun içeriği ise şu şekilde;
 
{% csrf_token %} {{ form }}
Artık kullanabilirsiniz. Ekran çıktımız şu şekilde olacaktır.


noCAPTCHA
noCAPTCHA'nın reCAPTCHA'dan neredeyse hiç bir farkı yok. Hemen ufak tefek değişikliklerden bahsedelim. Github sayfasını sizinle paylaşalım. https://github.com/ImaginaryLandscape/django-nocaptcha-recaptcha Bu sayfada kullanımı oldukça basit bir şekilde anlatılmış.
İlk önce kurulum yapıyoruz.
pip install django-nocaptcha-recaptcha
Daha sonra aynı şekilde INSTALLED_APPS'e ekliyoruz.
INSTALLED_APPS = (
....
    'nocaptcha_recaptcha',
)
settings.py dosyasına ayarlamaları ekliyoruz.
NORECAPTCHA_SITE_KEY = 'Googledan aldığınız Site Key'
NORECAPTCHA_SECRET_KEY = 'Googledan aldığınız Secret Key'
Form dosyasını şu şekilde değiştiriyoruz.
from django import forms
from nocaptcha_recaptcha.fields import NoReCaptchaField

class reCAPTCHAForm(forms.Form):
    captcha = NoReCaptchaField()
View dosyamız
from django.shortcuts import render
from go.forms import reCAPTCHAForm
# Create your views here.
def go(request):
 if request.method == "POST":
     form = reCAPTCHAForm(request.POST)
     if form.is_valid():
                """ Doğru ise yapılacaklar """
 else:
     form = reCAPTCHAForm() 
 return render(request, 'index.html', locals())
index.html şablon dosyamız


 
{% csrf_token %} {{ form }}
Burada dikkat etmeniz gereken ekstrandan Google'ın javascript dosyasını çağırıyor olmamız.

9 Ocak 2015 Cuma

Django ile uygulama yaparken bazen model dosyalarınızda çoklu dil desteği oluşturmak isteyebilirsiniz. 3.parti uygulama olarak hvad bunun için müthiş bir kolaylık sağlıyor. Uygulamanın github sayfasına buradan veya kendi dökümantasyonuna buradan ulaşabilirsiniz.
Biz bu yazıda basit bir örnek yaparak model dosyamızı nasıl çoklu dil desteği verebiliriz ve bunu web sitesinde seçim olarak nasıl gösterebiliriz buna bakacağız. İlk olarak basit bir şekilde uygulamayı kuralım.
pip install django-hvad
Ardında uygulamayı projemize dahil edelim.
INSTALLED_APPS = (
    ....
    'hvad',
)
Şimdi uygulamayı kullanabiliriz. İlk önce yapmamız gereken model oluşturmak. Model oluştururken bildiğiniz gibi djangonun kendi model sınıflarından kalıtım alıyoruz. Burada ise yapmamız gereken hvad uygulamasının sınıflarından kalıtım almak. Basit bir model oluşturalım.
from hvad.models import TranslatableModel, TranslatedFields,
class Images(TranslatableModel):
    image = models.ImageField()
    category = models.ForeignKey(Category)

    translations = TranslatedFields(
        title=models.CharField(max_length=200),
        description=models.TextField(),
    )

Burada gördüğünüz gibi bir model oluşturduk. Burada image alanı sabit olduğu için translation içerisine almadık sonuç olarak resim her zaman aynı. Ama title ve description alanları her dil için farklı olarak girilmesi gerektiğinden dolayı TraslatedField alanı içerisin aldık. Şimdi bu model oluşturduğumuza göre admin.py dosyası içerisinde ayarlamalarını yapmalıyız. admin.py dosyası şu şekilde olmalı.
from *.models import Images
from hvad.admin import TranslatableAdmin

class ImagesAdmin(TranslatableAdmin):
    def __init__(self, *args, **kwargs):
        super(ImagesAdmin, self).__init__(*args, **kwargs)
Bunları yaptıktan sonra admin sayfasından ekleme yapmaya çalışırsanız şu şekilde bir pencere ile karşılacaksınız.
Gördüğünüz gibi hemen hemen her dil için ekleme yapabiliyoruz. Burada TranslatedField alanı içerisine almadıklarımızı bir kere girmemiz yeterli aldıklarımızı için her dil için farklı olarak girmeliyiz. Burada bazı dilleri istemeyebilirsiniz. Bunun için istediğiniz dilleri şu şekilde settings.py dosyasına ekleyebilirsiniz.
LANGUAGES = (
    ('tr', 'Turkish'),
    ('en', 'English'),
)
Artık sadece Türkçe ve İngilizce sekmelerini göreceksiniz. Bu şekilde iki dile indirmiş olduk. Peki ekleme yaptıktan sonra bunları view dosyaları içerisinde dillere göre nasıl alacağız. Buda oldukça basit.
images = Images.objects.language('en').all()
Bu şekilde sadece ingilizce yazılan kısımlar gelecektir. Eğer siz bir kayıt eklerken sadece türkçe kısmını girer ve ingilizce kısmını boş bırakırsanız bu sorguda o kayıt gelmeyecektir. Burada language kısmı içerisini session değerinden çekerek kullanıcının seçtiği dile göre veritabanından sorgulama yapabilirsiniz. Bu yazıda çok basit bir şekilde hvad uygulamasının kullanımından bahsettik. Gerçekten de insanın işini çok kolaylaştıran bir uygulama. Daha fazla bilgiye kendi dökümantasyonundan oulaşabilirsiniz.
Kaynakça