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

1 yorum :

  1. merhaba
    bu kodlarda bir hatamı var yada eksik birşey hata alıyorum " AttributeError
    Exception Value:
    'module' object has no attribute 'doktor_ekle' " yardım ederseniz sevinirim

    YanıtlaSil