Django ve React ile Full Stack —Django

Barış Dede
12 min readAug 5, 2020

--

Biliyorum, çok kapsamlı bir başlık. Olabildiğince basit tutacağım.

Bu yazıda bir kitap uygulamasını, Django ve React kullanarak kurulumdan son ürüne kadar yapacağız. Bir CRUD(Create,Read,Update,Delete) uygulamasını, güzel ve basit bir giriş-geliştirme-ürün serisi yapmayı umuyorum. İki taraftan da (back end ve front end) çok fazla bilgi karmaşasına boğmadan, çalışır bir uygulamayı elde ederken aldığım notları, izlediğim adımları sizlerle paylaşmak istiyorum.

Ne, nedir gibi sorular üzerinde çok durmamaya, sıkmadan, amaca yönelik anlatmaya çalışacağım. Kullandığım her komut için bilmeyenler olabilir diye kaynak vereceğim, kendi dökümantasyon sayfalarından hızlı bir şekilde fikir sahibi olup yazıya geri dönebilirsiniz.

Django kısaca Python tabanlı ücretsiz ve açık kaynak kodlu, model-template-view mimarisini temel alan bir web kütüphanesidir.

React web projelerinizin kullanıcı arayüzlerini, component bazlı olarak oluşturmanızı sağlayan bir JavaScript kütüphanesidir.

Ortam Kurulumu #1

Yazıya devam etmeden önce cihazınızda kurulu olması gerekenler şu şekilde:

Python3PipNodeJS

Bu yazıyı yazarken Python 3.6~, pip 20.1.1, NodeJS 12.18.2 sürümlerini kullanıyorum. Referans aldığım betikler eğer farklı bir versiyonda çalışmaz veya hata verir ise sormaktan çekinmeyin.

Kendimize bir çalışma ortamı oluşturarak başlayalım. Klasör ismini ben DjangoReact yaptım. Klasör içerisine girerek pipenv kurulumumuzu yapacağız. Pipenv paketleme işlemlerini(bundler, npm, yarn, composer, etc.) Python dünyasına getiren bir araç. Otomatik olarak sanal ortam oluşturma ve yönetme imkanı sağlıyor.(yeni paketler yükleme/silme işlemleri)

Çalışma klasörümüze giriş yaptıktan sonra, aşağıdaki kodu komut satırına yapıştıralım.

python3.6 -m pip install pipenv --upgrade

Kurulum tamamlandıktan sonra, aşağıdaki kod ile sanal ortamımıza django 3.0.8(son sürüm) kurulumumuzu yapıyoruz.

pipenv install --python 3.6 django==3.0.8

Kurulum sonrası klasörümüz şu şekilde olmalı:

DjangoReact
├── Pipfile
└── Pipfile.lock

Virturalenv’i aktifleştirmek için pipenv shell kodunu çalıştırıyoruz.

Django projemizi oluşturmaya başlayabiliriz artık. Komut satırına django-admin yazdığınızda kullanabileceğiniz parametreleri listeler. Bizim şu anlık ilgilendiğimiz parametre startproject. Biz bulunduğumuz klasöre kurulum gerçekleştirmek istediğimiz için (yazı başlangıcında bir klasör oluşturmuştuk zaten) bulunduğumuz klasöre DjangoReact adında bir proje oluşturuyoruz.

django-admin startproject DjangoReact .

Klasörümüzün son hali bu şekilde:

DjangoReact/
manage.py
DjangoReact/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py

Buraya bir not düşmek istiyorum: proje ve uygulama farklı şeyler. startprojectve startapp kullanımları birbirinden farklıdır. Uygulama, belirli bir amaca hizmet eden web uygulamasıdır — blog, todolist, veritabanı kayıtları vs. Proje ise bir web sitesi içerisinde uygulama ve yapılandırma koleksiyonudur. Proje birden fazla uygulamayı içerisinde barındırabilir.

