19 Nisan 2014 Cumartesi

Kayıt Sıralama

Kullanıcıya kayıtları gösterirken, kullanıcının istediği bir alan üzerinde sıralama yapmasına izin verebiliriz. Daha önce doktorları listelediğimiz uygulamada kullanıcıya bazı alanlara göre listeleme imkanı sunalım. Bunun için doktor_listesi.html şablonundaki başlıkları şu şekilde değiştirelim.
    <tr>
        <th>Sıra</th>
        <th><a href="?siralama=1">Adi<a/></th>
        <th><a href="?siralama=2">Soyadi</a></th>
        <th>Telefon</th>
        <th>E-Posta</th>
        <th>İşlemler</th>
    </tr>
Dikkat ettiyseniz parametreleri GET metodu ile gönderiyoruz. Şimdi Doktor_listesi görünümünü sıralama olanağı verebileceğimiz şekilde değiştirelim.
def Doktor_listesi(request):
 siralama = 'adi'
 kiriter = request.GET.get('siralama')
 if kiriter:
  siralamaKriteleri = {
   '1':'adi',
   '2':'soyadi'
  }
  if kiriter in siralamaKriteleri:
   siralama = siralamaKriteleri[kiriter]

 doktorlar = Doktor.objects.order_by(siralama)
 return render_to_response('doktor_listesi.html',locals())
Burada yaptığımız işlem; eğer kullanıcı bir parametre girmiş ise girdiği parametreye göre girmediyse varsayılan olarak adi alanına göre sıralama yaptırdık. Burada kiriter değişkenini şablona gönderiyoruz. Bu değişkene göre alan adlarına farklı stiller uygulayarak belli olmasını sağlayabilirsiniz.
Tersten Sıralama
Hatırlarsanız Modeller'i işlerken tersten sıralama yapmak için alan adı başına - işareti koymamız gerektiğin söylemiştik. Verdiğimiz örnekte tersten sıralama yapmak isterseniz şu şekilde kullanabilirsiniz.
doktorlar = Doktor.objects.order_by("-"+siralama)
Kaynakça
  • Mustafa Başer Django Kitabı

18 Nisan 2014 Cuma

Merhaba PyQt

       Bir programlama dili öğrenilirken ilk yazılan kod "Merhaba Dünya" çıktısı veren kodlardır. Biz de burada ilk olarak PyQt'de bunu uygulayacağız. Ancak biraz farklılık yapıp "Merhaba Dünya" yerine "Merhaba PyQt" diyelim. Öncelikle kodu yazalım ve kodlar üzerinden anlatmaya devam edelim.

# !/usr/bin/env python
# -*- coding: cp1254 -*-

from PyQt4.QtGui import *

uygulama = QApplication([])
etiket = QLabel('Merhaba PyQt')
etiket.show()
uygulama.exec_()

Bu kodu çalıştırdığınız da şekildeki gibi bir pencere açılacaktır.

Şimdi bu program için yazdığımız kodlarda ne yaptığımıza bakalım. İlk üç satır ile gerçekleştirilen işlemlerin ne anlam ifade ettiğini bu kısma gelmeden önce biliyor olmanız gerekiyor. Bunlara değinmiyoruz.
Bir sonraki satırda bir Qt uygulaması başlattık. Qt uygulamalarının her biri QApplication nesnesinden oluşmaktadır. Parantezler arasında da nesneye gönderilecek argümanlar eklenir. Komut satırından gönderilen parametreler bu şekilde gönderilmektedir. Burada biz herhangi bir parametre kullanmadık.

5. satırda Qt'ye ait etiket isminde bir etiket oluşturduk, bu etikete parametre olarak verdiğimiz 'Merhaba PyQt' ise bu etiketin içeriğini yani içinde gösterilecek olan metni temsil etmektedir.
Etiket, buton gibi kullandığımız parçacıklara Widget denilmektedir.
Bir sonraki satırda ise oluşturduğumuz bu etiketin görünür olmasını sağladık.

Son satırda da uygulamamızın başlamasını istedik. Bu kod sonsuz bir döngüyü ifade etmektedir. Yani kod bu kısımda baştan tekrar çalışmaktadır. Bu sayede fare ve klavye gibi girdi cihazlarının sinyalleri dinlenebilmekte ve uygulamada kullanılabilmektedir.


Burada yazmış olduğumuz program kullanıcı denetimden yoksundur. Bu yüzden normal bir Grafiksel Kullanıcı Arayüzüne sahip sayılmaz. Tek yapılan iş etiket içeriğinin gösterilmesidir. Oysaki Grafiksel Kullanıcı Arayüzüne sahip bir program kullanıcısı tarafından gelecek girdilere tepki verebilir şekilde olmalıdır.


Etiketlere parametre olarak verdiğimiz metinler için boyut, renklendirme gibi özellikler için HTML kodları kullanılabilmektedir. Örneğin bu yazımızın rengini kırmızı yapalım ve boyutunu ise büyütelim. Bunun için etiketi oluşturduğumuz kodu aşağıdaki gibi düzenlememiz yeterli olacaktır.

etiket = QLabel('Merhaba PyQt')

Bu şekilde düzenledikten sonra çalıştırdığınızda ise aşağıdaki gibi bir çıktı oluşacaktır.

11 Nisan 2014 Cuma

Python RSA Modülü ile Kriptolama

Bu yazımızda Python'da rsa modülünü kullanarak nasıl kriptolama yapabileceğinizden bahsedeceğiz. Kullanımı oldukça basit. Ama bunun için ilk önce rsa modülünün kurulması gerekiyor. Bunun için şu komutu vermeniz yeterli.
sudo pip install rsa
Modülü kurduktan sonra kullanımı oldukça basit. Şu örneği inceleyelim.
import rsa

(sifrelemeAnahtari,sifreCozmeAnahtari) = rsa.newkeys(512)

mesaj = 'Python Dersleri'

sifreliMetin = rsa.encrypt(mesaj,sifrelemeAnahtari)
CozulmusMetin = rsa.decrypt(sifreliMetin,sifreCozmeAnahtari)
print sifreliMetin
print CozulmusMetin
##Örnek çıktı
4�c�*)�� �G�7l��A ��ƚm�p E��P��:n��� >
Python Dersleri
  • 1.satır : rsa modülü içe aktarıldı.
  • 3.satır : rsa modülü ile kriptolama yapabilmek için anahtarlar üretildi. Buradaki 512 bit sayısını belirtir.
  • 7.satır : encrypt metodu ile şifreleme yapılır. Şifreleme yapılırken oluşturulan anahtar kullanılır.
  • 8.satır : decrypt medou ile şifrelenen metin çözülür. Çözülme yapılırken oluşturulan anahtar kullanılır.
Eğer istersek bildiğimiz kriptolama algoritmalarını kullanabiliriz. Örneğin bir metni sha512 ile kriptolayalım. Bunun için
import rsa

(sifrelemeAnahtari,sifreCozmeAnahtari) = rsa.newkeys(752)

mesaj = 'Python Dersleri'

sifreliMetin = rsa.sign(mesaj,sifreCozmeAnahtari,'SHA-512')
print sifreliMetin
#Örnek Çıktı
���e�����/����Qb!n7� _|7VT �/��q���i Km⢐�ʝ���r�ȁq ���o 3=� �ŧ�16E�� ��6�E�] �l"�~�R=�
Bu yöntem için sign metodunu kullanıyoruz. SHA-512 ile kriptolama yapabilmek için bit uzunluğunun en az 752 olması gerekmektedir.
rsa modülü hakkında çok daha ayrıntılı bilgilere http://stuvel.eu/rsa adresinden ulaşabilirsiniz.

10 Nisan 2014 Perşembe

FTP Sunucu Servisi Dosya/Dizin Tespit Çalışması

Gerek sistem yöneticileri için gerekse sızma testi uzmanları için ağ içerisindeki FTP sunucu servislerinin tespit edilerek içeriklerinin araştırılması gerekebilmektedir. Windows ağlarındaki paylaşımları tespit ederek belirtilen yapılandırma dosyasına göre veri taraması gerçekleştiren projeye https://github.com/galkan/depdep adresinden erişim sağlanabilir. Bunun için öncelikle gerekli ağ içerisindeki FTP sunucu servisleri için keşif çalışması gerçekleştirilmelidir. Bu amaçla en çok kullanılan yazılımlardan olan nmap ile ön tanımlı 21/tcp portu için tarama gerçekleştirerek mecut FTP sunucu servisleri için keşif adımı gerçekleştirilmelidir. Bu işlem 192.168.1.0 ağı için aşağıda gösterildiği şekilde gerçekleştirilebilir.

# nmap -n -PN -sS -p 21 --open 192.168.1.0/24

Bu amaçla aşağıda gösterilen betik kullanılabilir. FTP servisi için gerekli modül olarak ftputil kullanılmıştır. Daha fazla ayrıntı için https://pypi.python.org/pypi/ftputil/2.2.3 adresine göz atılabilir.

#!/usr/bin/python

try:
       import sys
       import ftplib
except ImportError,e:
        import sys
        sys.stdout.write("%s\n" %e)
        sys.exit(1)


class FTP:
  result = []

  def __init__(self):
    """
     Create instance for ftp ...
    """

    self.ftp = ftplib.FTP()


  def is_directory(self, ftp, directory):
    """
     Determine whether given parameter is directory or not ...  
    """

    try:
      ftp.cwd(directory)
    except:
            return False

    ftp.cwd("..")
    return True



  def traverse(self, ftp):
    """
     Traverse ftp and add results to the result list ...   
    """

    dirs = ftp.nlst()
        for item in (path for path in dirs if path not in ('.', '..')):
      if self.is_directory(ftp, item):
              try:
                   ftp.cwd(item)
                   self.traverse(ftp)
                   ftp.cwd('..')
              except Exception, e:
          pass

      else:
        ret = "%s/%s"% (ftp.pwd(), item)
        FTP.result.append(ret)



  def run(self, ip_addr, port, timeout, username = None , passwd = None):
    """
     Run ftp for given ip address and credentials ...
    """ 

    try:
      self.ftp.connect(ip_addr, port , timeout)
    except:
      return False
  
 
    try:
      if username and passwd is not None:
        self.ftp.login(username, passwd)
      else:
        self.ftp.login()
    except:
      return  False   

    self.ftp.set_pasv(True)
    self.ftp.cwd("/")
  
        self.traverse(self.ftp)

    return FTP.result


