Django, formlarla çalışabilmemizi sağlayan kapsamlı bir takım enstrümanlar sunan özel bir yapıya sahiptir. Bu yapı özellikleri arasında, tek bir konumda form işlevselliği tanımlama, veri doğrulama ve Django modelleri ile entegrasyonlar yer alır, şimdi ufak bir örnek ile durumun nasıl işlediğine kısaca bakalım.
Form oluşturulması için django uygulamamız içerisinde forms.py adlı bir dosya oluşturuyoruz. İçerisini ise aşağıdaki gibi oluşturuyorum. Djangoda formların belirli bir dosya içerisinde bulunması gerekmediğinide hatırlatırım. Yani isterseniz forms.py oluşturmak yerine, uygulama dosyalarınızın içerisinde de barındırabilirsiniz. Örneğin: models.py veya views.py içerisinde formlar yer alabilirler.
from django import forms
class Contact(forms.Form):
name = forms.CharField(required=False)
email = forms.EmailField(label='Your email')
subject = forms.CharField(widget=forms.Textarea)
Burada en önemli nokta django’da formların forms.Form sınıfının bir alt sınıfı olarak alınması gerekmektedir. Bu yüzden otomatik olarak form yapısı içerisindeki bütün sınıflara eklenmesi gerekmektedir. Daha sonra, form sınıfının forms.CharField türünde ve form.EmailField türlerinden biri olan üç özellik olduğunu görebilirsiniz. Bu form alanı tanımları, belirli özelliklere karşılık gelir ve girdiyi kısıtlar.
Örneğin, forms.CharField girdinin bir dizi karakter ve form olması gerektiğini belirtir. forms.EmailField ise girdinin bir e-posta olması gerektiğini belirtir. Ayrıca, her bir form alanının, girdi türünü daha da kısıtlamak için özellikler (örn. required
) içerdiğini görebilirsiniz. Şimdilik bu Django form alanı türleri hakkında yeterli bilgiyi size verecektir.
Formumuzu oluşturduktan hemen sonra, gelin bu oluşturduğumuz formu projemizin views.py dosyası içerisinde nasıl kullanılabileceğine bakalım.
from django.shortcuts import render
from .forms import Contact
def contact(request):
form = Contact()
return render(request,'about/contact.html',{'form': form})
Oluşturduğumuz views.py içerisindeki contact fonksiyonu, önce Contact form sınıfını bir önceki örneğimizden teslim alıp başlatır ve bunu form referansına atar. Bu form başvurusu daha sonra about/contact.html şablonunda kullanılabilir hale getirilecek bir argüman olarak iletilir.
Ardından, Django’da kullandığımız şablonunun içinde Django formunu normal bir değişken olarak verebilirsiniz. standart şablon sözdizimini {{ form.as_table }} olarak kullanırsanız. Çıktısı aşağıdaki gibi olacaktır.
<tr>
<th><label for="id_name">Name:</label></th>
<td><input id="id_name" name="name" type="text" /></td>
</tr>
<tr>
<th><label for="id_email">Your email:</label></th>
<td><input id="id_email" required name="email" type="email" /></td>
</tr>
<tr>
<th><label for="id_comment">Comment:</label></th>
<td><textarea cols="40" id="id_comment" required name="comment" rows="10"></textarea></td>
</tr>
Django formunun HTML etiketlerine nasıl çevrildiğini gördünüz! Django formunun her form alanı için uygun HTML <input> etiketlerini nasıl ürettiğine dikkat edin (ör. Forms.EmailField(label = ‘E-postanız’), istemci tarafını bu alanı doldurmaya zorlamak adına <label>
içerisine required
ekler ve HTML5 tipini type="email"
olarak ayarlar. ve bir e-postanın doğrulanması da bu şekilde sağlanmış olur). Ayrıca, form alanında kullanılan bir takım alanların gerekliliklerini değiştirebilirsiniz. Bunu form yapısında devredışı bırakmak için required=False
olarak düzenleyin.
Ayrıca söz diziminde kullandığımız as_table ile çıktının HTML5 tablo yapısında olmasını işlerimizi kolaylaştırdığı için istedik. İsterseniz dokümantasyon aracılığı ile daha sonradan kendi yapınıza uygun olanı seçip kullanabilirsiniz.
Tüm bunları görsel bir şekilde anlatmamız gerekirse aşağıdaki şablon sizin için yeterli olacaktır.
Django Form İş Akışı
Bu noktaya kadar anlattıklarım. Django form sınıfına dayalı boş bir form döndürdük ve teorik olarak devam ettik. Django formlarını işlevsel bir hale getirmek için eksik parçaları hadi gelin hep birlikte tamamlayalım. Eksik parçaları ekleyelim.
Şimdiye kadar bir Django form sınıfı tanımının hızlı bir şekilde bir HTML formuna dönüştürülebileceğini öğrendiniz. Ancak bu otomatik HTML olayı, Django form sınıfı tanımlarını kullanmanın sadece bir ufak bölümüdür. Ayrıca form değerlerini doğrulayabilir ve hataları son kullanıcıya daha hızlı gösterebilirsiniz istersenizde kendi yapınızı kurarak yolunuza devam edebilirsiniz.
<form method="POST">{% csrf_token %}
{{form.as_p}}
<input type="submit" value="Kaydet" />
</form>
Şimdi oluşturduğumuz formun tüm web formları için standart olan HTML <form>
yapısını oluşturacak. method
tanımını POST olarak kullandık. POST yöntemi, kullanıcı verilerini işleyen web formlarında standart bir uygulamadır. Alternatif bir yöntem olarakta GET kullanabilirsiniz. Ancak, kullanıcı tarafından sağlanan verileri aktarmak için kullanılabilecek bir seçenek değildir.(genellikle)
Action
tanımlaması yapmadığımızı fark etmişsinizdir. Bu durumda istek bulunan mevcut sayfaya aktarılacaktır. {% csrf_token %}
ise POST isteği yoluyla gönderildiği ve Django tarafından işlendiği durumlar için ayrılan özel bir etikettir. Django tarafından uygulanan standart bir güvenlik mekanizması olan Cross-Site Request Forgery(Siteler Arası İstek Sahtekarlığı) anlamına gelir.
CSRF’yi devre dışı bırakmak ve formlarda {% csrf_token%}
Django etiketini dahil etmemek mümkün olsa da, CSRF bir güvenlik önlemi olarak çalıştığı için, {% csrf_token%}
Django etiketini POST ile gelen tüm formlara eklemeye devam etmenizi öneririz.
{{form.as_p}}
ise form yapısını oluştururken diğer elementlerin <p>
ile sarılması ve çıktıların satır satır işlenmesidir. Şimdi herşey kısmen hazır olduğuna göre gelelim isteklerin işleneceği views.py düzenlemeye kodumuz aşağıdaki gibi olacak
from django.shortcuts import render
from django.http import HttpResponseRedirect
from .forms import ContactForm
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('/about/')
else:
form = ContactForm()
return render(request,'about/contact.html',{'form':form})
Yukarıdaki örneğimizde en önemli nokta isteklerin işlendiği bölüm olan if/else yapısıdır. Yapılacak işlemlerimizi buna göre basitçe belirleyebiliriz. POST isteği gelirse ayrı, GET isteği gelirse ayrı olarak işleme alınaktır. POST mantığına daha yakından bakalım. İstek türü POST ise, gelen kullanıcı verisi var demektir, bu yüzden gelen veriye request.POST referansı ile erişir ve Django formunu onunla başlatırız. Ancak, bireysel form alanlarına erişmenin veya parça parça atamaları yapmanın gerekmediğine dikkat edin.
Bu noktada, bir kullanıcının Django form alan tanımları ile ilgili geçerli bir veri sağlayıp sağlamadığını hala bilmiyoruz (örneğin, değerler metinse veya geçerli bir e-posta değilse). Bir formun verilerini doğrulamak için, bağlı form örneğinde is_valid() yöntemini kullanmanız gerekir. Eğer form.is_valid() True ise veriler işlenir ve sonraki işlem yapılır, return
ile URL’ye yönlendirme ile son bulur. form.is_valid() öğesi false ise form verilerinin hataları olduğu anlamına gelir; ve istenen şekilde ister kullanıcıya mesaj ulaştırılır istersede form tekrar gösterilir.
CSRF veya siteler arası talep sahteciliği, siber suçluların kullanıcıları bir web uygulamasında istenmeyen eylemleri gerçekleştirmeye zorlamak için kullandıkları bir tekniktir. Kullanıcılar web formlarıyla etkileşimde bulunduklarında, sipariş vermekten (örn. Ürünler, para transferleri) verilerinin değiştirilmesine (ör. Ad, e-posta, adres) kadar değişen her türlü durum değiştiren görevleri yaparlar. Çoğu kullanıcı, bir HTTPS/SSL güvenli kilit sembolü gördüklerinden veya bir web formuyla etkileşimde bulunmadan önce kullanıcı adı ve parola kullandıkları için web formlarıyla etkileşimde bulunduklarında daha yüksek güvenlik duygusu hissetmeye eğilimlidirler.
Bir CSRF saldırısı, web uygulamasında sosyal mühendislik ve lax uygulama güvenliğine büyük ölçüde dayanır; bu nedenle, saldırı vektörü diğer güvenlik önlemlerine (örn. HTTPS/SSL, güçlü parola) bakılmaksızın çalışır.
Görebildiğiniz gibi, bir CSRF saldırısı gerçekleştirmek için, bir kullanıcının belirli bir sitede aktif bir oturuma sahip olması ve bir kullanıcının bir eylemi veya bir eylemi gerçekleştiren bir sayfayı tıklatması için kandırılması yeterlidir. Bu nedenle terimin adı: “Siteler arası”, istek orijinal siteden gelmiyor, çünkü bu siber suçlunun sahte bir isteğidir.
Web formları, bir kullanıcı için benzersiz olan ve bir oturum tanımlayıcısına benzer bir son kullanma süresine sahip , genellikle bir CSRF belirteci şeklinde adlandırılan benzersiz bir alan daha içermelidir.