Kontrol etmek için sunucumuzu çalıştırıp, doğru çalıştığını kontrol ediyoruz. python manage.py runserver kodunu çalıştırdığımızda terminaldeki çıktı aşağıdaki gibi olmalı.

(DjangoReact) $~ python manage.py runserverWatching for file changes with StatReloader
Performing system checks…
System check identified no issues (0 silenced).
You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run ‘python manage.py migrate’ to apply them.
July 17, 2020–14:22:01
Django version 3.0.8, using settings ‘backend.settings’
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Localhost’umuza girdiğimizde ise aşağıdaki ekran bizi karşılıyor. Evet! Çalıştı.

127.0.0.1

Son küçük bir dokunuşumuz kaldı. Onu da yapıyoruz…

Evet! Artık CV’mize Django’yu da ekleyebiliriz.

Model, View, Routing…urls #2

Şimdi ilk uygulamamızı oluşturma vaktimiz geldi. Yapılacaklar listemi şu şekilde yazdım:

1. Books-> Creating   -> Name?   -> Author?   -> Description?   -> Image?-> Search-> Delete-> Update2. Feed-> List of all books

DjangoReact klasörünün içerisinde gelip ./manage.py startapp books komutu ile bir uygulama oluşturuyoruz. Komutu çalıştırdıktan sonra klasörümüzün içerisinde ‘books’ adında bir klasör oluşturup içerisine kurulumu gerçekleştirecek. Klasörümüzün son hali şu şekilde;

DjangoReact/
├── books
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── db.sqlite3
├── DjangoReact
│ ├── asgi.py
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-36.pyc
│ │ ├── settings.cpython-36.pyc
│ │ ├── urls.cpython-36.pyc
│ │ └── wsgi.cpython-36.pyc
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
├── Pipfile
├── Pipfile.lock
└── todo.md

Model

Oluşturduğumuz books uygulamasının içerisindeki model.py dosyasını aşağıdaki gibi yapılandırıyoruz.

models.TextField() ile isim, yazar, açıklama alanlarını tanımlıyoruz. blank=False ve null=False yaptıklarım doldurulması gereken alanlarımız, diğerleri boş olsalar da kabul edeceğiz. id alanımız otomatik olarak artacak ve seçici olarak kullanılacağı için onu AutoField ve anahtar olarak tanımladık. Kapak fotoğraflarımızı alabilmek için de FileField kullanarak dosya yolu belirledik ve bu alan boş bırakılabilir dedik.

Migrate

Uygulamamızı, proje çalıştığında tanıyabilmesi için proje klasörümüz altındaki settings.py dosyasında INSTALLED_APPS dizisini bulup içerisine model ismimizi ekleyip kaydetmemiz gerekiyor 'books’. Bu işlemi yaptıktan sonra modelimizde yaptığımız değişiklikleri veritabanı şemasına yazmak için ./manage.py makemigrations komutunu çalıştırıyoruz ve tamamlandıktan sonra python manage.py migrate komutunu ile yaptığımız değişiklikleri uyguluyoruz.

$~ ./manage.py makemigrationsMigrations for 'books':
books/migrations/0001_initial.py
- Create model Books
$~ python manage.py migrateOperations to perform:
Apply all migrations: admin, auth, books, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying books.0001_initial... OK
Applying sessions.0001_initial... OK

Oluşturduğumuz modelimizi terminal ekranında test edelim bakalım nasıl görünüyor. ./manage.py shell yazıp projemizi çalıştırıyor ve ekrana aşağıdaki kodları sırasıyla yazıyoruz;

>>> from books.models import Books
>>> obj = Books()
>>> obj.name = "Otostopçunun Galaksi Rehberi"
>>> obj.author = "Douglas Adams"
>>> obj.description = "Uzaylı gören masum köylü" # null veya blank olabilir dediğimiz için bu kısmı boş geçebilirsiniz.
>>> obj.save()
>>> exit()

Yukarıdaki kodu çalıştırdık ve shell’den çıktık. Şimdi tekrar shell’e girip kaydımız gerçekleşmiş mi, veriyi çekebiliyor muyuz ona bakalım.