if __name__ == "__main__":
 ip = "192.168.37.37"
 port = 21
 timeout = 3
 username = "user"
 password = "password"

 ftp = FTP()
 for val in ftp.run(ip, port, timeout, username, password):
  print val




Betik ftp_traversing.py isimli dosyaya kaydediliğ aşağıdaki şekilde çalıştırıldığıdan elde edilecek çıktı aşağıdakinne benze şekilde olmaktadır.

# ./ftp_traversing.py
/dizin1/dizin2/dosya1
/dizin1/dizin3/dosya2
/dizin4/dizin5/dosya3
/dizin4/dizin6/dosya4
/dizin4/dizin7/dosya5
/dizin8/dizin9/dosya6




8 Nisan 2014 Salı

Kayıt Düzenleme ve Silme

Kayıt Düzenleme
Bir önceki konuda nasıl kayıt ekleyebileceğimizi gördük. Şimdi eklediğimiz bir kaydı nasıl düzenleyebiliriz? bunu inceleyeceğiz. Düzenleme işlemi yapabilmek için form elemanlarının varsayılan değerlerinin alanlara göre doldurulması gerekiyor. Hatırlarsanız bir form elemanın varsayılan değerini initial özelliği ile belirleye biliyorduk. Şimdi bu özelliği kullanarak doktorlar için oluşturduğumuz form ekleme formunu düzenleyelim. Eğer kullanıcı var olan bir kaydı düzenlemek isterse düzenleme, yeni kayıt eklemek isterse yeni kayıt ekleyelim.
İlk önce doktorları listelediğimiz şablonu değiştirerek form-ekle adresine gideceği butonu koyalım.
### doktor_listesi.html
<table border="1">
    <tr><th>Sıra</th><th>Adi</th><th>Soyadi</th><th>Telefon</th><th>E-Posta</th><th>İşlem</th></tr>

    {% for doktor in doktorlar %}
    <tr>
        <td>{{ forloop.counter }}</td>
        <td>{{ doktor.adi }}</td>
        <td>{{ doktor.soyadi }}</td>
        <td>{{ doktor.telefon }}</td>
        <td>{{ doktor.eposta }}</td>
        <td><a href="/doktor-ekle/?id={{ doktor.id }}">Düzenle</a></td>
    </tr>
    {% endfor %}

</table>
Adres çubuğuna http://localhost:8000/doktorlar/ yazdığımız da şu şekilde bir çıktı alacağız.
doktor_listesi.html şablonundaki 12.satıra inceleyelim. Burada GET metodunu kullanarak düzenleyeceğimiz verinin id numarasını alacağız. Veritabanından aldığımız id numarasına ait verileri getirerek formun varsayılan değeri yapacağız. Şimdi bu işlemleri yapacağımız doktor_ekleme görünümünü oluşturalım.
def doktor_ekleme(request):
 doktorID = request.GET.get('id')

 if doktorID:
  try:
   doktor = Doktor.objects.get(id=doktorID)
  except:
   return HttpResponse(u'Aradığınız doktor bulunamadı. ID= %s' % (doktorID))

 if request.method == 'POST':
  form = DoktorFormu(request.POST)

  if form.is_valid():
   temiz_veri = form.cleaned_data
   if not doktorID: doktor = Doktor()
   doktor.adi= temiz_veri['adi']
   doktor.soyadi = temiz_veri['soyadi']
   doktor.telefon = temiz_veri.get('telefon')
   doktor.eposta = temiz_veri.get('eposta')
   doktor.save()
   return HttpResponseRedirect('/doktorlar/')
 else:
  if doktorID:form = DoktorFormu(initial=doktor.__dict__)
  else: form = DoktorFormu()

 return render_to_response('form.html',
        {'form':form,'baslik':'Öğretim Elemanı İşlemleri'},
        context_instance = RequestContext(request))

Daha önce söylemiştik: GET metodu bir sayfa yenilendiğinde her zaman çalışır. Yani POST metodundaki gibi belirtmemiz gerekmiyor. Şimdi doktor_ekleme görünümünün adımlarını inceleyelim.
  • 2.satır: GET metodu ile id parametresinin değerini alıyoruz.
  • 4.satır: id parametresi ile bir değer gönderilmiş mi ? kontrol ediyoruz.
  • 6.satır: Eğer id gelmiş ise, o id'e ait doktoru veritabanında çekiyoruz.
  • 8.satır: Veritabanında doktoru çekerken eşleşme yapılamazsa öyle bir doktor olmadığını kullanıcıya bildiriyoruz.
  • 10.satır: Sayfanın Post edildiğinin kontrolünü yapıyoruz. Eğer POST edilmemişse 22.satıra atlanılacaktır.
  • 11.satır: Daha önce oluşturduğumuz DoktorFormu içerisine POST ile gelen değerleri gönderiyoruz.
  • 13.satır: DoktorFormu'na gönderilen değerlerin Form'un istediği değerler ile uyuşup uyuşmadığını kontrol ediyoruz.
  • 14.satır: Gelen verileri temizleyerek temiz_veri değişkenine atıyoruz.
  • 15.satır: Eğer doktorID boş ise yani id parametresine bir değer atanmamış ise doktor değişkenine Doktor() veritabanına eşitleyerek yeni veri ekleyeceğimizi bildiriyoruz. Eğer doktorID dolu ise atama işlemini zaten 6.satırda yapmıştık.
  • 16-19.satır Bu satırlar arasında veritabanındaki alanlara atama işlemini yapıyoruz. Zorunlu olmayan alanları hata olmaması için Post.get metodu ile aldığımıza dikkat edin. Bunu daha önce de söylemiştik.
  • 20.satır: Son atadığımız alanları veritabanına kaydediyoruz.
  • 22.satır Eğer görünüme POST edilerek gelinmedi ise bu blok çalışacaktır.
  • 23.satır: Eğer id parametresine değer atandı ise o değere sahip doktoru bularak doktor değişkenine atmıştık. Burada initial özelliğini kullanarak DoktorForm'u alanlarına varsayılan değer olarak doktor içerisindeki değerleri atıyoruz. Eğer id parametresine değer atanmadı ise boş bir DoktorFormu gönderiyoruz.
  • 26.satır: Şablon'a oluşturduğumuz formu gönderiyoruz.

Kayıt Silme
Kayıt düzenlemede olduğu gibi kayıt silme işlemi yapmadan önce doktor-listesi şablonuna sil butonunu koyalım.
###doktor_listesi.html
<table border="1">
    <tr><th>Sıra</th><th>Adi</th><th>Soyadi</th><th>Telefon</th><th>E-Posta</th><th>İşlem</th></tr>

    {% for doktor in doktorlar %}
    <tr>
        <td>{{ forloop.counter }}</td>
        <td>{{ doktor.adi }}</td>
        <td>{{ doktor.soyadi }}</td>
        <td>{{ doktor.telefon }}</td>
        <td>{{ doktor.eposta }}</td>
        <td><a href="/doktor-ekle/?id={{ doktor.id }}">Düzenle  </a><a href="/doktor-ekle/?id={{ doktor.id }}&sil=1">Sil</a></td>
    </tr>
    {% endfor %}

</table>
Adres çubuğuna http://localhost:8000/doktorlar/ yazdığımız da çıktı şu şekilde değişecek.
Şimdide doktor_ekleme görünümünü düzenleyelim.

def doktor_ekleme(request):
 doktorID = request.GET.get('id')

 if doktorID:
  try:
   doktor = Doktor.objects.get(id=doktorID)
  except:
   return HttpResponse(u'Aradığınız doktor bulunamadı. ID= %s' % (doktorID))

        ###silme işlemi için ekliyoruz
 if request.GET.get('sil'):
  doktor.delete()
  return HttpResponseRedirect('/doktorlar/')

 if request.method == 'POST':
  form = DoktorFormu(request.POST)

  if form.is_valid():
   temiz_veri = form.cleaned_data
   if not doktorID: doktor = Doktor()
   doktor.adi= temiz_veri['adi']
   doktor.soyadi = temiz_veri['soyadi']
   doktor.telefon = temiz_veri.get('telefon')
   doktor.eposta = temiz_veri.get('eposta')
   doktor.save()
   return HttpResponseRedirect('/doktorlar/')
 else:
  if doktorID:form = DoktorFormu(initial=doktor.__dict__)
  else: form = DoktorFormu()

 return render_to_response('form.html',
        {'form':form,'baslik':'Öğretim Elemanı İşlemleri'},
        context_instance = RequestContext(request))
Eğer sil parametresine değer ataması yapıldıysa doktorID ait doktor'u veritabanından siliyoruz. Son olarak doktorlar sayfasına doktor ekleyebilmek için Doktor Ekle butonu ekleyelim. Bunun için doktor_listesi.html şablonun istediğiniz bir yerine şu satırı ekleyin.
<a href="/doktor-ekle/">Doktor Ekle</a>
Yaptığımız uygulamalarda tüm işlemleri tek bir görünüm üzerinden yaptık. Eğer isterseniz farklı görünümler üzerinden de yapabilirsiniz. Silme işlemini farklı bir görünüm ile yapalım.
İlk önce urls.py dosyasına şu satırı ekleyelim.
url(r'^doktor-sil/',yonetim.views.doktor_silme),
Daha sonra doktor_listesi.html şablonunu değiştirelim.
<table border="1">
    <tr><th>Sıra</th><th>Adi</th><th>Soyadi</th><th>Telefon</th><th>E-Posta</th><th>İşlem</th></tr>

    {% for doktor in doktorlar %}
    <tr>
        <td>{{ forloop.counter }}</td>
        <td>{{ doktor.adi }}</td>
        <td>{{ doktor.soyadi }}</td>
        <td>{{ doktor.telefon }}</td>
        <td>{{ doktor.eposta }}</td>
##doktor-sil sayfasına yönlendirdik.
        <td><a href="/doktor-ekle/?id={{ doktor.id }}">Düzenle  </a><a href="/doktor-sil/?id={{ doktor.id }}">Sil</a></td>
    </tr>
    {% endfor %}

