Kullanılması gereken bir teknoloji SASS

Web tasarımda çok en önemli bir yere sahip olan CSS’in geliştirilmişi olan bu teknoloji, daha kolay CSS kodu yazmanızı, kodlarınızda değişkenleri kullanabilmenizi, gereksiz CSS kodlarından kaçınmanızı sağlıyor. Bu teknolojiyle stil sayfaları fazla büyümeden kolayca işlem yapabiliyorsun. Kendiniz fonksiyon yazabiliyorsunuz ve bu fonksiyonları kullanabiliyorsunuz.  Bu teknolojiyi kullanmak için öncelikle SCSS standartlarına uygun olarak kodlarınızı yazmanız, ardından Ruby Gems’den birisi olan SASS ile derlemeniz gerekiyor. Derlenince normal CSS’ye dönüşüyor ve böylece kullanabiliyorsunuz.

SASS ile SCSS arasındaki farklardan söz etmek gerekirse SASS noktalı virgül gibi ögeler kaldırılarak daha kolay kullanmanız sağlanıyor. Fakat SASS kullanırken dikkat etmeniz gerekenlerden birisi de girintiler. Derleyici girintilere göre yorumluyor kodunuzu. Yani buna bakarak SASS, Python’dan etkilenmiştir diyebiliriz.

Etkilendikleri arasında CSS, YAML ve HAML bulunuyor. Bu dillerden etkilenen dil 2007 yılında ortaya çıktı. SASS çıktıktan sonra 2 dili etkileyecektir: LESS ve Stylus.

$blue: #3bbfce
$margin: 16px

.content-navigation
  border-color: $blue
  color: darken($blue, 9%)

.border
  padding: $margin/2
  margin:  $margin/2
  border-color: $blue

SCSS şekli de şöyle.

$blue: #3bbfce;
$margin: 16px;

.content-navigation {
  border-color: $blue;
  color:
    darken($blue, 9%);
}

.border {
  padding: $margin / 2;
  margin: $margin / 2;
  border-color: $blue;
}

SASS teknolojisi Ruby yüklü makinelerde kullanılabilir. Ruby Gems ile indirilip kurulduktan sonra derlemek için kullanılabilir. Bu teknolojinin bize en büyük faydası seri ve rahat kod yazmamız olacaktır. Çünkü bir başlık altında kural yazarken “&” ile hover ve benzeri pseudo sınıflarını kontrol edebiliriz. Yani şöyle yapabiliriz.

.makale{
    width: 100%;
    height: 80px;

    &:hover{

       width:65%;        

    }
}

Şeklinde yazdığımız betiğimiz şu şekilde derlenecektir.

.makale{
     width : 100%;
     height : 80px;
}

.makale:hover{
     width : 65%;
}

Sanırım Hint CSS en büyük örneklerden birisi olacaktır. Tamamen SCSS kullanılarak yapılan bu tooltip uygulaması herhangi bir Javascript kodu gerektirmeden çalışır. Hint CSS’ye ulaşmak için tıklayınız.

Kullanabilirseniz kesinlikle kullanmanızı öneriyorum. Hayatta en önemli şeyden yani zamanda tasarruf edip kodlamadan daha çok zevk alabileceksiniz. Daha fazla bilgi için SASS’ın sitesini ziyaret edebilirsiniz!

PDO Prepare Kullanımı, Escape ve Avantajları

Nesne yönelimli olarak veritabanına bağlanabilme yöntemlerini önceki yazılarımızın birisinde anlatmıştık. Veritabanına SQL Injection’dan korunmak amacıyla yapabileceğimiz şeyler eski sistemlerde kısıtlıydı ve gereksiz fonksiyonlar kullanıyorduk. PDO kullanıyorsak bunun iki yolu var: quote ve prepare . Normal deyimler kullanıyorsak eğer PDO::quote kullanmamız daha mantıklı olacaktır. PDO::quote dediğimiz fonksiyon aslında karakterleri bir string verisine dönüştürmemizi sağlayan fonksiyonlardır. Escape etmeden yapılan sorgular güvenlik açıklarına sebep olabilir . Verimizin önüne “\” karakteri koyarak sorguda geçersiz sayılmasını sağlıyoruz.

PHP.Net’e bakarsak bununla ilgili şöyle bir örnek verdiğini görebiliriz:

$string = 'Münasebetsiz \' dizge';
Öncelenmemiş dizge: Münasebetsiz ' dizge
Öncelenmiş dizge: 'Münasebetsiz '' dizge'

Eğer bakarsak ‘Münasabetsiz \’ dizge’ bir adet kesme işareti var. Escape edilmemiş dizgede bu olduğu gibi çıkıyor. Gönderilen verinin string olduğunu bitirmiş oluyor. Yani o kesme işaretinden sonra herhangi bir SQL kodu yazılırsa çalışma ihtimali var.

Hazırlanmamış deyim kullanılıyorsa eğer yapabileceğiniz tek yöntem var: PDO::quote . Veritabanı  sorgusunda kullanacağımız deyim için şu şekilde bir kullanım sergileyebiliriz: Normal veriyi aynı mysql_real_escape_string gibi bir fonksiyon kullanırmışcasına ekleyeceğimiz string’e uyguluyoruz. Yani;

$r = new PDO('mysql:host=localhost;dbname=yeni','root','pass');

$string = 'Merhaba \' dünya!';

echo "Escape edilmemiş: $string\n";
echo "Escape edilmiş:" . $r->quote($string) . "\n";

Çıktılara bakarsak eğer kesme işaretinin normal bir karaktermiş gibi çıktığını göreceğiz.

Escape edilmemiş: Merhaba ' dünya!
Escape edilmiş: 'Merhaba '' dünya!'

Karakterler zararsız hale getirildi. Artık SQL sorgusuna etki etmeyecektir. Ama bakın burada PHP’nin bize ne dediğine?

Bu işlevi SQL deyimlerini oluştururken kullanıyorsanız, kullanıcı girdisini bir SQL deyimi haline getirmek için PDO::quote() yerine PDO::prepare() ile değiştirgeleri ilişkilendirilmiş SQL deyimleri hazırlamanızı hararetle öneririz. Değiştirgelerle ilişkilendirimiş hazır deyimler taşınabilir olmaktan başka daha kullanışlı ve SQL zerkine bağışık olmanın yanında sorgunun derlenmiş hali hem sunucuda hem de istemcide bulunduğundan yorumlanan sorgulardan çok daha hızlıdır.

PDO sürücülerinin hepsi bu yöntemi gerçeklemez. (özellikle PDO_ODBC) Bu bakımdan hazır deyimleri kullanmaya hazır olmalısınız.

Hazır deyimler, PDO’nun bize sağladığı en büyük avantajlardan biridir. Bu avantajların başında PDO::quote’ye göre daha hızlı olan PDO::prepare vardır. SQL sorgusu yer tutucularla yazılır ve prepare ile hazırlanır. Bu yer tutucular isimlendirilmiş veya isimlendirilmemiş olabilir. Yer tutucuların değerlerini dizilerle ayarlarız. 