>>> from books.models import Books
>>> firstBook = Books.objects.get(id=1)
>>> firstBook.name
'Otostopçunun Galaksi Rehberi'
>>> exit()

View

Elbette bu şekilde terminal üzerinden devam etmeyeceğiz. Biraz da view tarafını kurcalayalım.’books’ klasörümüzün altındaki views.py dosyasını açalım ve bir ritüeli gerçekleştirmek adına ekrana Hello World yazdıralım.

Projemiz içindeki urls.py dosyasına da ana sayfamızı aşağıdaki gibi tanımlıyoruz.

Tahmin etmesi güç biliyorum. http://127.0.0.1 adresine girdiğimizde kim bilir karşımıza ne çıkacak. Tadınızı kaçıran bir espriydi evet. Ekranda yine Hello World! yazımızı gördük.

Dinamik URL’ler

View dosyamız içerisine book_detail_view adında bir fonksiyon daha ekleyip, url üzerinden gelen parametreleri ekrana bastırıyoruz.

Elbette ki henüz bu kısmı tetikleyen bir url yakalayıcımız yok. urls.py dosyamız içerisindeki book.view importumuza book_detail_view fonksiyonunu ekleyip, urlpatterns dizimize path('books/<int:book_id>',book_detail_view) kodunu ekliyoruz.

http://127.0.0.1:8000/books/1 adresine girdiğimizde ekranda Hey 1 başlığını göreceğiz. Parametre olarak girdiğimiz herhangi bir değeri sayfa içerisinde ekrana basabiliyoruz artık. Hadi bu gelen parametreyi kullanarak veritabanımızda bulunan kitap bilgilerini ekrana yazdıralım.

from .models import Books kodunu views.py dosyamıza ekleyelim. book_detail_view fonksiyonumuz içerisinde gelen book_id değerini alıp o id’ye ait bilgileri alıp ekrana bastıralım.

Şimdi http://127.0.0.1:8000/books/1 adresine girdiğimizde ekranda çıktımız şu şekilde olacak:

Veritabanımızda bulunmayan bir id girişi yaptığımızda, veritabanında böyle bir veri bulunamadığına dair hata ile karşılaşacağız. Bu hatayı da yakalayıp standart 404 sayfamızı döndürelim.

book_detail_view fonksiyonumuzdaki obj tanımlamasını try-except ile kontrol altına alalım.

Standart 404 sayfası

CRUD uygulaması yapacağız dedim fakat sadece R(read) kısmını yaptım. C(create) kısmı için bir form oluşturalım. /templates/components/form.html adında bir dosya oluşturuyoruz ve o boş bir şekilde beklerken uygulamamızın altına bir de form.py adında dosya oluşturup formumuzu tasarlamaya başlayalım.

Yukarıdaki kodu form.py dosyamızın içerisinde yazdık. Projeye başlarken model oluşturduğumuzda name, author, description alanlarını TextField yapmıştık. Django’nun ‘forms’ sınıfını çağırarak oluşturduğumuz modelde, istediğimiz verilere göre bir form oluşturmasını istiyoruz. Kitap açıklamasını da sınırlandırarak veriler üzerinde nasıl kontrol yapabileceğimizin örneğini vermiş olmak istedim. İlerlerken Django’nun da nimetlerinden faydalanmak lazım.

Şimdi views kısmında bu formu kullanabiliriz. book_create_view adında bir fonksiyon oluşturup create-book url’si geldiğinde bu fonksiyonu çalıştırması için urls.py dosyamıza ekliyoruz.

Yukarıdaki kodda, form.py dosyamızdan BooksForm sınıfını çağırdık. Model oluştururken hangi verilerin zorunlu, hangilerinin zorunlu olmadığını belirtmiştik. Buna göre Django’nun form sınıfından kontrol sağlıyoruz, eğer beklenen veriler dışında bir veri girişi yoksa gelen formu kaydediyoruz. Bu view POST ile ya da direkt url aracılığıyla görüntülenebilir. POST geldiği zaman yapacağı davranışı form = BooksForm(request.POST or None) kısmında belirttik.