</table>
Son olarak da doktor_silme görünümünü oluşturalım.
def doktor_silme(request):
 doktorID = request.GET.get('id')
 if doktorID:
  try:
   doktor = Doktor.objects.get(id=doktorID)
  except:
   return HttpResponse(u'Aradığınız doktor bulunamadı. ID= %s' % (doktorID))

 doktor.delete()
 return HttpResponseRedirect('/doktorlar/')
Aynı işlemi farklı görünüm üzerinden yapmış olduk. Sizde güncelleme işlemini farklı görünüm üzerinden yapmayı deneyin.
Kaynakça
  • Mustafa Başer Django Kitabı

5 Nisan 2014 Cumartesi

Formların Görünümler ile Kullanılması

Gelelim asıl meselemize. Formu Django imkanlarından yararlanarak basit bir şekilde oluşturduk. Şimdi bunu görünümlerde kullanarak kullanıcıya göstermemiz gerekiyor. Daha önceden yaptığımız veritabanına Doktor ekleme işlemini artık Django Formlarını kullanarak yapalım.
İlk önce görünümü oluşturalım.
from yonetim.forms import *
def doktor_ekleme(request):
 if request.method == "POST":
  form = DoktorFormu(request.POST)
  if form.is_valid():
   temiz_degerler = form.cleaned_data
   doktor = Doktor(adi=temiz_degerler['adi'],soyadi=temiz_degerler['soyadi'],
       telefon=temiz_degerler.get('telefon'),eposta=temiz_degerler.get('eposta'))
   doktor.save()
   return HttpResponseRedirect('/doktorlar/')
  else:
   return render_to_response('form.html',{'form':form,'baslik':'Doktor Ekleme'},context_instance = RequestContext(request))
 else:
  form = DoktorFormu()
  return render_to_response('form.html',{'form':form,'baslik':'Doktor Ekleme'},context_instance = RequestContext(request))
Burada eğer Post edilmiş ise işlem yapıyoruz edilmemişse formu form.html şablonuna yönlendiriyoruz.
form = DoktorFormu(request.POST) satırı ile formdan gelen verileri doğrudan oluşturduğumuz DoktorFormu sınıfına yolluyoruz.
is?valid() ile kontrol ediyoruz eğer herhangi bir sıkıntı yoksa veritabanına kaydediyoruz. Girilen değerler de problem varsa tekrardan form sayfasına yönlendiriyoruz.
temiz_degerler = form.cleaned_data satırı ile gelen verileri güvenlik için temizledik ve temizlediğimiz değerler üzerinden işlem yaptık.
Zorunlu olmayan verileri temiz_degerler.get('telefon') şeklinde aldık. Eğer bu şekilde değilde doğrudan alırsak kullanıcı alanları doldurmazsa hata ile karşılaşırız. Bunu engellemek için bu şekilde kulandık.
Şimdi genel bir form tasarlayalım. yonetim/sablonlar içerisine form.html adında şablon oluşturuyoruz.
<!DOCTYPE html>
<html>
<head>
    <title>{{ baslik }}</title>
     <link rel="stylesheet" type="text/css" href="/static/base.css">
</head>
<body>
<h1>{{ baslik }}</h1>
{% if form.errors %}
    <span style="color: red">
        Hataları düzeltin :
    </span>
{% endif %}

<form method="POST">
    {% csrf_token %}
    <table border="1">
            {{ form }}
     <tr><td></td><td><input type="submit" value="Gönder" /></td></tr>
    </table>

</form>


</body>
</html>
Gördüğünüz gibi gönderdiğimiz formu doğrudan yazdırdık. Eğer bir hata varsa kontrolünü forms.error ile yakalayarak kullanıcıyı uyardık. Eğer kullanıcı verileri yanlış doldurarak gönderirse şu şekilde bir çıktı ile karşılaşacak.
Django formu oluştururken etiketleri alan isimlerine göre kendisi belirliyor. Biz istersek kendi etiketlerimiz oluşuturabiliriz. Bunun için DoktorFormu sınıfını değiştirelim.
class DoktorFormu(forms.Form):
 adi  =  forms.CharField(label="Adınız")
 soyadi  =  forms.CharField(label="Soyadınız")
 telefon =  forms.CharField(label = "Telefon Numaranız:",required=False)
 eposta  = forms.EmailField(label="E-Posta Adresiniz",required=False)
Sayfayı yenilediğiniz zaman kendi etiketlerinizi göreceksiniz. Hataları alan üstlerinde göstermek pek hoş olmadı bunun için şablonu biraz daha değiştirelim ve hataları yanında gösterelim.
<!DOCTYPE html>
<html>
<head>
    <title>{{ baslik }}</title>
     <link rel="stylesheet" type="text/css" href="/static/base.css">
</head>
<body>
<h1>{{ baslik }}</h1>
{% if form.errors %}
    <span style="color: red">
        Hataları düzeltin :
    </span>
{% endif %}

<form method="POST">
    {% csrf_token %}
    <table border="1">

        {% for f in form %}
            {% if f.errors %}<tr >{%else %}<tr>{% endif %}
            <th>{{ f.label }}</th>
            <th>{{ f }}</th>
            {% if f.errors %}<td style="color: red">{{ f.errors }}</td>{% endif %}
            </tr>
        {% endfor %}

     <tr><td></td><td><input type="submit" value="Gönder" /></td></tr>
    </table>

</form>


</body>
</html>
Burada alanları tek tek yazdırdık. Eğer o alanda bir problem varsa yanına yeni bir sütün daha ekleyerek hatayı gösterdik. Çıktımız şu şekilde olacak.
Bu işlem bu kadar. Şimdi küçük bir bilgi verelim. Elimizde bulunan bir form nesnesini istediğimiz bir başka nesneye dönüştürebilmek için widget özelliğini kullanabiliriz.
class DoktorFormu(forms.Form):
 adi  =  forms.CharField(label="Adınız")
 soyadi  =  forms.CharField(label="Soyadınız")
 telefon =  forms.CharField(label = "Telefon Numaranız:",required=False)
 eposta  = forms.EmailField(label="E-Posta Adresiniz",required=False)
 mesaj =  forms.CharField(widget=forms.Textarea)
Bu şekilde değiştirdikten sonra form içerisinde bir textarea nesnesi göreceksiniz.
Kaynakça

2 Nisan 2014 Çarşamba

Django Form Yapısı

Bir önceki bölümde Formların şablonlar içerisinde kullanarak görünümler ile bağlantısını sağlamıştık. Bu bölümde ise Django'nun bizim için sağladığı kolaylıklardan olan ve form oluşturma işini Django'nun hallettiği form yapısından bahsedeceğiz. Yani biz modelleri oluştururken yaptığımız gibi nasıl bir form istediğimizi söyleyeceğiz. Django formu bizim için oluşturacak.
Form oluşturma işlemini uygulama içerisindeki herhangi bir Python dosyası içerisinde yapabilirsiniz. Ama biz geleneğe bağlı kalarak forms.py dosyası içerisinde oluşturacağız. Şimdi daha önceki hastahane projemiz üzerinden gidiyoruz.
yonetim/forms.py dosyasını oluşturarak içerisine kodları yazıyoruz.
from django import forms

class DoktorFormu(forms.Form):
 adi  =  forms.CharField()
 soyadi  =  forms.CharField()
 telefon =  forms.CharField(required=False)
 eposta  = forms.EmailField(required=False)