Hazır deyimleri kullanmak oldukça basittir. 2 adet yer tutucu bulunmaktadır ve bu yer tutucular herhangi bir veri tipi için kullanılabilir. İsimsiz yer tutucu dediğimiz soru işaretleri sorgunun arasında kullanılır. Şu şekilde bir kullanımı vardır SQL deyiminde:

	$kayit_sql = "INSERT INTO $this->tablo ($this->username_sutun, $this->password_sutun, $this->email_sutun, $this->onayli_sutun) values (?,?,?,?)";
	$data = array(
	'kulturlupenguen',
	'sifrenin_hashlanmis_hali',
	'bilmemne@hotmail.com',
	'onayli' );  
	$kayit_sorgusu = $this->baglanti->prepare($kayit_sql);
	// Sorguyu çalıştır.
	$kayit_sorgusu->execute($data);

SQL sorgusunda dikkat ettiyseniz “?” işaretini tırnak içine almadan yazdık. Verilerimizi de $data adında bir dizi oluşturup yazdık. Ardından SQL kodunu hazırladık ( prepare($kayit_sql) ) . Ve execute ile verilerin olduğu diziyi çalıştırıdık. Sorgu veritabanına problemsiz gönderildi. Ve çok daha hızlı gönderildi diğer yöntemlere göre.

İsimli tutucular daha basit anlayabileceğimiz ve başka bir programcının da daha kolay okuyup anlaması için daha yararlı olacaktır. Onun dışında isimsiz yer tutuculardan fazla farkı yok. Onu da şu şekilde kullanabiliriz:

	$kayit_sql = "INSERT INTO $this->tablo ($this->username_sutun, $this->password_sutun, $this->email_sutun, $this->onayli_sutun) values (:nick, :pass, :email, :o nayli)";
	$data = array(
	'nick' => 'kulturlupenguen',
	'pass' => 'sifrenin_hashlanmis_hali',
	'email' => 'bilmemne@hotmail.com',
	'onayli' => 'onayli' );  
	$kayit_sorgusu = $this->baglanti->prepare($kayit_sql);
	// Sorguyu çalıştır.
	$kayit_sorgusu->execute($data);

İsimli tutucular kullanırken dikkat etmemiz gereken tek şey dizimizin anahtarlarının sorguda belirttiğimiz isimde olması. Anahtar dediğimiz şey bir verinin karşısına “=>” işareti çıkmasıdır. Benim tercihim ve önerim isimli tutucu kullanmanız olacaktır.

  • Başlı başına bir SQL Injection koruması sağlar.
  • Nesne yönelimli programlama yaparsınız ki diğer türlerden çok daha basittir.
  • Hazır deyimler kullanarak diğer korunma yöntemlerinden daha hızlı işlem yaparsınız. Bu büyük bir sistem kurmayı hedefleyen biriyseniz, ki büyük sistemlerde mikrosaniyelerin bile önemi vardır, kesinlikle kullanmanız gerekenlerden birisidir.
  • Çoklu sorgu yapıyorsanız PDO::query den daha hızlı olmanızı sağlar.
  • Sürücü sizin için SQL koruması yapar.

  • PHP 4 ile uyumlu değildir. (PHP 4′te OOP yok)
  • Yeni yeni OOP öğrenenler için zor olacaktır.

Eğer hala eski yöntemler kullanıyorsanız, belki değişim iyi gelebilir. Onun dışında performans da düşük ise bu yöntemi denemelisiniz.

WordPress hızlandırmak için ufak etkili detaylar

WordPress kullanıcıların çoğu zaman şikayet ettiği şeylerden birisi de hız problemidir. Bu hız problemi hem sunucuyu yavaşlatır, hem de ziyaretçilere kötü bir deneyim sunar. Örneğin sayfaların geç yüklenmesi, bir yazı yazarken ‘timeout’ olması, aynı anda çok ziyaretçi alınca veritabanı sorunu gibi sorunlar WordPress blog sahiplerini rahatsız etmektedir. WordPress’i hızlandırmak istiyorsak, biraz ‘wp-xxx’ dosyalarının içine girmeli ve kodlarını incelemeliyiz. Çünkü bilmeden yaptığımız her şey blogumuzun göçmesine neden olabilmektedir.

 WP HAFIZA LİMİTİNİZİ ARTTIRIN

WordPress her şeyi düşünmüş ve paylaşımlı sunucular için de kendi hafıza limitini koymuş. Bu hafıza limiti, yani RAM, yapacağımız işlemlerde yetersiz kalmakta ve işlem yavaşlayabilmekte veya hiç çalışmamakta olabilir. Bu hafıza limitini hacklememiz için yapmamız gerekenlerden bahsetmek gerekirse, en iyi yöntem default-constants.php adlı dosyayı bulup içerisini düzenlemek olacaktır. 18. satırda başlayan bu betiği düzenlememiz gerekebilir.

	// set memory limits
	if ( !defined('WP_MEMORY_LIMIT') ) {
		if( is_multisite() ) {
			define('WP_MEMORY_LIMIT', '64M');
		} else {
			define('WP_MEMORY_LIMIT', '40M');
		}
	}

Burada WordPress’in ne kadar hafıza kullanacağını belirten bir tanımlama var. Eğer çoklu-blog ise 64M kullanıyor, değilse de 40M RAM kullanıyor. Ama normalde PHP için ayrılan varsayılan değer 128M’tır. Bu WordPress hack’ı için yapmamız gerekenler bu değerleri sunucumuza ve ihtiyaçlarımıza göre düzenlememizdir.

Veya bu dosyayı düzenlemek yerine wp-config.php dosyamızın uygun bir yerine

define('WP_MEMORY_LIMIT', '256M');

Satırını ekleyebiliriz. Ama eğer yukarıdaki yöntemi yapmıyorsanız ve kullanacağınız RAM miktarı 256M’tan fazla ise gene default-constants.php adlı dosyayı düzenlemeniz gerekecektir. Neden diye sorarsanız, yukarıdaki kod bloğunun hemen altında ise şöyle bir betik var.

	if ( ! defined( 'WP_MAX_MEMORY_LIMIT' ) ) {
		define( 'WP_MAX_MEMORY_LIMIT', '256M' );
	}

Burayı da düzenlemeyeyim, ben wp-config.php ‘den devam edeyim derseniz, şu kodu eklemeniz yeterli.

define( 'WP_MAX_MEMORY_LIMIT', '384M' );

RAM sorununu böyle çözebilirsiniz. Ama kendi aldığınız sunucunun özellikleri de önemlidir.

 Otomatik yazı taslaklarını kapatın

WordPress, yazınını birden fazla sürümünü kaydeder ve bu yazılar, sanki 5-10 yazı varmış gibi veritabanını şişirir. Normalde 300 yazı için 3 MB gibi bir rakam olabilecek veritabanı, 12-15 MB’a kadar çıkabilir. Eğer yazı sürümlerinin ne olduğunu bilmiyorsanız, eski yazılarınızda aşağıya indiğinizde eski yazı sürümlerini görebileceksiniz. İşte onlar POST_REVISIONS olarak isimlendirilen bir sabitle kapatılıp açılabiliyor. Yazı sürümlerini kapatmanız size veritabanından tasarruf sağlayacaktır.

define('WP_POST_REVISIONS', false);

 Yazılarınızı 10 dakikada kaydetmeye ayarlayın

Yazı yazarken WordPress, belli bir süre içerisinde yazınızı kaydeder. Bu yazının kaydedilme süresini ayarlayabilirsiniz. Bir yazı yazarken iki de bir kaydedilmesi pek hoş olmayacağı için bu süreyi arttırabiliriz. Saniye bazında arttırmak için aşağıyı düzenleyebilirsiniz.