Şimdi de arayüz tarafındaki karşılığını görelim. form.html dosyamız şu şekilde;

form.as_p her elementi bir <p> tagı ile çerçevele anlamına geliyor. CSRF ise bir web uygulamasında oturum açan kullanıcının oturumu üzerinden kullanıcının istekleri dışında işlem yapılması durumudur. Kullandığımız token ise bunu engellemek adına oluşturulan bir hash’tir ve backend tarafında kontrol edilir. Konudan bağımsız faydalı bir bilgi.

Silme ve güncelleme işlemleri için tekrar bir açıklama yapmak istemedim, laf kalabalığı olmaması açısından. Kaydetme ve okuma işlemlerinden farklı değiller. Silmek için Books.object.filter(id=book_id).delete() kodunu kullanıyoruz. Güncelleme işlemi için ise okuma işlemi ile aynı.

book = Books.object.get(id=1)
book.name = "Yeni isim"
book.save()

Templates, REST API, Djangorestframework ve Tests #3

Şimdi elimizdeki verileri bir HTML Template dosyasının içerisine göndererek daha düzenli bir şekilde ekrana bastırmayı sağlayacağız.

Template

Öncelikle template klasörümüzü hazırlıyoruz. Ana dizine templates adında bir klasör oluşturuyoruz. Template yolunu belirleyebilmek için ise settings.py dosyamızda TEMPLATES dizisini bulup 'DIRS' içerisini [os.path.join(BASE_DIR, "templates")] olarak düzenliyoruz. Artık template yolumuzu belirttik. Templates klasörümüz içerisine /pages/home.html adında bir HTML dosyası oluşturuyoruz ve içerisine o dosya olduğunu belirten herhangi bir şey yazabilirsiniz. Ben “Hello World from home.html file” yazdım. Sonrasında, views kısmında ana sayfayı tanımladığımız home_view fonksiyonunun içerisini direkt ekrana bastıracak şekilde değil de HTML dosyamızı çağıracak şekilde yapılandırıyoruz.

Tekrar tekrar aynı kodları yazmaktan kaçınmak adına templates dizinimize bir adet base.html dosyası oluşturup, bütün sayfalarda kullanacağımız meta tagleri, başlık seçimleri gibi şeyleri tek bir dosyada tutuyoruz. Örnek olarak:

Daha önce twig, blade gibi tasarım motorları kullandıysanız bu fikir size uzak gelmeyecektir. Kullanmadım diyorsanız hızlı bir şekilde dökümantasyon sayfalarına gidip basit kullanımlarını inceleyebilirsiniz. Basit bir şekilde açıklamak gerekirse tasarım motorları, dinamik sayfalar içerisinde, backend tarafından gelen verileri derleyebilmemizi, parçalara ayırdığımız — menu,header,meta tags, sidebar vs. — dosyalarımızı ihtiyacımıza göre çalıştırmamızı sağlıyor. Konuyu dağıtmadan devam ediyorum.

Oluşturmuş olduğumuz base.html sayfasını home.html sayfasında değerlendireceğiz. home.html sayfamızı aşağıdaki gibi düzenliyoruz.

Yukarıda gördüğünüz gibi ana sayfaya girdiğimizde artık home.html sayfamızı çağırıyor. Sayfa derlendiğinde ise yukarıda bahsettiğim gibi base.html içerisine entegre edilerek bu şekilde bir çıktı elde ediyoruz.

REST API — DjangoRestFramework

Template’imizi çalıştırdık, biraz karıştırdık. Şimdi ise elimizdeki verileri json verisi olarak döndürelim. book_detail_view ve home_view kısmında return değerimizi HttpResponse olarak yapmıştık. home_view’de sayfamızı HTML üzerinden renderladık, book_detail_view kısmında ise direkt olarak ekrana bastırdık. django.http içerisinden JsonResponse classını çağırıyoruz. Verilerimizi direkt olduğu gibi değil de biraz daha kullanışlı halleri ile bastıracağız.