Burada ilk olarak django programından formsu içe aktarıyoruz. İçe aktarma yaptığımıza göre artık fonksiyonlarını kullanabiliriz. Oluşturduğumuz form sınıfının model sınıfı oluşturmaya çok benzediğini fark etmişsinizdir. Burada dikkat etmemiz gereken form alanlarına isim verirken modellerimizdeki isimler ile aynı olması gerektiğidir. telefon ve eposta alanlarını oluştururken kullandığımız required=False özelliği isteğe bağlı olduğunu belirtir.
Django kabuğunu açarak formumuzun nasıl olduğunu kontrol edelim.
>>> from yonetim.forms import *
>>> doktorForm = DoktorFormu()
>>> print doktorForm
<tr><th><label for="id_adi">Adi:</label></th><td><input id="id_adi" name="adi" type="text" /></td></tr>
<tr><th><label for="id_soyadi">Soyadi:</label></th><td><input id="id_soyadi" name="soyadi" type="text" /></td></tr>
<tr><th><label for="id_telefon">Telefon:</label></th><td><input id="id_telefon" name="telefon" type="text" /></td></tr>
<tr><th><label for="id_eposta">Eposta:</label></th><td><input id="id_eposta" name="eposta" type="email" /></td></tr>
Django bizim için label(etiket) ve input taglarını kullanarak formu oluşturdu.Buradaki etiketler alan isimlerinden çıkartılır.Django formları tarayıcıda düzgün görünebilmesi için tablo yapısını kullanarak oluşturdu. Ama dikkat etmelisiniz form açma(<table>) ve kapama(</table>) etiketleri bulunmamaktadır. Bu etiketleri şablon içerisinde kendimiz ekleyeceğiz. Formları oluşturmanın tek yolu tablo yapısı değil. Django bize bir kaç alternatif sunar.
Form elemanlarını satır satır bastıralım.
>>> from yonetim.forms import *
>>> doktorForm = DoktorFormu()
>>> print doktorForm
<tr><th><label for="id_adi">Adi:</label></th><td><input id="id_adi" name="adi" type="text" /></td></tr>
<tr><th><label for="id_soyadi">Soyadi:</label></th><td><input id="id_soyadi" name="soyadi" type="text" /></td></tr>
<tr><th><label for="id_telefon">Telefon:</label></th><td><input id="id_telefon" name="telefon" type="text" /></td></tr>
<tr><th><label for="id_eposta">Eposta:</label></th><td><input id="id_eposta" name="eposta" type="email" /></td></tr>
Veya form elemanlarını liste şeklinde de alabiliriz.
>>> print doktorForm.as_ul()
<li><label for="id_adi">Adi:</label> <input id="id_adi" name="adi" type="text" /></li>
<li><label for="id_soyadi">Soyadi:</label> <input id="id_soyadi" name="soyadi" type="text" /></li>
<li><label for="id_telefon">Telefon:</label> <input id="id_telefon" name="telefon" type="text" /></li>
<li><label for="id_eposta">Eposta:</label> <input id="id_eposta" name="eposta" type="email" /></li>
Python bizim için her şeyi biz nasıl istersek o şekilde yapıyor. Oluşturduğumuz bir form içerisinden istediğimiz bir elemanı çekebiliriz.
>>> print doktorForm['adi'].label
Adi
>>> print doktorForm['adi']
<input id="id_adi" name="adi" type="text" />
Varsayılan Değerler
Eğer bir form elemanın sayfa yüklenirken varsayılan bir değer ile yüklenmesini istiyorsanız bunu da sağlayabilirsiniz. Bunun için initial özelliğini kullanacağız.
>>> varsayilan = {'adi':'Adiniz. Bos birakilamaz.'}
>>> form = DoktorFormu(initial=varsayilan)
>>> print form
<tr><th><label for="id_adi">Adi:</label></th><td><input id="id_adi" name="adi" type="text" value="Adiniz. Bos birakilamaz." /></td></tr>
<tr><th><label for="id_soyadi">Soyadi:</label></th><td><input id="id_soyadi" name="soyadi" type="text" /></td></tr>
<tr><th><label for="id_telefon">Telefon:</label></th><td><input id="id_telefon" name="telefon" type="text" /></td></tr>
<tr><th><label for="id_eposta">Eposta:</label></th><td><input id="id_eposta" name="eposta" type="email" /></td></tr>
Artık adi etiketinin value değerinin dolu olduğunu görebilirsiniz.
Formların Kontrolü
Formlar doldurulduktan sonra bizim istediğimiz standartlara göre doldurulup doldurulmadığını kontrol edebiliriz. Eğer bu kontrolü yapmaz isek aldığımız değerleri veritabanına kaydederken standartlara uygun olmadığı için hata ile karşılaşırız. Kontrol etmek için is_valid() metodunu kullanacağız.
>>> gonderilenler = {'adi':'Mustafa','soyadi':'Kemal','eposta':'mustafa@mail.com'}
>>> doktorForm = DoktorFormu(gonderilenler)
>>> doktorForm.is_valid()
True
>>> gonderilenler = {'adi':'Mustafa','eposta':'mustafa@mail.com'}
>>> doktorForm = DoktorFormu(gonderilenler)
>>> doktorForm.is_valid()
False
İlk durumda form hatasız olduğu için True değeri döndürüldü. Fakat ikinci durumda soyadi kısmını zorunlu yapmıştık ve girilmediği için False döndü. Yani form hatalı bir şekilde doldurulmuş. Peki hatalı doldurulan kısımlar nereler? Bunu öğrenebilmek için , errors özelliğini kullanacağız.
>>> doktorForm.errors
{'soyadi': [u'This field is required.']}
Hataları buradan anladık. İngilizce olması önemli değil. Tarayıcıda, tarayıcının diline döndürülecektir.
Django formları kendi mekanizmasına göre denetler. Ama bazı durumlarda denetlemeyi kendi isteğimize göre değiştirmek isteyebiliriz. Bunun için clean_[alanadi]() fonksiyonunu kullanmamız gerekir. Django denetleme yaparken her form sınıfının altındaki bu işleve bakar. Şimdi telefon numarasının 11 karakterden oluşması için bu fonksiyonu yazalım.
class DoktorFormu(forms.Form):
 adi  =  forms.CharField(label="Adınız")
 soyadi  =  forms.CharField(label="Soyadınız")
 telefon =  forms.CharField(label = "Telefon Numaranız:",required=False)
 eposta  = forms.EmailField(label="E-Posta Adresiniz",required=False)

 def clean_telefon(self):
  tel = self.cleaned_data['telefon']
  if tel != "":
   if len(tel) != 11:
    raise forms.ValidationError('Telefon numarasi 11 karakter olmalidir.')
  return tel
Deneyelim.
>>> from yonetim.forms import *
>>> DoktorForm = DoktorFormu({'adi':'Mustafa','soyadi':'Metin','telefon':'5555'})
>>> DoktorForm.errors
{'telefon': [u'Telefon numarasi 11 karakter olmalidir.']}
Gördüğünüz gibi clean_[alanadi]() işlevini kullanarak kendi kontrolümüzü oluşturduk. Sizde istediğiniz bir alan için kontrol yapabilirsiniz.
Kaynakça

31 Mart 2014 Pazartesi

Python QT (PyQt) Kurulumu


PyQT, Riverbank tarafından geliştirilmektedir.
Linux dağıtımlarında genellikle PyQt paketi bulunmaktadır. Ancak yok ise Terminale
  • sudo apt-get install python2-pyqt4
kodunu yazdığınızda Python 2.x sürümü için PyQt4 paketini yükleyebilirsiniz.

Windows kullanıcıları ise http://www.riverbankcomputing.co.uk/software/pyqt/download adresine gidip kullandıkları sisteme ve Python sürümüne uygun PyQt paketini indirmelidirler.
Burada PyQt paketi dağıtımlarının isimlerinde Python sürümü, lisans türü ve Qt sürümü yazmaktadır. Biz sizler için burada Python 2.x için Qt4.8.5 sürümünün kurulumunu göstereceğiz.

Öncelikle Riverbank'ın sitesinden gerekli indirme işlemini yapıyoruz ve sonrasında inen kurulum dosyasını çalıştırıyoruz. Sırayla gelen ekranda Next ondan sonra gelen lisans sözleşmesi ekranında I Agree deyin.




Daha sonra karşınıza yüklemek istediğiniz bileşenleri soran yandaki ekran gelecektir. Burada bir değişiklik yapmanızı önermiyorum. Bu şekilde kuruluma Next diyerek devam edin.






Daha sonra karşınıza yandaki ekran gelecek burada PyQt'nin nereye kurulacağı sorulmaktadır. Kurulum asistanı Python2.7'nin nerede olduğunu bulamamışsa, Python 2.7'nin kurulu olduğu klasörü belirtin. Sonrasında da Install diyerek kurulumu gerçekleştirin.


Kurulum tamamlandıktan sonra gelen ekranda ise Finish diyerek, PyQt paketinin kurulumunu bitiriyoruz.


Kurulumu tamamladığınızdan emin olmak için kontrol edebilirsiniz. Bunun için Python'un etkileşimli kabuğuna
import PyQt4
yazmanız yeterli. Eğer
Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    import PyQt4
ImportError: No module named PyQt4
hatası alıyorsanız, kurulum hatalıdır. Hata almadan bir alt satıra geçmiş iseniz kurulumu doğru bir şekilde tamamlamışsınızdır.

Kaynaklar:
http://www.istihza.com/beta/qt4/temel_bilgiler.html
Mustafa Başer - Python Kitabı

28 Mart 2014 Cuma

Formlar

Şimdi formları daha detaylı kullanarak daha önceki hastahane projesinde kullanıcıya yeni Doktor ekleme işlemi yaptıralım. İlk önce formu barındıran bir şablon oluşturalım.
<!DOCTYPE html>
<html>
<head>
    <title>Doktor Ekleme</title>
    <link rel="stylesheet" type="text/css" href="/dosyalar/base.css" />
</head>
<body>

<h1>Doktor Ekle</h1>

<form action="/doktor-ekle/" method="post">
    {% csrf_token %}
    <table>
        <tr><th>Adı:</th><td><input type="text" name="adi"/></td></tr>
        <tr><th>Soyadı:</th><td><input type="text" name="soyadi"/></td></tr>
        <tr><th>Telefon</th><td><input type="text" name="telefon"/></td></tr>
        <tr><th>E-Posta</th><td><input type="text" name="eposta"/></td></tr>
         <tr><th></th><td><input type="submit" value="Ekle"/></td></tr>
    </table>

</form>

</body>
</html>
Buradaki kullandığımı % csrf_token %} satırına dikkat etmişsinizdir. Bu değişken Cross Site Request Forgery saldırılarından korunmak için form içerisinde her oturum için rastgele bir değer üretilip bu değer kullanıcıdan geleni ile karşılaştırıldıktan sonra işlemin yapılmasını sağlar. Form kaynağına bakarsanız şu şekilde bir satır görürebilirsiniz:
<input type='hidden' name='csrfmiddlewaretoken' value='yrseedSoajFQTxom0vYD8hD6QAj8CPo8' />
Şimdi kullanıcıdan verileri alarak ekrana yazdıran görünümü oluşturalım.
from django.http import *
from django.template import RequestContext
def doktor_ekle(request):
 if request.method == "POST":
  adi = request.POST.get('adi')
  soyadi = request.POST.get('soyadi')
  telefon = request.POST.get('telefon')
  eposta = request.POST.get('eposta')
  return HttpResponse('''
  <strong>Adi:</strong> %s <br/>
  <strong>Soyadi:</strong> %s <br/>
  <strong>Telefon:</strong> %s <br/>
  <strong>E-Posta:</strong> %s <br/>
  '''%(adi,soyadi,telefon,eposta))
 else:
  return render_to_response('doktor_formu.html',context_instance = RequestContext(request) )
Görünümü de oluşturduk. Tabi kullanıcının form'a ulaşabilmesi için urls.py dosyasına şu satırı eklememiz gerekiyor.
url(r'^doktor-ekle/',yonetim.views.doktor_ekle),
Artık tarayıcıdan localhost:8000/doktor-ekle diyerek forma ulaşabiliriz. Formu post ederek sonuçlarına bakabilirsiniz. Tabi biz burada sadece ekrana yazdırdık. Burada yapmamız gereken aldığımız verileri veritabanına eklememiz gerekir. Ama biz verileri alırken hiç bir filtreleme işlemi yapmadık. Hatırlarsanız Doktor tablosunda ad ve soyad kısımları zorunlu alanlardı. Eğer biz kullanıcı POST ettiğinde bu alanların dolu olup olmadığını kontrol etmezsek veritabanına eklemeye çalışırken Django hata döndürür. Bu yüzden ilk önce aldığımız verilerin kontrolünü yapalım. Görünümü şu şekilde değiştiriyoruz.
def doktor_ekle(request):
 if request.method == "POST":

  adi = request.POST.get('adi')
  soyadi = request.POST.get('soyadi')
  telefon = request.POST.get('telefon')
  eposta = request.POST.get('eposta')

  hatalar = []
  if not (adi or soyadi):
   hatalar.append('Adı veya soyadı boş bırakılamaz.')
  if eposta:
   if not ('@' and '.') in eposta:
    hatalar.append('Doğru bir E-posta adresi girmelisiniz.')
  if telefon:
   if len(telefon) != 11:
    hatalar.append('Telefon numarası 11 haneli olmalı.')
  if hatalar:
   return HttpResponse('Hataları düzeltip tekrar gönderin: <li>%s' % ' <li>'.join(hatalar))
  return HttpResponse('''
  <strong>Adi:</strong> %s <br/>
  <strong>Soyadi:</strong> %s <br/>
  <strong>Telefon:</strong> %s <br/>
  <strong>E-Posta:</strong> %s <br/>
  '''%(adi,soyadi,telefon,eposta))
 else:
  return render_to_response('doktor_formu.html',context_instance = RequestContext(request) )