define('AUTOSAVE_INTERVAL',600);  // 10 dakikada bir kaydeder

 Gereksiz sorgulardan kurtulun

Gereksiz sorgular derken aklımıza birçok şey geliyor. Sonuçta büyük bir sistem WordPress. Ama kendi yapacağımız temadaki birkaç düzenlemeyle bu sorunu halledebiliriz. Bunların başında, stil ve komut satırlarının çağrılması var. Normal bir temanın üst kısmı şu şekilde olur.

<link rel="stylesheet" type="text/css" media="all" href="<?php bloginfo('stylesheet_url'); ?>" />
<script type="text/javascript" src="<?php bloginfo('template_url');?>/ui/user-interface.js"></script>
<script type="text/javascript" src="<?php bloginfo('template_url');?>/ui/javascript.js"></script>

Eğer dikkat ederseniz, her seferinde bir sorgu çalışıyor ve template_url veritabanından çekiliyor. Ona göre de komut satırları ve stil dosyaları yükleniyor kullanıcıya. Bunu ne yapabiliriz diye sormanız gayet doğaldır. Önerim şu şekilde olandır.

<base href="http://www.kulturlupenguen.com/">

<link rel="stylesheet" type="text/css" media="all" href="wp-content/themes/penguenblog/style.css" />
<script type="text/javascript" src="wp-content/themes/penguenblog/ui/user-interface.js"></script>
<script type="text/javascript" src="wp-content/themes/penguenblog/ui/javascript.js"></script>

base elementi, bir web sitesinde dosyaların aranacağı alan adını tarayıcıya tanıtır. Eğer base kullanmadan yapsaydık, alt sayfalarda problem olacaktı ve stil ve komut dosyaları görünmeyecek, sitenin şaftı kayacaktı. Ayrıca burada 3 tane sorgudan kurtulmuş olduk. Yani 43 adet sorguyla ana sayfamız oluşuyorsa, 40 sorguya indi. Kendi temanız içerisinde bu tür küçük değişiklikler yapmalısınız.

 Kendi silahıyla WP’yi onarın

WordPress hacklerinden bir tanesi de veritabanını onarmadır. MyISAM olan veritabanı tabloları onarılıp, kontrol edilebilir. WordPress’i tamir etmenin yollarından biridir. Ayrıca ‘Bu yazıyı düzenlemeye yetkiniz yok.’ tarzında hatalar alıyorsanız, onararak düzeltebilirsiniz.

 define('WP_ALLOW_REPAIR', true);

Bu kodu wp-config.php dosyanıza ekledikten sonra onarma yapmak için girmeniz gereken adrese girin:

{blog_adresiniz}/wp-admin/maint/repair.php

WordPress veritabanını onarmaTamir et ve iyileştir dediğimizde, iyileştirmenin yapıldığında dair bir çıktı aldıysanız, tamamdır bu iş!

 Herkezin söylediği gibi EKLENTİLER!

Eklentisiz WordPress olmazsa olmazlardandır. Ama eklenti sayısını arttırmaya ve siteyi kasmaya gerek yok. Mesela ‘WordPress SEO by Yoast’ eklentisini kullanıyorsanız, ‘Google XML Sitemap’ eklentisine gerek yok. Yoast bu işi düşünmüş ve bu iş için de bir sitemap indeksi hazırlamış.

Cache eklentilerini kullanmanıza gerek yok. Eğer çok fazla trafik harcamıyorsanız kaldırmalısınız.

 SONUÇ

Yapacağınız işlemleri düşünerek yapmanız, sitenizin her zaman hızlı kalmasını sağlayacaktır. Bunların en başında temalarınız ve yüklediğiniz eklentiler gelmektedir. Bu eklentilerdeki ve temalardaki sorguları yukarıdaki gibi azaltırsanız, daha çok performans elde edersiniz. WordPress hızlandırmak size bağlı olan bir durumdur. Yani ne kadar hakimseniz o kadar hızlı kullanırsınız.

PHP ile Fibonacci sayı Dizisi Yapımı

Fibonacci sayı dizisinin genel mantığı, öncekiyle ondan önceki sayının toplanmasıdır. Yani ilk adımlar 1-1 ise 3. adım 2 olur. Aynı şekilde 4. adım da 5… Şu şekilde gider: 1-1-2-3-5-8-13-21-34-55-89… Bunun PHP’deki hali aslında biraz değişik. Fakat fark ettiğim bir şey var, 5000. adımdan sonra hata vermeye başlıyor ve çıktıyı “inf” olarak veriyor. Fazla uzatmadan kodlara bakabilirsiniz.

<?php
header('Content-type: text/plain');
$number = 10000;
error_reporting(0);
$satirlar = null;

for( $i = 1; $i<= $number; $i++ ) { // Eğer $i, 0 olursa boş değer dönmemesi için konular 0. indise sahip elemanı da çıktılar.
    $satirlar = array();
    $satirlar[] = 0; // Boş değer dönmemesi için konuldu.
    $satirlar[] = 1; // Başlangıç elemanı: 1 1 2 3 5 ...
    for( $j = 0; $j<$i; $j++) 
    {
        if($j) // $j belirtilen koşulu sağlıyorsa işlem yap.
        {
            $satirlar[] = $onceki[$j-1]+$onceki[$j];   
        }
    }

    $onceki = $satirlar; // Önceki elemanlar, aslında $satirlar dizisinin bir kopyası.

    echo number_format($satirlar[$i],0,'.','.')."\n"; // Büyük sayılar için number_format
}
?>

Php Hash Fonksiyonuyla Farklı Algoritmalarda Şifreler oluşturma

PHP’de en bilindik iki şifreleme yöntemi vardır. Bunlardan birincisi md5 ikincisi de sha1′dir. MD5 32 karakterli şifre üretirken, SHA1 40 karakterli şifreler üretir. Genelde veritabanına ilk önce sha1 ile sonra md5 ile şifrelenerek yollanır. Ama ne yazık ki diğer şifreleme algoritmalarının yüzüne bile bakılmamakta. Mesela bunların yanında ripemd160 md4 md2 sha512 sha256 gost whirlpool joaat ve haval algoritmaları bulunmakta. Bunlar farklı uzunlukta şifrelemeler yapıyor. Ama ne yazık ki belki bu algoritmaları bilmeyen kişiler var.

 

Bu algoritmaları nereden biliyorsunuz diye sorarsanız, PHP Info’nun hash kısmına bakmanızı isterim . Sizi yormadan buraya ekleyeyim resmini.

Şifreleme algoritmalarıBunların kullanımı ise şöyle oluyor:

<?php

hash('ALGORİTMA ADI', 'Şifrelenecek Yazı');

?>

Örnek olarak “Şifrelenecek Yazı” yazısını ele alalım ve bütün algoritmalarda şifreleyeyim. Ardından sonuçlara bakalım.

<?php
header('Content-type:text/plain');

$str = "Şifrelenecek Yazı";

$algs = "md2 md4 md5 sha1 sha224 sha256 sha384 sha512 ripemd128 ripemd160 ripemd256 ripemd320 whirlpool tiger128,3 tiger160,3 tiger192,3 tiger128,4 tiger160,4 tiger192,4 snefru snefru256 gost adler32 crc32 crc32b fnv132 fnv164 joaat haval128,3 haval160,3 haval192,3 haval224,3 haval256,3 haval128,4 haval160,4 haval192,4 haval224,4 haval256,4 haval128,5 haval160,5 haval192,5 haval224,5 haval256,5";