Yukarıdaki kodda, aranan veri bulunduysa data içerisine verilerini yazdık bulunamadıysa bir hata mesajı verdirttik. Bulunamadığında Http404 döndürmek yerine bir hata kodu ve mesaj bastırdık ekrana. Çünkü artık API sağlıyoruz.

Elimiz kirlenmişken tüm kitapları listeleyen kodumuzu da yazalım.

React kısmına geçmeden önce oluşturduğumuz API’yi JavaScript ile kullanalım. Her zaman react kullanmak zorunda değiliz sonuçta. Basit uygulamalarda basit çözümler üretelim.

Yapacağımız işlem son derece basit bir JavaScript kodu yazmak. Bir Http isteği atacağız ve dönen verileri ekrana basacağız. Ana sayfa üzerinde elimizdeki bütün kitapları liste olarak bastırmak için aşağıdaki kodu kullanıyoruz.

Amacımız genel yapıyı anlamak olduğu için tasarımsal olarak herhangi bir düzenleme yapmadım. Belki son aşamada küçük dokunuşlar ile güzel bir görüntü yakalarız.

Kitap ekleme sayfamızı book_create_view ile yapmıştık. Şimdi formumuzu kendimiz oluşturup, eklemek istediğimiz verileri API’ye gönderelim. Ekleme işlemlerini direkt ana sayfa üzerinden yapıp create-book adresine gönderelim.

Ana sayfaya yukarıdaki formu ekleyelim. Formu doldurup kaydet butonuna bastığımızda CSRF verification failed. Request aborted. hatası alacağız. Formu ilk oluşturduğumuzda bir csrf_token göndermiştik. Aynısını burada da uygulamamız lazım. Formun içerisine {% csrf_token %} kodumuzu ekliyoruz. Ekledikten sonra formumuzu çalışır hale getirdik.

Ekleme işlemimiz gerçekleştiğinde adresimiz /create-book şeklinde kalacak. Ekleme işlemi başarıyla gerçekleştiyse ana sayfaya yönlendirme yapalım. next girişini bunun için aldık. View sayfamıza django.shortcuts kütüphanesinden redirect argümanını çağıralım( from django.shortcuts import render, redirect ). Gelen next değerimizi yönlendirilecek sayfa olarak kullanacağız ve eğer kayıt gerçekleştiyse yönlendireceğiz.

Küçük bir önlem almak adına, yönlendirilecek adresin güvenli olduğundan emin olalım. Bir şekilde içeriye next değeri olarak farklı bir adres gönderilirse kullanıcı istenmeyen bir adrese yönlendirilmesin. Bunun için settings.py dosyamıza ALLOWED_HOSTS dizisi ile güvenli adreslerimizi ekleyelim.

ALLOWED_HOSTS = ['127.0.0.1', 'yourdomainname.com', 'localhost']

Bu adresleri kontrol edebilmek için Django’nun sağladığı özelliklerden faydalanacağız. Sayfaya from django.utils.http import is_safe_url kodumuzu ekliyoruz. Bu kod ayarlara eklediğimiz kabul edilen adresler ile yönlendirilmek istenen sayfayı karşılaştırarak, güvenli olup olmadığını kontrol edecek. if next_url != None kontrolü yaptığımız satıra bir kontrol daha ekliyoruz ve son hali if next_url != None and is_safe_url(next_url) olacak şekilde kaydediyoruz. Bu haliyle çalıştırıp bir form gönderdiğimizde artık hata ile karşılaşacağız. Çünkü ayarlarımızı sayfaya çağırıp kabul edilen adreslerimizi göstermedik. from django.conf import settings ile ayarlarımızı sayfamıza çağırıyoruz. Sayfa içerisinde ALLOWED_HOSTS = settings.ALLOWED_HOSTS değişkenimizi tanımlıyor ve is_safe_url() içerisine ikinci parametre olarak gönderiyoruz is_safe_url(next_url, ALLOWED_HOSTS)