Burada eğer adı veya soyadı girilmediyse, kullanıcı telefon numarasını eksik veya fazla girdiyse, eposta adresi içerisinde @ ve . işaretleri yoksa kullanıcıya hata döndürüyoruz. Kullanıcı hatalı girdiği zaman geri dönerek tekrar düzeltmek zorundadır. Biz bu şekilde yapmayalım da kullanıcı hatalı girerse hataları ve formu aynı sayfada göstererek kullanıcıyı uyaralım. Görünümü tekrardan şu hale getirelim.
def doktor_ekle(request):
 if request.method == "POST":

  adi = request.POST.get('adi')
  soyadi = request.POST.get('soyadi')
  telefon = request.POST.get('telefon')
  eposta = request.POST.get('eposta')

  hatalar = []
  if not (adi and soyadi):
   hatalar.append('Adı veya soyadı boş bırakılamaz.')
  if eposta:
   if not ('@' and '.') in eposta:
    hatalar.append('Doğru bir E-posta adresi girmelisiniz.')
  if telefon:
   if len(telefon) != 11:
    hatalar.append('Telefon numarası 11 haneli olmalı.')
  if hatalar:
   return render_to_response('doktor_formu.html',locals(),context_instance = RequestContext(request))
  else:
   return HttpResponse('''
   Adi: %s 
Soyadi: %s
Telefon: %s
E-Posta: %s
'''%(adi,soyadi,telefon,eposta)) else: return render_to_response('doktor_formu.html',context_instance = RequestContext(request))
Eğer hata ile karşılaşırsa tekrardan doktor_formu.html şablonuna yönlendireceğiz. Bu sayfaya yönlendirdiğimiz zaman formdaki alanlar boş gelecektir. Bunu engellemek için doktor_formu.html şablonunda POST ile gelen verileri elemanlar içerisine yazdırmamız gerekli. Hataları da yine aynı şekilde şablon içerisinde yapacağız. Bu yüzden doktor_formu.html şablonu üzerinde bazı değişiklikler yapacağız.
Uyarı: Eğer bir Python dosyasında Türkçe karakter kullanırsanız hata ile karşılaşırsınız. Hata ile karşılaşmamak için dosya içerisinde en başa şu kodu yazmanız gerekir.
# -*- coding: utf-8 -*-
Bizim dosyalarımızda bu kod olduğu için Türkçe karakterlerde herhangi bir sıkıntı yaşanmadı.
<!DOCTYPE html>
<html>
<head>
    <title>Doktor Ekleme</title>
    <link rel="stylesheet" type="text/css" href="/dosyalar/base.css" />
</head>
<body>

<h1>Doktor Ekle</h1>

{% if hatalar %}
    <span style="color:red">
        {{ hatalar|unordered_list }}
    </span>
{% endif %}

<form action="/doktor-ekle/" method="post">
    {% csrf_token %}
    <table>
        <tr><th>Adı:</th><td><input type="text" name="adi" value="{{ adi }}"/></td></tr>
        <tr><th>Soyadı:</th><td><input type="text" name="soyadi" value="{{ soyadi }}"/></td></tr>
        <tr><th>Telefon</th><td><input type="text" name="telefon" value="{{ telefon }}"/></td></tr>
        <tr><th>E-Posta</th><td><input type="text" name="eposta" value="{{ eposta }}" /></td></tr>
         <tr><th></th><td><input type="submit" value="Ekle"/></td></tr>
    </table>

</form>

</body>
</html>
Burada kullanıcı hatalı giriş yaparsa şu şekilde bir çıktı ile karşılaşacaktır. Bir kaç deneme yapabilirsiniz.
Şimdi gelelim asıl işlemimize. Kullanıcıdan verileri aldıktan sonra ne yapacağız ? Tabi ki veritabanına eklememiz gerekiyor. Bu yüzden görünümü veritabanına ekleme işlemini yapacak şekilde değiştirmemiz gerekiyor.
def doktor_ekle(request):
 if request.method == "POST":

  adi = request.POST.get('adi')
  soyadi = request.POST.get('soyadi')
  telefon = request.POST.get('telefon')
  eposta = request.POST.get('eposta')

  hatalar = []
  if not (adi and soyadi):
   hatalar.append('Adı veya soyadı boş bırakılamaz.')
  if eposta:
   if not ('@' and '.') in eposta:
    hatalar.append('Doğru bir E-posta adresi girmelisiniz.')
  if telefon:
   if len(telefon) != 11:
    hatalar.append('Telefon numarası 11 haneli olmalı.')
  if hatalar:
   return render_to_response('doktor_formu.html',locals(),context_instance = RequestContext(request))
  else:
   doktor = Doktor(adi=adi,
       soyadi=soyadi,
       telefon=telefon,
       eposta=eposta)

   doktor.save()
   return HttpResponseRedirect('/doktorlar/')
 else:
  return render_to_response('doktor_formu.html',context_instance = RequestContext(request))
Doktor ekleme işlemi yaptıktan sonra daha önceden hazırlamış olduğumuz veritabanında ki doktorları listeleyen doktorlar sayfasına yönlendirme yapıyoruz.
Eğer isterseniz formları kullanmak için şu yolu da kullanabilirsiniz. Formu çağırdığınız ve post edildikten sonra işlemleri yapacağınız görünümü birbirinden ayırabilirsiniz.
## urls.py
 url(r'^arama/',yonetim.views.arama),
 (r'^arama-form/',yonetim.views.arama_form),
## views.py
def arama_form(request):
 return render_to_response('arama.html',context_instance = RequestContext(request))

def arama(request):
 if request.method == "POST":
  aranan = request.POST.get('aranan')
  return HttpResponse('Aranan ifade : %s' %(aranan))
 else:
  return HttpResponse('Bu şekilde arama yapılamaz..')
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>

<form action="/arama/" method="post">
    {% csrf_token %}
<b>Ara:</b><input type="text" name="aranan" /><br/>
    <input type="submit" value="Ara" />
</form>

</body>
</html>

Kaynakça

25 Mart 2014 Salı

PyQt'ye Giris

pythondersleri.com yeni bir yazı dizisi "PyQt : Grafiksel Kullanıcı Arayüzü Uygulamaları" ile karşınızda! Bu yazıyı okuyarak, PyQt ile haşır neşir olmaya başlamadan önce yazı dizisinin kapsamı ile ilgili olarak fikir sahibi olabilirsiniz.

PyQt, kullanıcılara grafiksel arayüz (GUI) deneyimi sunmak için geliştirilmiş bir Python kütüphanesidir.

Tasarlamış  olduğunuz uygulamaları sunma biçiminiz tamamen sizin tasarrufunuzda olan bir durumdur. Geliştirilmekte olan işletim sistemleri (mobil dahil), kullanıcıların uygulamalar ile olan etkileşimini her geçen gün daha da kolaylaştırmaya çabası içerisindedirler. Dolayısıyla geliştireceğiniz uygulamaların komut satırı arayüzü üzerinde çalışmasından çok, görsel bir arayüz üzerinde çalışması uygulamalarınızın kullanılabilirliğini arttıracaktır.

Python üzerinde GUI uygulamaları geliştirmenizi sağlayacak çeşitli kütüphaneler mevcuttur. Tkinter, PyGObject + GTK3, PyQt bu kütüphanelere örnek olarak gösterilebilirler. PyQt'nin ne olduğunu irdelemeye başlamadan önce Qt ile ilgili bir özet geçmek faydalı olacaktır.
Qt çapraz platform desteği olan GUI geliştirme araç takımıdır. Qt ilk olarak Norveçli Trolltech firması tarafından geliştirilmeye başlanmış, daha sonra Nokia'nın bünyesine katılmıştır. Son olarak başarılı bir özgür yazılım projesi olacağı öngörüsüyle Digia isimli firma tarafından satın alınan Qt, LGPL ile lisanslanarak geliştiricilerin kullanımına sunulmuştur.Yayınlanan en son stabil sürümü 5.2'dir. Dünya çapında büyük firmaların (Google, Adobe, Siemens vb.) Qt altyapısı kullanılarak geliştirilmiş uygulamaları mevcuttur.


PyQt ise Riverbank Computing LTD şirketi tarafından geliştirilmeye devam edilen bir kütüphanedir. Uygulamalarınızda PyQt kullanmayı tercih ederseniz;  2D / 3D grafik desteğinden tutun, Model/View mimarisine kadar birçok yapıyla çalışma imkanına sahip olursunuz. Kısacası modern bir arayüz geliştirme kütüphanesi avuçlarınızın arasında!
Haydi bir sonraki yazıya gözatıp PyQt'ye merhaba deyin!

24 Mart 2014 Pazartesi

GET ve POST Metodları

Kullanıcıdan veri alırken iki şekilde alabiliriz. Bu yöntemler GET ve POST metodlarıdır. Aralarında bazı farklar vardır. GET ile alınan tüm veriler tarayıcının adres çubuğunda görülür ve yaklaşık olarak 2KB civarında boyut sınırlaması vardır. POST metodu ise verileri tarayıcıya doğrudan gönderdiği için gönderilen veriler adres çubuğunda görünmez. Herhangi bir boyut sınırlaması da yoktur.
GET Metodu
yonetim/views.py dosyasına arama görünümü ekleyelim.
from django.http import *
def Arama(request):
 if request.method == "GET":
  kelime = request.GET['kelime']
  return HttpResponse('Aranan Kelime:  %s' % (kelime))