$algos = explode(' ', $algs);

foreach( $algos as $algo ) {
    echo $algo . ' => '.hash($algo,$str)."\n";
}

?>

Programı çalıştırdığımızda alacağım sonuç ise gerçekten ilgi çekici.

md2 => 78badc8a958e1fe0b69f7f586d4f0948
md4 => 6282d97aaf4540e82e6f96c6eaf26568
md5 => eb0ab3ae8544141bf42d08113ad7b2b2
sha1 => 8c1d2d9f9a7a1991547531c653294088c38a12b6
sha224 => 6c8ef0b6f9d9fb9305d693ed2dc51c0c1b651bd28a5a9e8bffd8b475
sha256 => b0a9f3fbd301d77c842e3f887df36cc33ba4603007ace35823da7ea1af22977d
sha384 => 6bba7cdb863a705996f5ce05cca28ef40b7181542775e96f2d616c7d054f69dfd489818eb056008b1da0dbdf9932bc93
sha512 => 441d50c3d9b92c183d02f87161839d90eccdde9789eef91173dd658afa051e1325089a192a6be896af06222560b68ad328ec59cccf23731b8209ee8fa5ce8b51
ripemd128 => e91168e68de972d5f7a7c192c2d6c366
ripemd160 => 07a393a57a8b04c46be0c4c2360185c5471578d2
ripemd256 => f5c0e855446f207f00c0d9f764038072e62e0f7b5021de79522bbc780552fed7
ripemd320 => 9eb4b57e92ee4950eb524b9222078751d0baae077621f4f9be85b30dfbee18aa880766f5a3b188e2
whirlpool => b39a7bcd9016610b7c59b521bbd86ccb1fbd2379351f6b9ecfdbe605caf3295039459198aa1e82842797dba55a4b1aec295644c19fcc9513d4606b5796ce8458
tiger128,3 => d71b978c8f90cb2c4c13da21768c8c41
tiger160,3 => d71b978c8f90cb2c4c13da21768c8c41af6837de
tiger192,3 => d71b978c8f90cb2c4c13da21768c8c41af6837de902f4023
tiger128,4 => 582d41fcb9a9ad1d26369fa436b884fb
tiger160,4 => 582d41fcb9a9ad1d26369fa436b884fb58d8e247
tiger192,4 => 582d41fcb9a9ad1d26369fa436b884fb58d8e24787c779e8
snefru => c8777ad975e8eefd96e44fb32f735ec573f532099a31beb6dbe8b22a58f0ec2a
snefru256 => c8777ad975e8eefd96e44fb32f735ec573f532099a31beb6dbe8b22a58f0ec2a
gost => 06ade855a9037a590552a74a9adc4c05e4bc2306d624a25bc174bf0a5dd1301b
adler32 => 577708aa
crc32 => d69cf583
crc32b => ea7a205e
fnv132 => 5ef7775e
fnv164 => 37fa648f8d80663e
joaat => ba3f7c8a
haval128,3 => 08812acb9d114f5bd38b12b8841c16ad
haval160,3 => 506398f08b1cb6172b655637e518247f9a608ed3
haval192,3 => 6840d4131733869ae6720bbe059918158dd3ab918f926f8f
haval224,3 => b9dd3713e6d124071b2505acadef26a9be7ba25186b94081ce1e0e0b
haval256,3 => 2f19d9b5c48ff97775c2f2aae5a1d4be8aaf39ce31a3c474a28d61b47eb8e5c2
haval128,4 => 5c86d3d43aaa3eb9b2b6c16ed8f84967
haval160,4 => e0cd6455da966ed2cae72c7e87ed125bd95d6152
haval192,4 => c559a1e13599a3bb157c4d2df8d22116897fdf59e62c270e
haval224,4 => 08547816b286d4716f81a7953f3dca092701420f91c90248436d838e
haval256,4 => 0aa5f52d00820aaf048661883ab77ed5d12c4dfcf5b399abd8c3f6c26e51ec12
haval128,5 => 2a95f04bb44117856c0b1d71f50fb6b2
haval160,5 => a7859dea99c32995ff4e25b93e1a7dafe19e5139
haval192,5 => 2ed77304ad660d8d4d7990b0d593168c6beaf15237386530
haval224,5 => a0414a7c97b4e72a72f0c9eae255834320b6c585313444bf4fb70263
haval256,5 => 47df27912c2d1b69fb945744d3e210d8cdb2e59c74795a03388d1e6453c3cfbd

Sadece md5 ve sha1 ile kalmayıp, diğer algoritmaları da kullanırsak hem şifrelememiz her hacker tarafından fark edilmez, hem de kolay kolay bulunmaz. Ben şu an sha256 ve sha512 kullanıyorum. sha256 ile 64 karakterli salt elde ederken sha512 ile 128 karakterli elde ediyorum. Veritabanım büyümesin diyorsanız sha256 veya haval256,4, yer önemli değil diyorsanız sha512 öneriyorum. Tabi size kalmış bir tercih meselesi.

PHP ile Hex Renk Kodlarını RGB Biçimine Dönüştürme

Renklerin HEX kodlarını RGB biçimine çevirmek için HEX kodunu çevirmemiz gerekiyor. HEX kodlarına biraz bakarsak aslında 16 tabanlı sayılardır. Bu 16 tabanlı sayıları PHP’de hexdec ve dechex fonksiyonları ile işliyoruz. Genelde renkler için hex kodları 6 karakterli oluyor. Basamaklar için yapmamız gereken işlemde substr kullanıyoruz. Kısacası RGB, yani ‘red’ ‘green’ ‘blue’ olduğu için 2′şerli olarak alıp, 16 tabanlı sayıyı 10 tabanlı sayıya çevirmemiz gerekiyor. Mantık oldukça basit olmakla beraber oldukça doğru sonuçlar vermekte.

function hex2rgb($hex)
    {
        if( strlen($hex) > 6 )
        {
            $hex = str_replace('#','',$hex);
            $r = hexdec(substr($hex,0,2));
            $g = hexdec(substr($hex,2,2));
            $b = hexdec(substr($hex,4,2));      

            return array(
                'RED' => $r,
                'GREEN' => $g,
                'BLUE' => $b
            );
        } else {
            return false;
        }
    }

Fonksiyonumuz hazır. Şu şekilde kullanabiliriz.

hex2rgb('#FF0000');

Geriye dizi döndürdüğü için dizi elemanları şöyle olacaktır.

'RED' => 255
'GREEN' => 0
'BLUE' => 0

Django İlk Uygulamamızı Yazıyoruz – 3

Geçen yazımızda modellerimizi oluşturup Django ile mikroblogumuzu yapmıştık. Bir adet yazı eklemiştik ve başarılı şekilde çalıştırmıştık. Şimdi ise Django’nun gelişmiş yönetim panelinden bahsetmek istiyorum. Bu yönetim paneline istediğimiz şekilde müdahale edebiliriz. Genelde yaptığımız uygulamalar için bir dosya oluşturup o dosyadan müdahale ediyoruz. Şöyle de denilebilir bir çeşit hook sistemi var. Yazdığımz uygulamaya göre şekilleniyor. Bu şekillendirmeleri uygulamanın dizininde admin.py adında bir dosya oluşturarak yapabiliyoruz.