View kodumuzun son hali şu şekilde:

Güvenli adres kodumuzun doğru çalışıp çalışmadığını test etmek için oluşturduğumuz form üzerinden next değerini farklı bir adres ile değiştirebilirsiniz.

Serializer

Serialization(Serileştirme) işlemi elimizdeki sınıf veya nesnelerin saklanmak veya gönderilmek istenen formata dönüştürme işlemidir. Kaydettiğimiz nesne veya sınıfların tiplerini bilemediğimiz durumlarda yeniden kullanılabilirlik açısından serileştirme işlemi yaparak, daha sonrası için kullanılabilirliğini artırabiliriz. Bu işlem verilerimizin küçülmesini ve performans artışını beraberinde getirecektir.

REST API üzerinde de oynamalar yapmamızı sağlayacak ve serialization işlemimiz için bize yardımcı olacak django kütüphanesi olan djangorestframework’ü pipenv install djangorestframework kodunu konsol ekranına yazarak projemize kuralım. settings.py dosyamızda INSTALLED_APPS dizimize rest_framework ‘ü ekleyip kaydedelim. Artık kodumuzu yazarken bu kütüphaneyi sayfamıza çağırarak kullanabiliriz.

Aslında serialize işlemimizi book_list içerisinde kitaplarımızı books = [{'id':x.id, 'name':x.name, 'author':x.author, 'description': x.description} for x in blist] şeklinde tanımlayarak yapmıştık. Bu işlemi ayırarak model içerisine ufak bir ekleme yapıyoruz.

Model içerisine serialize fonksiyonumuzu tanımladıktan sonra, books_list view’ımızı daha temiz hale getirebiliriz.

Artık değişkenimizi tanımlarken yaşadığımız kod karmaşasından kurtulduk.

Kitap kaydetme işlemini Form kullanarak yapmıştık. Şimdi bu işlemi bir de djangorestframework ile serialization işlemi de yaparak tekrar yazalım. serializer.py adında bir dosya oluşturarak form.py içerisinde yazdığımız kodu buraya uyarlayalım.

Serializer dosyamızı hazırladık şimdi de view tarafında bunu kullanalım.

Daha önce oluşturduğumuz book_create_view fonksiyonumu _pure ekleyerek değiştirdim. Oluşturduğum serializer ile bu fonksiyonu yeniden yazdım. Öncekinde bir html dosyası renderlamıştık. Şimdi ise ekrana dönen sonucumuzu json olarak bastırdık: ki front end tarafından bu fonksiyonu tetiklerken, dönen sonuçları front end tarafında işleyelim.

Django View’lardan Django Rest Framework View’lara doğru geçiş yapalım.

Önce book_create_view fonksiyonumuzu değiştirerek başlayalım.

from rest_framework.response import Response ve from rest_framework.decorators import api_view kodlarını view sayfamıza ekliyoruz ve book_create_view sayfamızın görünümünü API sayfası olarak değiştiriyoruz.

@api_view() kodunu fonksiyonumuzun üstüne ekleyerek çalışacak fonksiyonun bir API görünümü almasını sağlıyoruz. İçerisine verebileceğimiz, POST-GET gibi parametreler ile bu fonksiyona hangi metodlar ile erişilebileceğini yazıyoruz. Kitap eklerken biz POST metodunu kullandık ve diğerlerini istemiyoruz. Döndüreceğimiz sonuçları da JsonResponse değil Response olarak gönderiyoruz artık.

Aynı işlemi kitap listeleme fonksiyonumuz olan books_list ve book_detail_view için de yapıyoruz — fonksiyonun üstüne @api_view(['GET']) ekleyip JsonResponse kodumuzu Response ile değiştiriyoruz.