Tarayıcıdan http://localhost:8000/arama/?kelime=deneme girdiğiniz zaman çıktıyı alacaksınız.
Aranan Kelime: deneme
Burada dikkat etmemiz gereken veriyi request.GET['kelime'] metodu ile aldığımız için eğer kelime girilmemiş ise yani tarayıcıdan http://localhost:8000/arama/ girilirse hata ile karşılaşırız. Burada hata ile karşılaşmamak için request.GET.get('kelime') metodunu kullanmalıyız. Eğer veri girilmedi ise boş değer döndürür.
### views.py
def arama(request):
 if request.method == "GET":
  kelime = request.GET.get('kelime')
  return HttpResponse('Aranan Kelime:  %s' % (kelime))
##Taryıcı adres çubuğu
http://localhost:8000/arama/
### Çıktı
Aranan Kelime: None
Gördüğünüz gibi hata ile karşılaşmadık. Aslında herhangi bir adrese girildiğinde biz işlem yapmasak bile GET metodu çalışır.
POST Metodu
Şimdi POST metodunu anlayabilmek için aynı örneğin form uygulamasını yapalım. Formlara daha ayrıntılı şekilde bakacağız. İlk önce yonetim/sablonlar içerisine get_post.html adında bir şablon oluşturuyoruz.
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>

<form action="/arama-post/" method="post">
    {% csrf_token %}
    Aranacak kelime : <input type="text" name="kelime" />
    <input type="submit" value="Ara" />
</form>


</body>
</html>
Şimdi yonetim/views.py dosyasına şu görünümü ekliyoruz.
from django.http import *
from django.template import RequestContext
def arama_post(request):
 if request.method == "POST":
  kelime = request.POST['kelime']
  return HttpResponse('Aranan kelime: %s'%(kelime))
 else:
  return render_to_response('get_post.html',context_instance=RequestContext(request))
urls.py
url(r'^arama-post/',yonetim.views.arama_post),
Şimdi tarayıcıdan localhost:8000/arama-post yazarak arama formuna ulaşabilirsiniz. Görünümde yaptığımız işlem eğer POST işlemi yapıldıysa kelimeyi kelime = request.POST['kelime'] satırı ile elde ediyoruz. HttpResponse ile ekrana basıyoruz. Eğer POST işlemi yapılmadıysa get_post.html şablonunu ekrana yazdırıyoruz.
Kaynakça :

22 Mart 2014 Cumartesi

URL Hakkında Bilgiler

Formlar konusuna geçmeden önce URL hakkındaki bazı bilgileri ulaşmayı görelim. HTTPRequest nesneleri URL hakkında çeşitli bilgileri içerir. Bulunduğumuz adresin yolunu almak için request.path özelliğini kullanabilir. Bulunduğumuz adresin yolunu almak için görünüm oluşturalım.
def yol(request):
 yol = request.path
 return HttpResponse('Adres Yolu: %s' % (yol))
Görünüme ulaşabilmek için urls.py ekleyelim.
url(r'adres-yolu/',yonetim.views.yol),
Adres çubuğuna localhost:8000/adres-yolu yazdığınızda şu şekilde bir çıktı alacaksınız.
Adres Yolu: /adres-yolu/
O anda adres çubuğunda bulunduğumuz yerin adresini bu şekilde aldık. Dikkat ederseniz host name kısmı alınmadı.
Özellik/MethodAçıklamaÖrnek
request.get_host()Hostname ulaşmak için kullanılır.localhost:8000
request.get_full_path()Tam yolu almak için kullanılır. Tarayıcıdaki verilen parametrelerde görülür.Tarayıcı : http://localhost:8000/adres-yolu/?get=deneme
Method'un dönüş değeri : /adres-yolu/?get=deneme
request.is_secure()Eğer HTTPS protokolü kullanılıyorsa True döndürür. HTTP protokolü kullanılıyorsa False döndürür.False
Request Değerinin Diğer Özellikleri
Oluşturduğumuz bir görünümde argüman olarak aldığımız request(istek) değişkenin çeşitli az önce bahsettiklerimiz gibi çeşitli metodları vardır. Buradaki request yerine istediğiniz değişken ismini verebilirsiniz. Biz sadece geleneklere uymak için request olarak kullanacağız.
def gorunum(request):
request.META
request.Meta kullanıcının ip adresi, kullandığı tarayıcı, sunucu adı, sunucunun kullandığı protokol gibi pek çok bilgiyi içeren bir sözlüktür.
  • HTTP_USER_AGENT Tarayıcı hakkında bilgi verir.
  • REMOTE_ADDR Kullanıcı ip adresi.
  • SERVER_PORT Sunucunun kullandığı port numarası.
Bu şekilde pek çok anahtar içermektedir. Bu anahtarların ve değerlerinin hepsine şu şekilde ulaşabilir ve istediğinizi kullanabilirsiniz.

def display_meta(request):
    values = request.META.items()
    values.sort()
    html = []
    for k, v in values:
        html.append('%s%s' % (k, v))
    return HttpResponse('%s
' % '\n'.join(html))

Yönetim Paneli Sites Bölümünü Aktifleştirme

Bu kısım biraz bizi uğraştırdığı için sizin de aynı sorunlar ile karşılaşacağınızı düşündüğümüz için ayrı bir yazı olarak yazmaya karar verdik. Yönetim paneline giriş yaparsanız sizi şu şekilde bir pencere karşılaşacaktır.
Burada gördüğünüz gibi Sites bölümü bulunmuyor. Şimdi bu bölümü aktifleştirmeyi göreceğiz. Bu bölümün aktif olmamasının sebebi settings.py dosyasında INSTALLED_APPS kısmında uygulamaları yüklerken bu uygulamayı yüklememiş olmamızdır.
'django.contrib.sites',
Bu ifadeyi ekleyelim ve INSTALLED_APPS demetinin son hali şu şekilde olsun.
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites',
 'yonetim',
)
Bu işlemi yaptıktan sonra Yönetim Paneli'ne Sites bölümünün geldiğini göreceksiniz.
Ama burada siteler bağlantısına tıkladığınızda no such table: django_site şeklinde bir hata alacaksınız. Bunun sebebi ise; veritabanı oluştururken az önce eklediğimiz uygulama projemize ekli olmadığı için uygulamaya ait olan django_site tablosunun oluşturulmamış olmasıdır. Bu sorunu da veritabanını silerek
python manage.py syncdb
komutunu vererek veritabanını tekrardan oluşturmalıyız. Burada tüm verilerin kaybolacağını unutmamalısınız. Djangoda veritabanı işlemleri gerçekten önemli. Artık Sites bölümünden sitemiz ile ilgili ayarları yapabiliriz.
Bu işlemleri yaptıktan sonra settings.py dosyasına şu satırı ekliyoruz.
SITE_ID=1

20 Mart 2014 Perşembe

Yönetim Paneli

Django'nun en güçlü taraflarından biri otomatik gelen yönetim panelidir. Daha önce herhangi bir dil ile web sitesi yaptıysanız kendinize yönetim paneli yazmanız gerektiğini biliyorsunuzdur. Yönetim paneli çoğunlukla veritabanı içerisindeki yazılara,kategorilere, yorumlara müdahale etmek için kullanılan bir paneldir. Açıkçası bir web sitesi yapmanın en can sıkıcı taraflarından biri yönetim paneli yapmaktır. İşte Django bize burada muhteşem bir kolaylık sağlıyor ve yönetim panelini hazır bir şekilde kullanımımıza sunuyor. Yönetim panelinin amacı her zaman aynıdır. Ekstra durumlar pek fazla bulunmaz. Veritabanına müdahale etmek için kullanılır. Django geliştiricileri bu rutin işlemleri bizim için düşünmüşler.
Yeni oluşturduğunuz bir projenin settings.py dosyasını açarsanız şu kısmı göreceksiniz.
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
)
Yönetim(admin) uygulaması projeye dahil edilmiş bir şekilde gelmektedir. urls.py dosyası içerisinde tanımlı bir şekildedir.
from django.conf.urls import patterns, include, url

from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    url(r'^admin/', include(admin.site.urls)),
)
admin uygulaması django.contrib modülünün bir parçasıdır. INSTALLED_APPS değişkenine baktığınız zaman admin uygulamasından başka olarak sessions,messages gibi başka uygulamaları da barındırmaktadır. Tarayıcıda localhost:8000/admin yazdığınızda yönetim paneline ulaşırsınız. İsterseniz değiştirebilirsiniz.
urlpatterns = patterns('',
    url(r'^yonetim/', include(admin.site.urls)),
)
Artık localhost:8000/yonetim diyerek ulaşabiliyoruz. Yönetim panelini açtığınız zaman kullanıcı adını ve şifresini soran bir sayfa ile karşılaşacaksınız. Buradaki kullanıcı adını ve şifreyi daha önce atamıştık. İsterseniz yeni bir proje üzerinden hatırlayalım.
İlk önce Okul adında bir proje oluşturuyoruz.
django-admin.py startproject Okul
Aslında bunları yazmamıza gerek yok ama biz yinede sıradan gidelim. Projemizi oluşturduktan sonra porje içerisinde yonetim uygulamasını oluşturuyoruz.
python manage.py startapp yonetim
Uygulamayı oluşturduktan sonra yonetim/models.py dosyasını açalım ve okul ile ilgili modelimiz oluşturalım.
from django.db import models

class OgretimElemani(models.Model):
 adi = models.CharField(max_length=50)
 soyadi = models.CharField(max_length=50)
 eposta = models.EmailField(blank=True)

 def __unicode__(self):
  return u'%s, %s'%(self.soyadi,self.adi)


class Dersler(models.Model):
 adi = models.CharField(max_length=50)
 ogretim_elemani = models.ForeignKey(OgretimElemani)

 def __unicode__(self):
  return u'%s'%(self.adi)


class Ogrenciler(models.Model):
 adi = models.CharField(max_length=50)
 numarasi = models.CharField(max_length=50)
 dersler = models.ManyToManyField(Dersler)

 def __unicode__(self):
  return u'%s, %s'%(self.adi,self.numarasi)