Dosyayı oluşturduğumuzda aşağıdakileri yazıyoruz.

from django.contrib import admin
from .models import Mikro

class MikroAdmin(admin.ModelAdmin):
    date_hierarchy = 'yayinlanma_tarihi'
    fields = ('yayinlanmis','baslik','slug','icerik','yazar')
    list_display = ('baslik','yayinlanma_tarihi','yayinlanmis')
    list_display_links = ['baslik']
    list_filter = ['yayinlanmis','guncelleme_tarihi','yazar']

    prepopulated_fields = { 'slug' : ('baslik',) } 
    search_fields = ['baslik','icerik']

admin.site.register(Mikro, MikroAdmin)

Mikro modelini, MikroAdmin sınıfıyla yönetici paneline kayıt etmiş bulunduk. “list_display”e baktığımızda yazıların listeleneceği bölümde yayınlanma durumunu, tarihini ve başlığını göstereceğini belirttik. Bir de arama bölümü oluşturduk ki başlığa ve içeriğe göre arama yapabiliyor. Birkaç tane de filter oluşturduk. Bunlar yayınlanan yazılar, güncelleme tarihi en yüksek olan yazılar ve yazar ismine göre. Şimdi sunucunuzu çalıştırın ve yönetim paneline girin. Mikros seçeneğine tıklayın.

Gördüğünüz üzere bazı yerle Türkçeleştirme gerektiriyor. models.py dosyanızı açın ve burada Mikro modeline şunları ekleyin.

def yayinlanmis_admin(self):
        if self.yayinlanmis:
            return True
        else:
            return False

    def baslik_admin(self):
        return self.baslik

    def yayinlanma_admin(self):
        return self.yayinlanma_tarihi

    # Admin paneli için tasarım özelleştirmeleri

    yayinlanmis_admin.admin_order_field = 'yayinlanmis'
    yayinlanmis_admin.short_description = 'Yayınlanmış'
    yayinlanmis_admin.boolean = True

    baslik_admin.admin_order_field = 'baslik'
    baslik_admin.short_description = 'Yazı Başlığı'

    yayinlanma_admin.admin_order_field = 'yayinlanma_tarihi'
    yayinlanma_admin.short_description = 'Yayınlanma Tarihi'

Ekledikten sonra models.py dosyanız şu şekilde olmalıdır.

#-*- coding:utf-8 -*-
from django.db import models

# Create your models here.

from django.contrib.auth.models import User
from django.template.defaultfilters import slugify

class MikroManager(models.Manager):
    def live(self):
        return self.model.objects.filter(yayinlanmis=True)

class Mikro(models.Model):
    yayinlanma_tarihi = models.DateTimeField(auto_now_add=True, editable=False)
    guncelleme_tarihi = models.DateTimeField(auto_now=True, editable=False)
    baslik = models.CharField(max_length=255)
    slug = models.SlugField(max_length=255, blank=True, default='')
    icerik = models.TextField()

    yayinlanmis = models.BooleanField(default=True)
    yazar = models.ForeignKey(User, related_name='yazilar')
    objects = MikroManager()

    class Meta:
        ordering = ['-yayinlanma_tarihi','baslik']

    def __unicode__(self):
        return self.baslik

    def yayinlanmis_admin(self):
        if self.yayinlanmis:
            return True
        else:
            return False

    def baslik_admin(self):
        return self.baslik

    def yayinlanma_admin(self):
        return self.yayinlanma_tarihi

    # Admin paneli için tasarım özelleştirmeleri

    yayinlanmis_admin.admin_order_field = 'yayinlanmis'
    yayinlanmis_admin.short_description = 'Yayınlanmış'
    yayinlanmis_admin.boolean = True

    baslik_admin.admin_order_field = 'baslik'
    baslik_admin.short_description = 'Yazı Başlığı'

    yayinlanma_admin.admin_order_field = 'yayinlanma_tarihi'
    yayinlanma_admin.short_description = 'Yayınlanma Tarihi'

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.baslik)
        super(Mikro, self).save(*args, **kwargs)

    @models.permalink
    def get_absolute_url(self):
        return ('mikro:detail',(),{'slug':self.slug})

Burası tamam olduğuna göre admin.py dosyasını yeniden düzenlememiz gerekiyor. Aşağıdaki kodları dosyaya aynen yapıştırırsanız sorun yaşamazsınız.

from django.contrib import admin
from .models import Mikro

class MikroAdmin(admin.ModelAdmin):
    date_hierarchy = 'yayinlanma_tarihi'
    fields = ('yayinlanmis','baslik','slug','icerik','yazar')
    list_display = ('baslik_admin','yayinlanma_admin','yayinlanmis_admin')
    list_display_links = ['baslik_admin']
    list_filter = ['yayinlanmis','guncelleme_tarihi','yazar']

    prepopulated_fields = { 'slug' : ('baslik',) } 
    search_fields = ['baslik_admin','icerik']

admin.site.register(Mikro, MikroAdmin)

Bu da tamam olduğuna göre yönetim panelini tekrar açabiliriz. Şimdiki görüntü şuna benzer olacaktır.

Ama o da ne? Nesnelerimiz “mikro” olarak geçiyor. Hatta aşağıda da “2 mikros” yazıyor :) Bunu düzeltmek için models.py dosyamızı açıp, Mikro sınıfının içerisinde bir alt sınıf olan Meta’da düzenleme yapmamız gerekiyor.

    class Meta:
        ordering = ['-yayinlanma_tarihi','baslik']
        verbose_name = 'Mikro Blog'
        verbose_name_plural = 'Mikro Blog'

verbose_name ve verbose_name_plural ile bu sorunun üstesinden gelebiliriz.

Şu anlık bu kadar! Yazılarınızı düzenleyebilirsiniz ve yeni yazılar ekleyebilirsiniz. Filtrelerden geçirebilirsiniz. Diğer yazımızda yan menüdeki filtre isimlerinin değiştirilmesinden ve yazı düzenleme kısmının düzenlenmesinden bahsedeceğiz.

Django İlk Uygulamamızı Yazıyoruz – 2

Yönetim panelini etkinleştirmiştik. Şimdi küçük bir mikroblog uygulaması yapalım. Bu uygulamada eğer “The Social Network” filmini izlediyseniz, Mark’ın mikroblogu gibi bir şey yapacağız. Twitter’a benzer olan bu mikroblogda yapacağımız şey belli bir karakter limiti ile yazılar yazmak ve onları SEF Url’ler ile göstermek olacak. Şimdi projemizin dizinine geliyoruz. manage.py dosyasını görmeniz lazım. Öncelikle bir adet uygulama oluşturmamız gerek. Uygulama ve projeler arasındaki farka bakarsak uygulama projenin içinde olur ve bir işlem yapar, örneğin bloglar gibi. Ama proje bu uygulamaların bütünüdür. Mesela büyük bir teknoloji sitesi açtınız. Projenize forum ve blog da eklemek istiyorsunuz. İşte asıl site, forum ve blog bu projeye dahildir ama bu uygulamalar birer proje değildir.

Hemen şu komutu çalıştırarak bir adet uygulama oluşturalım:

python manage.py startapp mikroblog

