/

Django Rest Framework -1

Bu eğitim bölümümüzde ise Rest Framework’ü anlatacağım. Teknik detaylara girmeden önce Rest Framework nedir biraz bundan bahsedelim.

Rest Framework bizlere hem mobil uygulamalar için,hem web uygulamaları için ,hem de masaüstü uygulamalarımız için ortak bir back-end kodlamamızı sağlayan gelişmiş bir frameworktür. Örnek olarak Rest Framewok ile kodladığınız bir back-end sunucusunu hem mobil uygulamanızda hem de web uygulamanızda ortak olarak kullanabilirsiniz.

Rest Framework’ü front end teknolojileri ile örnek olarak Angular,React,Vue gibi teknolojilerle birlikte kullanarak uygulamalarınızı geliştirebilirsiniz. Rest Framework programlamada ortak bir yapıda response’ları verdiğinden dolayı bu çıktıları ister Angular ile ister React ile kullanabilirsiniz. Peki bu çıktıların türü nedir. Tabii ki de JSON gibi yapılar. İsteğe göre farklı yapılarda da bu çıktıları gönderebiliyorsunuz front-end tarafına tabiiki de. Şimdi Kodlamaya geçelim.


Proje Oluşturma

Klasik bir django projesi oluşturalım hızlıca. Buralar django’yu ilgilendirdiğinden dolayı hızlıca geçeceğim.

django-admin startproject projeName

Projemizi oluşturduk.Şimdi ise projemizi çalıştıralım.

python manage.py runserver

Ardından gerekli tabloların veritabanımızda oluşması için gerekli komutları yazalım.

python manage.py migrate

Ardından admin panelimize girebilmek için de bir super user oluşturalım.

python manage.py createsuperuser

Şimdi ise bir blog projesi oluşturmamız için bir blog uygulaması oluşturalım hızlıca.

python manage.py startapp POSTAPP

Oluşturduğumuz uygulamayı settings.py dosyası altında INSTALLED_APPS dizinine eklemeyi de unutmayalım.

Her şey tamam. Şimdi ise rest framework için gerekli adımlara geçebiliriz.


Bilgisayarımıza Rest Framework’ü kurmak için ise şu komutları terminalimizde çalıştırmamız gerekiyor.

pip install djangorestframework

Ardından ise settings.py dosyasında INSTALLED_APPS dizinine rest framework’ü eklememiz gerekiyor.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'POSTAPP',
]

 

Rest frameworkü de eklediğimize göre artık API oluşturmaya başlayabiliriz. Bunun için oluşturduğumuz uygulama klasörüne API adında bir klasör ve içerisine de bazı dosyaları oluşturmamız gereklidir.

İlk başta oluşturmuş olduğumuz POSTAPP klasörümüzün içerisine API klasörünü oluşturalım.

Ardından ise içerisine şu dosyaları oluşturalım ve ne anlama geldiklerini açıklayalım.

POSTAPP/
   api/
      __init__.py
      views.py
      urls.py
      serializers.py

Şimdi burada oluşturduğumuz dosyaların anlamlarını açıklayalım.

__init__.py dosyası ile bu klasörün bir python modülü olduğunu belirtiyoruz

views.py dosyası ise gelen isteklere göndereceğimiz cevapların olduğu sınıfları ya da fonksiyonları yazacağımız dosyadır.

urls.py dosyası ise djangonun kendi yapısından da tahmin edeceğiniz üzere API url’lerimizi ayarlayacağımız dosyadır

serializers.py dosyası ise gelen querysetlerimizi istediğimiz formatlara (Örnek olarak JSON) sokacak yapılarımızı yazacağımız dosyadır.Bunun detaylarına yavaş yavaş geleceğiz.


İlk önce projemizin ana klasöründe hazır halde gelen urls.py dosyasına gidip oluşturduğumuz API klasörüne göre url path’lerini tanımlayalım.

urlpatterns = [
    path('admin/', admin.site.urls),
    path("api/post/",include("POSTAPP.api.urls",namespace="post")),
]

