Bu arada projemizin ihtiyaç duyduğu kütüphaneleri, paketleri vs. requirements.txt dosyası altında tutacağız. Böylece projemizi paylaştığımız zaman, takım arkadaşlarımız veya diğer insanlar $ pip install -r requirements.txt komutu ile kolayca proje gereksinimlerini kurup projeyi ayağa kaldırabilir.
Örnek requirements.txt dosyamız aşağıdaki gibi duracak. =='den sonrası versiyonları belirtmektedir.
xxxxxxxxxx
Flask==0.12.2
Flask-WTF==0.14.2
Configurations (Yapılandırmalar)
Projemiz şimdiye kadar herhangi bir yapılandırmaya ihtiyaç duymadı çünkü basit işler yaptık. Ancak proje dışarıdan paketler yüklendikçe, büyüdükçe belirli yapılandırmalara(konfigürasyonlara) ihtiyaç duyacak.
Projemizin temel dizinine bir adet modül ekleyelim. blog/config.py
SECRET_KEY Flask uygulamaları için çok önemlidir. Bazı Flask kütüphaneleri, yazılımları SECRET_KEY'i kriptografi için, token üretmek için kullanırlar. Flask-WTF de web formlarında CSRF (Cross-Site Request Forgery) saldırılarına karşı güvenlik amacıyla bu SECRET_KEY'i kullanır.
Web formlarında bu SECRET_KEY ile token anahtar (uzun karakterlerden oluşan stringler) üretilir. Her form submit edildiğinde farklı anahtar üretilir. Böylece saldırılara karşı güvenlik önlemi alınır.
Bizim SECRET_KEY'imiz önceden tanımlı var ise onu alır yoksa elle girdiğimiz cok-gizli-anahtar gibi verdiğimiz stringi alır. Stringi güçlü ve zor karakterlerden oluşturmak gerekli tabii ki. Burada örnek olması açısından yazdık.
StringField, Password Field .. gibi sınıflardan obje oluşturarak username, password.. gibi alanlara atama yaptık. Bunlar bizim web formlarımızı temsil edecek.
StringField sınıfına ve diğer sınıflara bakacak olursak; ilk parametre gösterim amaçlı yani label, varsa ikinci parametre olan validators Form alanının boş gitmemesi, düzgün formatta gitmesi için kullanılıyor. Burada biz boş olmaması içinDataRequired( ) sınıfını kullandık.
submit butonu için de tanımlama yapmak gerekiyor.
Form Templates
Tanımladığımız LoginForm sınıfının gösterimi için HTML template'e ihtiyacımız var.
myapp/templates/login.html dosyasına alanları yazıyoruz.
xxxxxxxxxx
{%extends 'base.html'%}
{%block content%}
<h1>Giriş Yap</h1>
<formaction=""method="POST">
{{form.hidden_tag()}}
<table>
<tr>
<td>{{form.username.label}}</td>
<td>{{form.username(size=32)}}</td>
</tr>
<tr>
<td>{{form.password.label}}</td>
<td>{{form.password(size=32)}}</td>
</tr>
<tr>
<td>
{{form.remember_me()}}
{{form.remember_me.label}}
</td>
</tr>
</table>
<p>{{ form.submit() }}</p>
</form>
{%endblock%}
Bu login template'i LoginForm'dan oluşturulmuş bir nesne(form) bekleyecektir.
<form action=" " method = "POST" ...> satırındaki action form submit edildiğinde hangi url'e gidileceğini gösterir. Request tipinin GET yerine POST seçilmesi daha güvenlidir. GET ile gönderilen formların alanları ve alanlara yazılan değerler URL alanına(adres çubuğuna) eklenir. POST ile gönderildiğinde URL alanında görülmez. Form datası request body'ye eklenir.
{{form.hidden_tag()}}CSRF ataklarına karşı güvenlik için token anahtar ekler. SECRET_KEY ve form.hidden_tag() işlemlerini gerçekleştirdiyseniz güvenlik için gerisini Flask-WTF sizin için yapacaktır.
Daha önceden HTML formları ile çalışanlar için bu form tag'leri ilginç gelebilir. Burada herşey form objesi üzerinden gidiyor. form.username.label üzerinde label kullanımını görüyoruz. form.username(size=32) kod parçasında size HTML attribute(özellik, nitelik)'lerini temsil eder.
HTML attribute'lerini bazı yerlerde özellikle kullanmak gerekebilir. Bunlar için örnek kullanım:
base.html'e de Navbar için <td><a href="/login">Giriş Yap</a></td> satırını ekledik.
Giriş Yap butonuna bastıysanız Method not Allowed hatası alacaksınız. Şu ana kadar sadece gösterim işini yaptık. Form'un submit sonrası iş mantığı için bazı eklemeler yapmamız gerekiyor.
@app.route varsayılan olarak GET methodu isteklerini karşılıyor. Burada biz POST isteklerini de kabul edeceğimizi belirttik.
Form submit edildiğinde form.valiadate_on_submit() değeri True olur ve form dataları ile ne yapacaksak burada yaparız.
Form submit edilmediğinde if bloğunu es geçer ve login sayfasını render eder.
flash() methodu kullanıcıya mesaj vermek için kullanılan faydalı bir methoddur.
redirect() methoduna verilen URL ile istediğiniz URL'e yönlendirme yapabilirsiniz. Burada kullanıcı giriş yaptıysa index sayfasına yönlendirme yaptık.
Şimdi base.html sayfamızda flash() methodundan gelen mesajları gösterecek kodları yazalım.
xxxxxxxxxx
<html>
<head>
{% if title%}
<title>{{title}}- Blog</title>
{% else%}
<title>Blog'a hoşgeldiniz.</title>
{%endif%}
</head>
<table>
<tr>
<td><ahref="/index">Anasayfa</a></td>
<td><ahref="/login">Giriş Yap</a></td>
</tr>
</table>
<hr>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<hr/>
<!-- body olarak kullanılacak kısım -->
{% block content %} {%endblock%}
</html>
Burada with yapısı ile Flask'in bize sunduğu get_flashed_messages() methodundan dönen mesajları, if bloğunda boş değilse for döngüsü ile <li> tag'lerinde gösteriyoruz.
login.html'i de hata mesajları için biraz düzenleyelim.
Flask'in bize sunduğu kullanışlı methodlar'dan biri de url_for() methodudur. Bu method yardımı ile html sayfalarındaki /index, /login gibi URL'ler yerine url_for('method_adi') diyerek kolayca python tarafına method isimleri ile erişebileceğiz. Linklerin değişiminin method isimlerinin değişiminden fazla olması, kompleks URL'lere erişim ve o URL'leri kullanımın url_for() ile daha kolay olması, bizi bu kullanışlı methoda yönlendiriyor. base.html'de değişiklik yapalım.
Yorumlar