Bu komuttan sonra projenizin dizininde “mikroblog” adında bir klasör oluşacaktır. Bu klasörün içeriğinde şu dosyaları görmeniz gerekiyor.

  • __init__.py
  • models.py
  • views.py
  • tests.py

Bu dosyaları gördüyseniz projenizi başarıyla oluşturdunuz. Şimdi models.py dosyasına girip aşağıdaki kodları yazın.

#-*- coding:utf-8 -*-
from django.db import models

# Create your models here.

from django.contrib.auth.models import User
from django.template.defaultfilters import slugify

class MikroManager(models.Manager):
    def live(self):
        return self.model.objects.filter(yayinlanmis=True)

class Mikro(models.Model):
    yayinlanma_tarihi = models.DateTimeField(auto_now_add=True, editable=False)
    guncelleme_tarihi = models.DateTimeField(auto_now=True, editable=False)
    baslik = models.CharField(max_length=255)
    slug = models.SlugField(max_length=255, blank=True, default='')
    icerik = models.TextField()

    yayinlanmis = models.BooleanField(default=True)
    yazar = models.ForeignKey(User, related_name='yazilar')
    objects = MikroManager()

    class Meta:
        ordering = ['-yayinlanma_tarihi','baslik'] # en yeniler her zaman üstte olacak

    def __unicode__(self):
        return self.baslik

    def save(self, *args, **kwargs):
        if not self.slug: #slug yoksa başlığı sluga çevirerek kullan
            self.slug = slugify(self.baslik)
        super(Mikro, self).save(*args, **kwargs)

    @models.permalink
    def get_absolute_url(self):
        return ('mikro:detail',(),{'slug':self.slug})

Modelimizi oluşturduk şimdi projemizin ana dosyasına girelim yani ilkProjem dizinine. INSTALLED_APPS değişkenine değer eklememiz gerekiyor. Şu şekilde yapmanız gerekiyor.

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Uncomment the next line to enable the admin:
    'django.contrib.admin',
    # Uncomment the next line to enable admin documentation:
    'django.contrib.admindocs',
    'mikroblog',
)

Bunu yaptıktan sonra manage.py dosyasını çalıştıracağız. Şu komutla tekrar çalıştırın.

python manage.py sql mikroblog

Komut satırında şöyle bir SQL komutu gördüyseniz uygulama kurulmuş demektir:

BEGIN;
CREATE TABLE `mikroblog_mikro` (
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
    `yayinlanma_tarihi` datetime NOT NULL,
    `guncelleme_tarihi` datetime NOT NULL,
    `baslik` varchar(255) NOT NULL,
    `slug` varchar(255) NOT NULL,
    `icerik` longtext NOT NULL,
    `yayinlanmis` bool NOT NULL,
    `yazar_id` integer NOT NULL
)
;
ALTER TABLE `mikroblog_mikro` ADD CONSTRAINT `yazar_id_refs_id_2c2ad8b2` FOREIGN
 KEY (`yazar_id`) REFERENCES `auth_user` (`id`);

COMMIT;

Son bir kere daha syncdb komutunu çalıştırıyoruz.

python manage.py syncdb

Şimdi biraz oynayalım. “manage.py” dosyasını gene çalıştırıp interaktif kabuğa gireceğiz.

python manage.py shell

Aşağıdakileri teker teker girin.

Python 2.7.5 (default, May 15 2013, 22:44:16) [MSC v.1500 64 bit (AMD64)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from mikroblog.models import Mikro
>>> from django.utils import timezone
>>> from django.contrib.auth.models import User
>>> yazar = User.objects.get(id=1)
>>> yazi = u'Şu an bunu okuyorsanız başarıyla kurdunuz demektir :) '
>>> tarih = timezone.now()
>>> baslik = u'Düşünme, yap!'
>>> n = Mikro(yayinlanma_tarihi=tarih, baslik=baslik, icerik=yazi, yayinlanmis=T
rue, yazar=yazar)
>>> n.save()
>>> Mikro.objects.all()
[<Mikro: D├╝┼ş├╝nme, yap!>]
>>> Mikro.objects.get(pk=1)
<Mikro: D├╝┼ş├╝nme, yap!>

Şimdi bir adet yazı oluşturmuş durumdayız. Veritabanımıza baktığımızda konsoldaki gibi Türkçe karakter problemi olmadan kayıt edildiğini görebiliriz.

Template Sistemi ve Yazıyı Gösterme

Gene projemizin settings.py dosyasını (ilkProjem/settings.py) açıp bir değişkeni daha düzenleyeceğiz. Bu değişken template dosyalarının barındığı klasör ismini depo ediyor. Şöyle değiştirin:

import os
import os.path
BASE_DIR = os.path.dirname(os.path.abspath(__file__))

TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'templates')]

Ardından aynı dizin içerisine bir “templates” dizini oluşturun. Onun içine de “mikroblog” dizini açın. Ardından article.html diye bir dosya oluşturun. Şimdilik bu işimiz bitti.

urls.py dosyası oluşturun

Bir urls.py dosyası oluşturun ama “mikroblog” dizini içerisinde olsun. O dosyayı açın ve şöyle düzenleyin.

from django.conf.urls import patterns, url
from . import views

urlpatterns = patterns('',
    url(r'^$', views.YaziListView.as_view(), name='list'),
    url(r'^(?P<slug>[\w-]+)/$', views.YaziDetailView.as_view(), name='detail'),
)

Bunu şimdi asıl URL ayarlarına eklememiz gerekiyor. Kökteki urls.py dosyasını açın ve şu şekilde düzenleyin.

from django.conf.urls import patterns, include, url

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    # Examples:
    # url(r'^$', 'ilkProjem.views.home', name='home'),
    # url(r'^ilkProjem/', include('ilkProjem.foo.urls')),

    # Uncomment the admin/doc line below to enable admin documentation:
    url(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    url(r'^admin/', include(admin.site.urls)),
    url(r'^blog/', include('mikroblog.urls')), # işte uygulamamız bu url'den erişiliyor
)

Uygulamamız yavaş yavaş şekillenmeye başladı. Şimdi templates dizinine girin ve önceden oluşturduğumuz mikro_list.html dosyasını açın içerisine şu kodları girin. Tam bir tasarım değil ama bilgiyi şu anlık görebilmemiz için gerekli. Bu bizim yazdığımız yazıların gösterileceği sayfa. Yani anasayfa akışı da diyebiliriz.

{% load url from future %}
<h1>Yazılar</h1>

{% for mikro in object_list %}
    <li><a href="{% url 'detail' mikro.slug %}">{{ mikro.yayinlanma_tarihi|date }} - {{ mikro.baslik }}</a></li>
{% empty %}
    <li>Daha yazı yazılmamış. Lütfen yönetici panelinizden yazı yazın!.</li>
{% endfor %}

Bu süslü parantezler arasına istediğimiz çoğu şeyi yazabiliyoruz. Değişkenler, if ve while sorguları… İşte Django’yu sevmek için ayrı bir neden daha! Şimdi mikroblog klasöründeki views.py’yi açın ve aynen kopyalayın.

# Create your views here.

from django.views.generic import ListView, DetailView
from models import Mikro

class YayinlanmisYazilar(object):
    def get_queryset(self):
        return self.model.objects.live()

class YaziListView(YayinlanmisYazilar, ListView):
    model = Mikro

    def get_context_data(self, **kwargs):
        context = super(YaziListView, self).get_context_data(**kwargs)
        return context