Modeli oluşturduğumuza göre artık tabloları oluşturabiliriz. Bildiğiniz gibi komut satırına şu komutu yazıyoruz.
python manage.py syncdb

Creating tables ...
Creating table django_admin_log
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_groups
Creating table auth_user_user_permissions
Creating table auth_user
Creating table django_content_type
Creating table django_session
Creating table yonetim_ogretimelemani
Creating table yonetim_dersler
Creating table yonetim_ogrenciler_dersler
Creating table yonetim_ogrenciler

You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): 
Tabloları oluşturduktan sonra bize yetkili bir kullanıcı oluşturmak isteyip istemediğimizi soruyor. Bu soruya yes dedikten sonra username(kullanıcı adı), e-posta(Email address) ve şifre(password) istiyor. Burada kullanıcı adını ve E-posta kısımlarını doldurmak zorunda değilsiniz. Eğer kullanıcı adını doldurmazsanız varsayılan olarak root olacaktır. Şifre kısmını iki kere girmek zorundasınız. Şifreyi de girdikten sonra süper kullanıcı oluşturulur.
python manage.py runserver
komutu ile projeyi server üzerinde çalıştırdıktan sonra tarayıcıya localhost:8000/admin yazarak yönetim paneline ulaşın. Karşınıza şu şekilde bir pencere gelecektir.
Burada oluşturmuş olduğunuz kullanıcı adı ve şifre ile giriş yaparak yönetim paneline girebilirsiniz. Eğer giremiyorsanız süper kullanıcı oluşturduğunuzdan emin olun. Eğer süper kullanıcı oluşturmadıysanız şu komut ile oluşturabilirsiniz.
python manage.py createsuperuser
Giriş yaptıktan sonra kullanıcıları düzenleyebileceğiniz bir sayfa ile karşılaşacaksınız. Fakat bu sayfa İngilizce ilk önce sayfayı Türkçe yapalım. settings.py dosyası içerisindeki LANGUAGE_CODE değişkenini şu hale getirelim.
LANGUAGE_CODE = 'tr-TR'
Artık sayfamız türkçe ama oluşturduğumuz veritabanı ait tabloları göremiyoruz. Bu alanları eklemek zorundayız. İlk önce settings.py içerisindeki INSTALLED APPS değişkenine oluşturduğumuz uygulamayı ekliyoruz.
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
 'yonetim',
)
Ekleme işlemini yaptıktan sonra yonetim uygulaması içerisindeki admin.py dosyasına şu satırları ekliyoruz.
from django.contrib import admin

from yonetim.models import *

admin.site.register(OgretimElemani)
admin.site.register(Dersler)
admin.site.register(Ogrenciler)
Sayfayı yenilediğiniz zaman yonetim uygulaması içeriğinin geldiğini göreceksiniz.
Yönetim paneli bize kullanıcılar,gruplar ve veritabanları üzerinde işlemler yapma olanağı verir.
Django'nun yönetim paneli her uygulama içerisindeki admin.py içerisine bakar ve eklemesi gereken yerleri -veritabanı alanları- gibi kendi içerisine ekler ve kullanıcıya üzerlerinde işlem yapma olanağı verir.
Kaynakça

18 Mart 2014 Salı

Q Nesnesi ve Tam SQL Sorguları

Q Nesnesi
Sorgulamalarda filter() nesnesini kullanırken birden çok argüman gönderebiliyoruz. Bu gönderdiğimiz argümanlar arasına SQL'de and konur.
>>> doktorlar = Doktor.objects.filter(adi='Ahmet',ucret__lt=1500)
Buradaki filtreleme şu şekilde: Adi Ahmet olan ve ücreti en az 1500 olan Doktorları getir. Dikkat ettiyseniz ve kullandık. Yani sorgu şu şekilde.
Select * from Doktor where adi='Ahmet' AND ucret>1500)
Sorguda AND değilde OR kullanmak istiyorsak Q Nesnesini kullanacağız.
>>> from django.db.models import Q
>>> sorgu = Q(ucret=1500) | Q(ucret=2000)
>>> doktorlar = Doktor.objects.filter(sorgu)
>>> doktorlar
[<Doktor: Rıdvan , Durmaz>, <Doktor: Sevgi , Dönmez>]
Buradaki sorgumuz OR ile birleştirildi. Ücreti 1500 veya 2000 olan doktorları istemiş olduk. SQL sorgusu şu şekilde olacak.
Select * from Doktor Where ucret=1500 OR ucret=2000
Bu sorgulamayı Q Nesnesini kullanmadan şu şekilde de yazabildik.
doktorlar = Doktor.objects.filter(ucret=1500) | Doktor.objects.filter(ucret=2000)
Tam SQL Soguları
Bazen sorgulama yaparken Django'nun bize sunduğu Model sorgulamaları işimizi görmeyebilir. Böyle durumda SQL sorgusunu doğrudan yazarak sorgulama yapabiliriz.
>>> for doktor in Doktor.objects.raw('Select * from ucret_Doktor'):
...     print doktor
Ahmet , Mehmet
Rıdvan , Durmaz
Sevgi , Dönmez
Bu şekilde doğrudan SQL sorguları üzerinden çalışabiliriz.
Not: Sorgu içerisindeki ucret_Doktor kısmındaki ucret uygulamanın adını Doktor ise tablonun adını belirtir.
Eğer istersek sorgudan dönen ilk satırı şu şekilde alabiliriz.
>>> doktor = Doktor.objects.raw('Select * from ucret_Doktor')[0]
>>> doktor
<Doktor: Ahmet , Mehmet>
Dışarıdan değer alabileceğimiz bir sorgulama yapalım.
>>> min_ucret=1500
>>> for doktor in Doktor.objects.raw('Select * from ucret_Doktor where ucret>%s' %min_ucret):
...     print doktor
Rıdvan , Durmaz
SQL sorgularını bir Modele bağlı kalmadan doğrudan işletebiliriz.
>>> from django.db import connection
>>> cursor = connection.cursor()
>>> cursor.execute('Select * from ucret_Doktor')
>>> row = cursor.fetchone()
>>> row
(1, u'Ahmet', u'Mehmet', 1000)
Buradaki fetchone() yerine fetchall() kullanarak tüm satırları döndürebiliriz. Burda cursor.executu() ile istediğimiz sorguyu çalıştırabiliriz.
>>> cursor.execute('Insert into ucret_Doktor(adi,soyadi,ucret) values("Selcuk","Inan",3000)')
>>> veri = cursor.execute('select * from ucret_Doktor')
>>> doktorlar = cursor.fetchall()
>>> doktorlar
[(1, u'Ahmet', u'Mehmet', 1000), (2, u'R\u0131dvan', u'Durmaz', 2000), (3, u'Sevgi', u'D\xf6nmez', 1500), (4, u'Selcuk', u'Inan', 3000)]
Gördüğünüz gibi ekleme sorgusu başarı ile çalıştı.
Kaynakça

16 Mart 2014 Pazar

Sorgulama Seçenekleri

Modellerden veri çekerken sorgulama için objects.filter() fonksiyonunu kullanmıştık. Bu bölümde filter() fonksiyonuna ait bazı özelliklerden bahsedeceğiz.
exact
Tam eşleştirme yapar.
>>> doktor = Doktor.objects.filter(adi__exact='Ali')
>>> doktor
[<doktor: ali="" hikmet="" mail.com="">]
Sorgusu ise şu şekilde olacaktır.
Select * from Doktor where adi='Ali';
iexact
Eşleştirme yaparken büyük küçük harf duyarsızlığı vardır.
>>> doktor = Doktor.objects.filter(adi__iexact='ali')
>>> doktor
[<Doktor: Ali , hikmet ,ali@mail.com>]
contains
Kelime grubu içerisinde arama yapar. Eğer kelime içerisinde aranan alt kelime varsa geriye döner.
>>> doktor = Doktor.objects.filter(adi__contains = 'a')
>>> 
>>> dokto
[<Doktor: Ahmet , Mehmet ,doktor@mail.com>, <Doktor: Ali , hikmet ,ali@mail.com>]
Sorgusu;
Select * from Doktor WHERE adi LIKE '%a%';
icontains
Aramayı duyarsız hale çevirir.
in
Aramayı liste içerisinden yapar.
>>> polikilinik = Polikilinik.objects.filter(kodu__in=['P404','P505'])
>>> polikilinik
[<Polikilinik: P404 , Serdivan >, >Polikilinik: P505 , İstanbul >]
gt
Girilen değerden daha büyük değerleri getirir.
>>> doktor = Doktor.objects.filter(id__gt=2)
>>> doktor
[<Doktor: Ali , hikmet ,ali@mail.com>]
idsi 2'den büyük olan doktorları listeledik.
gte
Girilen değere eşit veya daha büyük verileri getirir.
>>> doktor = Doktor.objects.filter(id__gte=2)
>>> doktor
[<Doktor: Veli , Kırmızı ,veri@mail.com>, <Doktor: Ali , hikmet ,ali@mail.com>]
id'si 2 veya daha büyük olan doktorları getirdik
lt ve lte
lt: Daha küçük veriler. lte: Eşit veya daha küçük veriler.
>>> doktor = Doktor.objects.filter(id__lt=2)
>>> doktor
[<Doktor: Ahmet , Mehmet ,doktor@mail.com>]
startswith ve istartswith
startswith: Girilen değer ile başlayan verileri getirir. istartswith: Girilen değer ile başlayan verileri duyarsız bir şekilde getirir.
>>> doktor = Doktor.objects.filter(adi__startswith='A')
>>> doktor
[<Doktor: Ahmet , Mehmet ,doktor@mail.com>, <Doktor: Ali , hikmet ,ali@mail.com>]
endswith ve iendswith
endswith: Girilen değer ile biten verileri getirir. iendswith: Girilen değer ile biten verileri duyarsız bir şekilde getirir.
>>> doktor = Doktor.objects.filter(adi__endswith='A')
>>> doktor
[<Doktor: Ahmet , Mehmet ,doktor@mail.com>, <Doktor: Ali , hikmet ,ali@mail.com>]
range
Girilen aralıktaki değerleri getirir.
import datetime
baslangic = datetime.date(2005, 1, 1)
bitis = datetime.date(2005, 3, 31)
Doktor.objects.filter(giris_tarihi__range=(baslangic, bitis))
Sorgusu
Select * from Where giris_tarihi '2005-01-01' Between '2005-03-31';
year
Yıl sorgulaması yapar.
Doktor.objects.filter(giris_tarihi__year=2013)
month
Yıl sorgulaması yapar.
Doktor.objects.filter(giris_tarihi__month=10)
day
Yıl sorgulaması yapar.
Doktor.objects.filter(giris_tarihi__day=18)
HESAPLAMA FONKSİYONLARI
Sorgulama işlevi yaparken kullanabileceğimiz hesaplama fonksiyonlarına bakalım.
count
Sayma işlemi yapar.
##Doktor sayısını bulalım
>>> doktor_sayisi = Doktor.objects.all().count()
>>> doktor_sayisi
3
Avg
Ortalama hesaplar.
###Doktorların maaş ortalaması
>>> from django.db.models import Avg
>>> ucret_toplami = Doktor.objects.all().aggregate(Avg('ucret'))
>>> ucret_toplami
{'ucret__avg': 1500.0}
Max
En büyüğü bulur.
###En yüksek doktor maaşı
>>> from django.db.models import Max
>>> yuksek_ucret = Doktor.objects.all().aggregate(Max('ucret'))
>>> yuksek_ucret
{'ucret__max': 2000}
Min
En küçüğü bulur.
###En düşük doktor maaşı
>>> from django.db.models import Min
>>> dusuk_maas = Doktor.objects.aggregate(Min('ucret'))
>>> dusuk_maas
{'ucret__min': 1000}
Sum
Toplamı bulur.
###Doktorların toplam maaşı
>>> from django.db.models import Sum
>>> toplam_maas = Doktor.objects.aggregate(Sum('ucret'))
>>> toplam_maas
{'ucret__sum': 4500}
Kaynakça