Halihazırda zaten admin path’imiz yer alıyor. Buna bir de api/post olarak yeni path eklemiş olduk.Include methodu ile de api/post/ ‘a gelen istekleri oluşturduğumuz API klasörünün içerisindeki url dosyamıza yönlendirme işlemini yaptık.

Şimdi ise oluşturduğumuz post için bir model yazalım hızlıca. POSTAPP klasöründeki models.py dosyasına gelelim.

class PostModel(models.Model):
    Author       = models.ForeignKey(User,on_delete=models.CASCADE)
    Title        = models.CharField(max_length=50)
    Content      = models.TextField()
    Draft        = models.BooleanField(default=False)
    CreatedDate  = models.DateTimeField(editable=False)
    ModifiedDate = models.DateTimeField(editable=False)
    Slug          =AutoSlugField(unique=True,editable=False,populate_from="Title")
    Image        = models.ImageField(upload_to="PostImages",null=True,blank=True)

Burada createdDate ve ModifiedDate alanları için auto_now_add=True gibi değerler girmeye çalışmış olabilirsiniz.Ancak bunlar bug’lı olabildiğinden dolayı modelimizin save methodunu override ederek bu işlemi manuel olarak yapacağım.

def save(self,*args,**kwargs):
    if not self.id:
      self.CreatedDate=timezone.now()
      self.ModifiedDate=timezone.now()
      self.Slug = slugify(unidecode(self.Title))
      return super(PostModel,self).save(*args,**kwargs)

Buralar django’nun kendisi ile ilgili olduğundan dolayı çok detaylı durmuyorum üzerinde. Çünkü bizim konumuz rest framework’ü öğrenmek.

Hızlıca da modelimizin Meta sınıfını tanımlayıp gerekli birkaç ayarı da yapalım.

class Meta:
    db_table="Posts"
    verbose_name_plural="Postlar"
    verbose_name="Post"

def __str__(self):
   return self.Title

Modelimizi oluşturduktan sonra veritabanında tabloların oluşması için gerekli kodları terminalimizde yazalım.

python manage.py makemigrations

Bu kodlarla veritabanımızda tabloların oluşması için gerekli python dosyaların oluşmasını sağladık. Tabloların oluşması için ise şu komutları çalıştıracağız

python manage.py migrate

Tablolarımız da oluştuğuna göre sonraki adımlara geçebiliriz.

Şimdi kendimizin oluşturduğu POSTAPP dizini altındaki api klasörü içerisindeki boş urls.py dosyamıza gelelim.

from django.urls import path
from .views import PostListAPIView

app_name="post"
urlpatterns = [
    path("list/",PostListAPIView.as_view(),name="postList"),
]

İlk başta app_name=”post” ile bir uygulama ismini belirttik.

Şimdi ise burda daha oluşturmadığımız view’leri import etmeye çalıştık ve bunları path’imize göre kullanmaya çalıştık. Hemen bu isimlerini yazdığımız views’leri POSTAPP/api dizini altındaki views.py dosyamızda oluşturalım.

İlk başta bize gelen istek ile veritabanında olan tüm postları bir JSON yapısında göndereceğimiz bir view oluşturalım. Bu view’imizin ismini de POSTAPP/api/urls.py dosyasında oluşturmuş olduğumuz ismi kullanalım.

from POSTAPP.models import PostModel
from rest_framework.generics import ListAPIView

class PostListAPIView(ListAPIView):
    serializer_class = PostSerializer
    queryset         = PostModel.objects.all()

Burada yaptıklarımızı anlatalım. Rest Framework’ün içerisinde olan listeleme işlemi için hazır halde gelen ListAPIView sınıfını kullanarak bir view oluşturduk. İlk başta queryset değişkeni ile hangi modeli döndüreceğimizi belirliyoruz. Ve bu modelimizden gelen verileri yani queryseti serialize edecek serializer sınıfımızı belirtmemiz gerekiyor. Sonuçta karşı tarafa queryset göndermeyeceğiz. Serialize edilmiş JSON objesini göndereceğiz. Queryseti JSON objesine çevirecek olan yapı da oluşturmuş olacağımız serializerler olacaktır.