Hepsi bu! — değil, elbette. Fakat şuan pratiğe devam edebilmemiz için ihtiyacımız olanları karşıladık. Djangorestframework ile ilgili daha fazla bilgi edinmek için dökümantasyon sayfasını ziyaret edebilir, kullanabileceğiniz faydalı parametreler hakkında bilgi edinebilirsiniz. Dökümantasyonları çok güzel hazırlanmış.

Tests

Django tarafında yapacağımız son işlemimiz, test kodumuzu yazmak. TDD(Test Driven Development) tarafımızı en basit aşamadayken besleyip alışkanlık kazanırsak, başka bir dilde bile olsa bu alışkanlık bize fazlasıyla zaman kazandıracaktır.

Uygulamamızı kurduğumuzda test dosyamızı da beraberinde getiriyor. Komut satırına ./manage.py test books yazdığımızda testimizi çalıştıracak ve ilk çıktımız şu şekilde olacak:

System check identified no issues (0 silenced).----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK

Sonuçlar mükemmel. Çünkü içeride bir test kodumuz yok. Bu mükemmelliği korumayı umut ederek yolumuza devam ediyoruz. test.py dosyamızın içerisinde Books modelimiz için bir test yazalım.

Bu testte yeni bir kitap ekledik ve testi çalıştırdığımızda yeni bir kullanıcı ekleyip id’sini kontrol edecek. Eğer kaydedemediyse veya kaydettiği veri olması gerekenden farklıysa hata verecek.

Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.
----------------------------------------------------------------------
Ran 1 test in 0.003s
OK
Destroying test database for alias 'default'...

Test kodumuz hatasız bir şekilde çalıştı. Eğer self.assertEqual(book_obj.id, 5) yapsaydık testimizi çalıştırdığımızda AssertionError: 1 != 5 diye bir hata alacaktık. Bu işlemi yaparken ilk defa veri girişi yapıyor gibi varsayıyor ve ilk girilen verinin 1 olması beklenirken 5 mi diye kontrol ediyoruz. Aynı hata, eğer oluşturulan objenin id’si 1 olmazsa da gelecekti. Dünyanın binbir türlü hali var bir bakmışsın integer değer bile dönmemiz objeden. Bilemezsin, her şey olabilir bu hayatta. Testing konusunda Django’nun dökümantasyonundan faydalı kullanımları görebilirsiniz.

Peki her şey tamamlandıktan sonra yaptığımız bu işi biz nasıl yayına alacağız? Bu kısımda hemen her servis sağlayıcının dökümantasyon sayfalarında bilgi mevcut. Yorumlanabilir bir tarafı olmadığı için sizlere doğrudan kaynak vereceğim. Django’yu bulut tabanlı bir sistemde çalıştırabilirsiniz. Bunun en popüler örneklerinden birisi Heroku. Doğrudan kendi yönergelerini takip ederek ilk projenizi yayına alabilirsiniz. Eğer kendi sunucunuzu kullanmak isterseniz DigitalOcean sayfasında yayın yönergeleri mevcut. Bu işlemler ssh bağlantısı kurabildiğiniz bütün sunucularda aynı olacaktır.

Şuana kadar Django ile yapacağımız işlemleri tamamladık. Kitap ekleme, listeleme ve istenilen kitabı ekrana bastırdık. Tekrar eden kodları, yazıyı uzatmamak için eklemedim. Elbette ki her şey bu kadarla bitmiyor. Yazdığımız her satır kodun bir alternatifi mevcut. Her başlık kendi içerisinde daha da derinlere iniyor. En basitler ile yola çıkarak, bol pratik ile kendimizi geliştirmeye devam edeceğiz. Bu yazıda kullandığım kaynak kodlarını Github üzerinden inceleyebilir, dilerseniz katkıda bulunabilirsiniz.

Soru veya sorunlarınız için bana Twitter üzerinden ulaşabilirsiniz.

Bu yazının devamı olan, React ile arayüz geliştirmeye giriş yaptığım Django ve React ile Full Stack — React yazıma da bekliyorum.

Happy codding! :)

Github, Twitter, Instagram : @bari5d

--

--