14 Mart 2014 Cuma

Statik Dosyalar

Eğer daha önceden web sitesi geliştirdiyseniz, projenize statik dosya eklemişsiniz demektir. Statik dosyalar resim,*.pdf,*.txt, gibi dosyalardır. Bunların yanında bizim için son derece önemli olan css dosyaları da statik dosyalardır. Daha önceden yaptığımız hastahane projesi üzerinden gidersek hastahane/settings.py dosyasını açarsanız. Şu şekilde bir satır göreceksiniz.
STATIC_URL = '/static/'
Bu statik dosyaların yerinin static dizini olacağını belirtiyor. Oluşturulan tüm uygulamalar içerisindeki static dizinleri içerisine bakılması için aşağıdaki kod parçasını urls.py içerisine şu kod parçasını ekleyin.
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns += staticfiles_urlpatterns()
Bu kod parçası sayesinde biz tarayıcı da şu şekilde bir adres girdiğimi zaman
http://localhost:8000/static/kim-korkar-linuxtan.pdf
tüm uygulamalar içerisindeki static dizini altında kim-korkar-linuxtan.pdf dosyası aranacaktır. URL'deki static adresini STATIC_URL değişkenine istediğiniz değeri atayarak değiştirebilirsiniz.
Tabi bu şekilde tüm uygulamalar içerisindeki static dizinlerine teker teker bakılması doğru değildir. Tüm statik dosyaların tek bir dizin içerisinde toplanarak istenildiği zaman o dizinden çekilmesi daha doğru olacaktır. Tüm statik dosyaları dosyalar dizini içerisinde toplayalım. Bu dizin projenin ana dizini içerisinde olacaktır. Şimdi Django'nun bu yolu bulabilmesi için settings.py dosyası içerisine şu satırları ekliyoruz.
STATICFILES_DIRS = (
 os.path.join(anadizin,'dosyalar'),
)

STATIC_URL = '/dosyalar/'
Dosyalarımızı artık bu dizinde saklayacağız. STATIC_URL değişkenini de değiştirdik. Yani tarayıcıdan bir dosyaya ulaşmak için
http://localhost:8000/dosyalar/resim.jpg
yazımını kullanmamız gerekiyor.
Şimdi daha önceden yaptığımız Doktor Listesi sayfası içerisine .css dosyası ekleyelim. Yapmamız gereken dosyalar dizini içerisine style.css dosyası oluşturmak ve içerisine şu kodları yazmak.
table {
    border: 1px solid #ddd;
    border-radius: 5px;
}

table td,th,tr {
    padding: 5px;
}

table th {
    background: #234f32;
    color: #fff;
}
Şimdi css dosyamızı doktor_listesi.html dosyasına göstermemiz gerekiyor. Bunun için <head></head> etiketleri arasına şu kodu ekliyoruz.
<link href="/dosyalar/style.css" rel="stylesheet" type="text/css" />
Artık yeni görünümümüzü elde etmiş olduk.
Statik dosyalar sayesinde sitemize css dosyası eklemiş olduk.
Kaynakça

12 Mart 2014 Çarşamba

Modellerin Görünümler ile Kullanılması

Modelleri görünümler ile kullanmanın daha önce yaptıklarımızdan pek bir farkı yoktur. Daha önce bir tablo içerisinden verileri şu şekilde almıştık.
doktorlar = Doktor.objects.all()
İşte bu şekilde aldığımız verileri görünüm(view) içerisinden şablonlara(template) aktaracağız ve kullanıcıya göstereceğiz. İlk önce şablonlarımızı saklayacağımız dizini oluşturalım.
yonetim/sablonlar
Şimdi şablon dizinin yolunu settings.py dosyası içerisine ekleyelim. TEMPLATE_DIRS değişkenine şu satırı ekliyoruz.
TEMPLATE_DIRS = (
os.path.join(anadizin,'yonetim/sablonlar')
)
Buradaki anadizin değişkenini daha önceden tanımlamıştık. İsterseniz bi hatırlayalım.
dizin = os.path.dirname(__file__)
anadizin = os.path.split(dizin)[0]
Oluşturduğumuz yonetim uygulaması içersinden sablonlar dizinini oluşturuyoruz. Şablonlarımız burada saklayacağız. Doktorları listeleyecek bir görünüm hazırlayacağız. yonetim içersindeki views.py dosyasına şu kodları ekliyoruz.
## models dosyasını içe aktarıyoruz
from models import *


def Doktor_listesi(request):
        ## Daha önce kullandığımız Doktor.objects.all() fonksiyonu ile verileri doktorlar değişkenine atıyoruz.
 doktorlar = Doktor.objects.all()
 return render_to_response('doktor_listesi.html',locals())
Şimdi doktor_listesi.html şablonunu oluşturuyoruz. Şablonun yonetim/sablonlar dizininde olmasına dikkat edin.
<!DOCTYPE html>
<html>
<head>
    <title>Doktorlar Listesi</title>
</head>
<body>

<table border="1">
    <tr><th>Sıra</th><th>Adi</th><th>Soyadi</th><th>Telefon</th><th>E-Posta</th></tr>

    {% for doktor in doktorlar %}
    <tr>
        <td>{{ doktor.adi }}</td>
        <td>{{ doktor.soyadi }}</td>
        <td>{{ doktor.telefon }}</td>
        <td>{{ doktor.eposta }}</td>
    </tr>
    {% endfor %}

</table>

</body>
</html>
Geriye sadec url'i eklemek kaldı. hastahane/urls.py dosyasını açarak aşağıdaki kodları ekliyoruz.
##yonetim uygulaması içerisindeki views dosyasını içe aktarıyoruz
import yonetim.views

### url kımsını ekliyoruz.
url(r'^doktorlar/',yonetim.views.Doktor_listesi),
hastahane/urls.py dosyasının son hali şu şekilde olacaktır.
from django.conf.urls import patterns, include, url

from django.contrib import admin
admin.autodiscover()

import yonetim.views

urlpatterns = patterns('',

    url(r'^admin/', include(admin.site.urls)),
 url(r'^doktorlar/',yonetim.views.Doktor_listesi),
)
url'i de eklediğimize göre artık adresimize ulaşabiliriz. Şimdi tarayıcıya
http://localhost:8000/doktorlar/
adresini girelim. Aşağıdaki gibi bir çıktı alacağız.
Modelleri şablonlar ile kullanmak bu kadar basit. Sizde daha farklı uygulamalar yaparak kendinizi deneyebilirsiniz. Kaynakça

9 Mart 2014 Pazar

Django 1.3 sürümünden itibaren Class Based Views (Sınıf Tabanlı görünüm) konsepti gündeme geldi.  Bu şekilde view fonksiyonlarının yerini python objeleri alır.
Specific HTTP metodları ayrı methodlarla belirlenebilir, nesne tabanlıteknikleri (mixins) gibi daha çok kullanılabilir.

Önce Python’da fonksiyon ve method farkını bir örnekle görelim:
class PrintMe(object):
    def __init__(self, astring):
        self.l = astring 
    def print_me(self):
        print(self.l)
Metodu çalıştıralım:
p = PrintMe("po")
p.print_me()
Fonksiyon:
def print_me(l):
    print l
Fonksiyonu çalıştıralım:
print_me("po")
Ve çıktılar:


Django'da bir HTTP GET için , bir view (görünüm) fonksiyonu şu şekilde:
from django.http import HttpResponse

def any_view(request):
    if request.method == 'GET':
        # kodlarınız
        return HttpResponse('any responce')

CBV’de (Class Based Views) ise :
from django.views.generic import View
class AnyView(View):
    def get(self, request):
        # kodlarınız
        return HttpResponse('any responce')
urls.py’da :
from django.conf.urls import patterns
from anyapp.views import AnyView

urlpatterns = patterns('',
    (r'^any/', AnyView.as_view()),
)

CBV’de, get ve post methodları:
Bir CBV’de, get ve post methodunun argumanları, self , request (HttpRequest) ve URLconf’da belirlediğiniz request argumanıdır:
from django.views.generic import View
class ViewClass(View):
    def get(self, request, arg1, keyword=value):
        return method1()
    def post(self, request, arg1, keyword=value):
        return method2()


Kaynakça:
https://docs.djangoproject.com/en/dev/topics/class-based-views/intro/
http://lgiordani.github.io/blog/2013/10/28/digging-up-django-class-based-views-1/
http://programmer.97things.oreilly.com/wiki/index.php/Don't_Repeat_Yourself