Şimdilik serializer_class değişkenine PostSerializer adında bir serializer oluşturdum.Bu serializeri ise aynı dizinde olduğumuz serializers.py dosyasında oluşturacağız. Hadi gelin hemen oluşturalım.

from rest_framework import serializers

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model  = PostModel
        fields =  ["Author","Title","Content",'Draft','CreatedDate','ModifiedDate']

Burada bir serializer oluşturduk. Meta sınıfımızı da oluşturup içerisine hangi model olduğunu söylememiz gerekiyor. Bunu da oluşturmuş olduğumuz modeli import ederek verebiliriz. Fields alanı ise karşı tarafa oluşturduğumuz modelden hangi alanları göndereceğimizi belirttiğimiz listedir.

Her şey tamam olduğuna göre admin panelinden rastgele bir post oluşturup bunu JSON formatında çekmeye çalışalım.

http://127.0.0.1:8000/api/post/list/ Oluşturmuş olduğumuz url path’ine giriş yapalım ve karşımızda:

Gördüğünüz gibi JSON formatımızda veriler gelmektedir.Şimdi bazı düzenlemeler yapalım. Örnek olarak Author yani kullanıcının ID’si geliyor. Bunu istemiyorsak kullanıcının adını göndermek istiyorsak oluşturduğumuz serializers’imizde şu düzünlemeleri yapmamız gerekiyor.

from rest_framework import serializers

class PostSerializer(serializers.ModelSerializer):
  
    class Meta:
        model  = PostModel
        fields =["Author","Title","Content",'Draft','CreatedDate','ModifiedDate']

    def get_Author(self,obj):
        Author = serializers.SerializerMethodField(method_name="get_Author")
        return obj.Author.username

serializers’in içerisinden SerializerMethodField kullanarak bir method oluşturdum ve bu method içerisine bir self bir de obj olarak iki parametre alıyor. obj objemizi temsil ediyor. ardından obj.Author dedikten sonra ister username ister farklı bir alanımızı karşı tarafa gönderebiliriz.Hemen test edelim.

Gördüğünüz gibi Author kısmında artık kullanıcının ID’si değil,kullanıcının username’i yer alıyor. Buralar isteğinize göre değişebilir.Tamami ile opsiyoneldir.

Hemen gelen Tarih formatlarını da düzenlemeye sokarak gönderelim,sizlere de örnek olur.

from rest_framework import serializers

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model  = PostModel
        CreatedDate  = serializers.SerializerMethodField(method_name="get_CreatedDate")
        ModifiedDate = serializers.SerializerMethodField(method_name="get_ModifiedDate")
        Author       = serializers.SerializerMethodField(method_name="get_Author")
        fields = ["Author","Title","Content",'Draft','CreatedDate','ModifiedDate']

        def get_Author(self,obj):
            return obj.Author.username
          
        def get_CreatedDate(self,obj):
            tarih = datetime.strftime(obj.CreatedDate, '%d/%m/%Y %H:%M:%S')
            return str(tarih)

        def get_ModifiedDate(self,obj):
            tarih = datetime.strftime(obj.ModifiedDate, '%d/%m/%Y %H:%M:%S')
            return str(tarih)
          
          

Tarih formatını datetime modülü ile düzenledikten sonra çıktımıza tekrar bakalım.

Artık gördüğünüz gibi tarih formatımızı da daha güzel bir şekilde karşı tarafa göndermiş bulunuyoruz.


Son olarak da oluşturduğumuz post eğer taslak ise bunu karşı tarafa göndermemek için ufak bir ayar yapalım views’imiz üzerinde.

class PostListAPIView(ListAPIView):
    serializer_class = PostSerializer

    def get_queryset(self):
        queryset = PostModel.objects.filter(Draft=False)
        return queryset

get_queryset özel methodunu yazarak Draft’ı False olan,yani taslakta olmayan nesneleri getirmeyi başardık.

Comments

    There are no comments yet.

Comment