Şimdi yazımızın detaylı olarak gösterileceği kısma girelim. mikro_list.html‘in bulunduğu dizinde bir de mikro_detail.html dosyası açın ve aşağıdakini içine yapıştırın.

{% load url from future %}
<h1>{{ object.baslik }}</h1>

<p>{{ object.icerik|linebreaks }}</p>

<strong>{{ object.yazar }} bu yazıyı {{object.yayinlanma_tarihi}} tarihinde yazdı.</strong>

<p>
<a href="{% url 'list' %}">Anasayfa</a>
</p>

Burada dikkat çekmek istediğim bir noktada var. anasayfa kısmına bakarsak, a elementinin href değeri “{% url ‘list’ %}” olarak ayarlanmış. Şimdi yukarıya çıkın ve mikroblog dizini içerisindeki urls.py’yi açın. Orada name=’list’ gözüne çarpacaktır. İşte anasayfanın URL’sini yazmış bulunuyoruz.

Tabi bu HTML Template’i render etmemiz için views.py’yi açıp sonuna şu sınıfı da eklemek gerekli.

class YaziDetailView(YayinlanmisYazilar, DetailView):
    model = Mikro

    def get_context_data(self, **kwargs):
        context = super(YaziDetailView, self).get_context_data(**kwargs)
        return context

Her şey tamam olduğuna göre Python Shell’ini açıp bir adet yazı ekleyelim. ilkProjem dizinindeyken şu komutu çalıştırıp…

python manage.py shell

… ardından şunları girmeniz yeterli:

Python 2.7.5 (default, May 15 2013, 22:44:16) [MSC v.1500 64 bit (AMD64)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from mikroblog.models import Mikro
>>> from django.utils import timezone
>>> from django.contrib.auth.models import User
>>> yazar = User.objects.get(id=1)
>>> yazi = u'Şu an bunu okuyorsanız başarıyla kurdunuz demektir :) '
>>> tarih = timezone.now()
>>> baslik = u'Düşünme, yap!'
>>> n = Mikro(yayinlanma_tarihi=tarih, baslik=baslik, icerik=yazi, yayinlanmis=T
rue, yazar=yazar)
>>> n.save()
>>> Mikro.objects.all()
[<Mikro: D├╝┼ş├╝nme, yap!>]
>>> Mikro.objects.get(pk=1)
<Mikro: D├╝┼ş├╝nme, yap!>

Girdikten sonra sunucumuzu çalıştırıyoruz (manage.py ile çalıştırabilirsiniz). Ardından aşağıdaki adrese giriyoruz:

http://127.0.0.1:8000/blog

İşte tamam!

Yazılar sayfası

Şimdi “Düşünme, yap!” başlığına tıklayıp yazdığımız yazıya bakalım.

Yazı içeriği

Sorun yok gibi gözüküyor. Ama hala eksiği bitmedi. Şimdilik bu kadar ama sonraki yazıyı da şiddetle okumanızı tavsiye ediyorum. Çünkü Django Admin Paneli entegresini yapacağız. Oradan yazı ekleyip silebileceğiz, yazıyı düzenleyebileceğiz ve yayınlanma durumunu kontrol edebileceğiz.

Django “Merhaba Dünya” Uygulaması ve Ayarlar

Önceki yazımızda Django’yu Windows 8 bilgisayarımıza kurmuştuk ve çalıştığına dair bir ekran çıktısı almıştık. Şimdi ise Django’muzu kullanmaya başlayabiliriz. İlk olarak ayarlarımızı yapacağız. Ayarlarımızı yaptıktan sonra fonksiyon sistemine geçeceğiz. Ardından URL’leri düzenleyeceğiz ve aynı PHP’deki gibi URL’den GET metoduyla bilgi alacağız. Bunun üzerine mesela blog sisteminde olduğu gibi URL’den aldığımız veriyi işleyeceğiz. Şimdi başlayalım. Öncelikle projemizin içerisinden settings.py dosyasını bulalım. Bu dosya şuna benzer olacaktır.

# Django settings for ilkProjem project.

DEBUG = True
TEMPLATE_DEBUG = DEBUG

ADMINS = (
    # ('Your Name', 'your_email@example.com'),
)

MANAGERS = ADMINS

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': '',                      # Or path to database file if using sqlite3.
        # The following settings are not used with sqlite3:
        'USER': '',
        'PASSWORD': '',
        'HOST': '',                      # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
        'PORT': '',                      # Set to empty string for default.
    }
}

# Hosts/domain names that are valid for this site; required if DEBUG is False
# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
ALLOWED_HOSTS = []

# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# In a Windows environment this must be set to your system time zone.
TIME_ZONE = 'America/Chicago'

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'

SITE_ID = 1

# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True

# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale.
USE_L10N = True

# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = True

# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/var/www/example.com/media/"
MEDIA_ROOT = ''

# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://example.com/media/", "http://media.example.com/"
MEDIA_URL = ''

# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/var/www/example.com/static/"
STATIC_ROOT = ''

# URL prefix for static files.
# Example: "http://example.com/static/", "http://static.example.com/"
STATIC_URL = '/static/'

# Additional locations of static files
STATICFILES_DIRS = (
    # Put strings here, like "/home/html/static" or "C:/www/django/static".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
)

# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
#    'django.contrib.staticfiles.finders.DefaultStorageFinder',
)

# Make this unique, and don't share it with anybody.
SECRET_KEY = 'ta=bk-$^8!x)+x*10zjf=q^stg19h%%&ub5#vv3rwk7&ryl3^z'

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
#     'django.template.loaders.eggs.Loader',
)

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    # Uncomment the next line for simple clickjacking protection:
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

ROOT_URLCONF = 'ilkProjem.urls'

# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'ilkProjem.wsgi.application'

TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
)

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Uncomment the next line to enable the admin:
    #'django.contrib.admin',
    # Uncomment the next line to enable admin documentation:
    #'django.contrib.admindocs',
)

# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error when DEBUG=False.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        }
    },
    'loggers': {
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
    }
}

Böyle bir dosyamız olacak. Bu dosyamızın birkaç bölümünü değiştirmeliyiz. Öncelikle saat kısmını düzeltelim.

TIME_ZONE = 'America/Chicago'

Bunu kendi zaman dilimimize ayarlayalım.

TIME_ZONE = 'Europe/Istanbul'

Bunu ayarladıktan sonra dili ayarlamamız lazım. LANGUAGE_CODE değişkenini tr-TR olarak değiştirmemiz gerekiyor.

LANGUAGE_CODE = 'tr-TR'

Basit ayarlamalarımız bunlar. settings.py dosyasını dikkatli şekilde okuyarak diğer ayarları siz yapabilirsiniz. Ama en temel ayarlar bunlardır.

Merhaba Dünya

Her şey ‘Merhaba Dünya!’ ile başlamış olabilir aslında. Belki Adem ve Havva da cennetten dünyaya geldiklerinde de bu söz öbeğini kullanmış olabilirler.Kim bilir!

İlk merhaba dünya uygulamamız için öncelikle views.py dosyamızı açmalıyız. Bu dosya istekleri işliyor. Fonksiyonlarımızı buraya yazarak işimizi hallediyoruz.  Eğer dosya yoksa oluşturun :)

İlk fonksiyonumuzu yazmaya hazırsak hemen yazalım.

Bu dosya views.py dosyası olacak.

#-*- coding: utf-8 -*-
from django.http import *

def MerhabaDunya(request):
    merhaba = '<strong style="color:red">Merhaba</strong> dünya! <br>'
    user = 'Kullandığınız tarayıcının gönderdiği User-Agent:<br>%s'% request.META['HTTP_USER_AGENT']

    return HttpResponse(merhaba+user)

Şimdi urls.py dosyamızı açıyoruz. Bu kısım önemli özellikle ‘Merhaba Dünya’mızı görmek istiyorsak. urls.py’yi açıp kopyalayın.

from django.conf.urls import patterns, include, url
# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()

import views

urlpatterns = patterns('',
    # Examples:
    url(r'^$', 'ilkProjem.views.home', name='home'),
    #url(r'^ilkProjem/', include('ilkProjem.foo.urls')),

    # Uncomment the admin/doc line below to enable admin documentation:
    #url(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    #url(r'^admin/', include(admin.site.urls)),

    url(r'^merhaba-dunya/$', views.MerhabaDunya)
)

Gördüğünüz gibi daha demin yazdığımız views.py’yi import ettik ve patterns’e bir adet eleman ekledik. Elemanımızda url fonksiyonunu kullandık ve yapılacak işlem için views.MerhabaDunya fonksiyonunu kullandık ki bu fonksiyonu önceden yazdığımız fonksiyondu. Artık http://127.0.0.1:8000/merhaba-dunya/ adresine girerek uygulamamıza bakabiliriz.

ve Django ile 'Merhaba Dünya' diyoruzUser-Agent değerini de request.META[‘HTTP_USER_AGENT’] ile halletmiş olduk. Sonunda Django ile de dünyaya bir ‘Merhaba!’ dedik!

Djangoya giriş ve windows kurulumu

Temmuz ayının sıcak günlerinde beynimin pişmesiyle beraber laflarımın çoğunu Python ve Django oluşturmaya başladı. Django demeye başlayınca çevrem “Django da ne yaaaaa” demeye başladı. Django’yu Google’da olduğu gibi aratırsanız film adı çıkıyor. Ama bu değil. Django’nun ne olduğunu, bize neler getirdiğini, avantajlarını ve en önemlisi nasıl kurulacağını anlatacağım. Eğer bir terslik de çıkmazsa Django ile ilgili yazılarımı yazacağım ve püf noktalarını anlatacağım. Django için en genel tanım bir web framework’udur.

Django Web Framework

Django bir web framework’üdür ve Python dili ile yazılmıştır. Açık kaynak olarak dağıtılmaktadır ve geliştirilmektedir. Python altyapısını kullanır. MVC yapısını kullanır.

Kendine özgü template sistemiyle dinamik sitelerinizi rahatlıkla oluşturabilirsiniz. Oldukça gelişmiş bir URL yapısı vardır ki 5 dakikada sadece urls.py dosyasını düzenleyerek SEF linkler yaratabilirsiniz. Ayrıca hem sunucuyla etkileşim, hem de web yazılımı yapmak istiyorsanız gayet etkili bir yapısı var. Python’ın masaüstü yazılım gücüyle Django’nun webdeki gücünü birleştirerek oldukça güzel uygulamalar yapılabilir.

Ayrıca hızlı çalışır ve kaynak sıkıntısı çekmezsiniz. Az kaynağa sahip sunucularda bile gayet performanslı çalışır.

İlk olarak Django’nun son sürümünü indirmemiz gerekiyor. Django’yu bu sayfadan indirdikten sonra Python kurmamız gerek. Django’yu indirdiyseniz, arşiv dosyasını ben C: klasörüne açtım. İstediğiniz bir yere açın. Şimdi Python kurmamız gerekiyor. Python’ın 3.x.x sürümlerine tam olarak hakim olamadığım için ben 2.x.x sürümlerini indiriyorum. Bu sayfadan Python’ı indirdikten sonra ortam değişkenlerinden ‘Path’ değişkenine Python yolunu eklememiz gerekiyor.

Python’ı ben C:\Python27 klasörüne kurdum. Sürümüm 2.7 olduğu için böyle bir ad aldı. Şimdi komut satırından ‘python’ı çalıştırmak için ortam değişkenlerini düzenlememiz gerekiyor.

Python CMD

Gördüğümüz gibi ‘python’ yazınca uygulamayı çalıştıramıyoruz. Çalıştırmak için ortam değişkenlerini düzenlememiz gerek. Windows 8 kullanırken aramadan ‘ortam değişkenleri’ diye aratırsanız, 2 adet sonuç alırsınız. Siz sistem ortam değişkenlerini düzenleyeceksiniz. Şimdi ‘Path’ isimli değişkeni seçin ve düzenleye tıklayın. Ardından Python’ı nereye kurduysanız o klasörün yolunu belirtmemiz gerekecek yani şöyle.

Python PathKaydettikten sonra konsolda ‘python’ yazıp çalıştırabiliriz.

Düzgün şekilde çalışıyorŞimsi Django’yu çıkarttığımız dizine gidip Django’yu kurabiliriz. Django’yu indirmiştik ve bir dizine açmıştık. Ben Django’yu C:\Django-1.5.1 dizinine kurdum. Şimdi o dizinin içine cd komutu ile giriyorum. Ardından şu komutu yolluyorum.

python setup.py install

Django kurulmaya başlayacaktır. Konsolumuz bir yığın şeyle dolacaktır. Şimdi ilk projemizi yaratmamız için Django’yu kurduğumuz dizin içerisinden django-admin.py dosyasını bulmalıyız. Onu bulduktan sonra masaüstüne veya herhangi bir müsait yere atıp oradan çalıştıracağız. Gene ben bu dosyayı bulup C:\Users\user\Desktop\Django\ dizinine attım. Bu dizinden çalıştırıyorum. Şimdi ilk projemizi oluşturalım. django-admin.py dosyasını çalıştıracağız.

django-admin.py startproject ilkProjem

Eğer konsol ekranında bir şey görünmüyorsa ve django-admin.py’nin bulunduğu dizinde ilkProjem diye bir klasör oluştuysa başarıyla Django’da proje oluşturdunuz demektir. Klasörün içine girdiğinizde karşınıza manage.py dosyası çıkacaktır ve proje adıyla bir klasör daha. Şimdi ilk projemizi çalıştıralım ve Python’dan biraz yararlanalım. Gelecek yazılarımızda ise nasıl ‘Merhaba Dünya!’ diyeceğimizi ve SEF Url sistemini yapacağız. Oluşturduğunuz projeyi çalıştırmak için yapmanız gereken django-admin.py dosyasının bulunduğu dizinden, oluşturduğunuz projenin bulunduğu dizine geçmek. Yani sırasıyla yapmanız gerekenler:

cd ilkProjem

python manage.py runserver

Bu komutları da yazdığınızda karşınızda şöyle bir çıktı olacaktır.

Validating models...

0 errors found
July 12, 2013 - 22:16:23
Django version 1.5.1, using settings 'ilkProjem.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.

Şimdi http://127.0.0.1:8000 adresine giriyoruz …

[12/Jul/2013 22:19:07] "GET / HTTP/1.1" 200 1960

… sonuç başarılı projemiz çalışıyor. Dikkat ederseniz konsolda isteklerin gelişini de görebilirsiniz.

Tebrikler, Django’yu başarıyla kurdunuz ve ilk projenizi yaptınız!