İçeriğe geç

Django Rest Framework XML Parse & Render

Giriş.

Rest Framework ile geliştirme yaparken aynı endpoint üzerine gelen farklı formatlardaki istekleri işleyebilir yine aynı endpoint üzerinden farklı formatlara sahip cevaplar dönebilirsiniz.

Desteklenen cevap formatları renderer_classes, desteklenen istek formatları ise parser_classes üzerinde belirtilir.

Modern API’lar geliştirirken en çok kullanılan veri alış-veriş formatı JSON olsada bazı durumlarda farklı formatlara ihtiyaç duyabiliriz. Örneğin API’nızı kullanacak olan nispeten eski istemciler varsa sizden XML formatında veri alış-verişini desteklemeniz istenebilir.

Bugün XML parsing ve rendering işlemlerinin DRF ile nasıl yapılabileceğine göz atacağız.


Kurulum ve kullanım.

Eski sürümlerde XML rendering ve parsing için DRF yerleşik bir çözüm barındırıyor olsa da daha sonraki sürümlerde bu özellik 3rd party olarak RestFramework XML paketi altında sunulmakta ve geliştirilmekte.

O yüzden ilk olarak geliştirme ortamımıza bu paketi kuralım.

Bu paket şu anda Python 3.5+ ve Django 2.2+ sürümlerine destek vermekte.

$ pip install djangorestframework-xml

Örnek bir kullanım için, varsayılan kullanıcı modelini kullanacağız.

Kullanıcıları oluştururken ve listelerken kullanılacak olan serializer ve viewı tanımlayalım.

# your_app/serializers.py

from django.contrib.auth import get_user_model
from rest_framework import serializers

User = get_user_model()


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = "__all__"
        extra_kwargs = {"password": {"write_only": True}}
# your_app/views.py

from django.contrib.auth import get_user_model
from rest_framework.generics import ListCreateAPIView
from rest_framework.parsers import JSONParser
from rest_framework.renderers import JSONRenderer
from rest_framework_xml.parsers import XMLParser
from rest_framework_xml.renderers import XMLRenderer

from users.serializers import UserSerializer

User = get_user_model()


class UserListView(ListCreateAPIView):
    serializer_class = UserSerializer
    queryset = User.objects.all()
    renderer_classes = [JSONRenderer, XMLRenderer]
    parser_classes = [JSONParser, XMLParser]

DRF plugabble bir mimariye sahiptir. Dolayısıyla restframework-xml paketi altından import ettiğimiz XMLParser ve XMLRenderer sınıflarını spesifik bir view üzerine kayıt edebiliriz.

DRF gelen isteğin, Accept headerına göre yada query param format değerine göre, renderer_classes üzerinde tanımlı olan formatlardan biri ile cevap dönmeye çalışacaktır.

Listelemeyi test edelim.

$ http --body  "localhost:9001/api/users/?format=xml"
<?xml version="1.0" encoding="utf-8"?>
<root>
  <list-item>
    <id>1</id>
    <last_login/>
    <is_superuser>True</is_superuser>
    <username>egehan</username>
    <first_name/>
    <last_name/>
    <email>egehan.gundogdu@gmail.com</email>
    <is_staff>True</is_staff>
    <is_active>True</is_active>
    <date_joined>2022-02-20T12:07:21.009928Z</date_joined>
    <groups/>
    <user_permissions/>
  </list-item>
</root>

XML formatta bir body ile kullanıcı kayıt edelim.

$ printf '<?xml version="1.0" encoding="utf-8"?>
<root>
    <username>egehan_xml</username>
    <first_name>egehan</first_name>
    <last_name>xml</last_name>
    <email>egehan.gundogdu@xml.com</email>
    <password>secure_password</password>
</root>'| http  --follow --timeout 3600 POST 'http://localhost:9001/api/users/' \
 Accept:'application/xml' \
 Content-Type:'application/xml'
HTTP/1.1 201 Created
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 409
Content-Type: application/xml; charset=utf-8
Date: Sun, 20 Feb 2022 13:33:37 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.9.6
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

<?xml version="1.0" encoding="utf-8"?>
<root>
  <id>10</id>
  <last_login/>
  <is_superuser>False</is_superuser>
  <username>egehan_xml</username>
  <first_name>egehan</first_name>
  <last_name>xml</last_name>
  <email>egehan.gundogdu@xml.com</email>
  <is_staff>False</is_staff>
  <is_active>True</is_active>
  <date_joined>2022-02-20T13:33:37.428488Z</date_joined>
  <groups/>
  <user_permissions/>
</root>

Güzel! Artık XML formatta gelen bir istek gövdesini parse edebiliyor ve cevabı yine aynı formatta dönebiliyoruz.

Fakat dikkat ettiyseniz, listeleme sırasında XML deki en dıştaki elementin tagi root, serialize edilen her objenin kapsayıcı tagi ise list-item.

Eğer burada da bir özelleştirmeye ihtiyacınız varsa custom bir renderer sınıfı yazabilir ve viewınıza kayıt edebilirsiniz.

from rest_framework_xml.renderers import XMLRenderer

class CustomUserXMLRenderer(XMLRenderer): 
    item_tag_name = "user" 
    root_tag_name = "user-list"
$ http --body "http://localhost:9001/api/users/?format=xml"
<?xml version="1.0" encoding="utf-8"?>
<user-list>
  <user>
    <id>1</id>
    <last_login/>
    <is_superuser>True</is_superuser>
    <username>egehan</username>
    <first_name/>
    <last_name/>
    <email>egehan.gundogdu@gmail.com</email>
    <is_staff>True</is_staff>
    <is_active>True</is_active>
    <date_joined>2022-02-20T12:07:21.009928Z</date_joined>
    <groups/>
    <user_permissions/>
  </user>
</user-list>

Son olarak eğer tüm endpointlerinizin, XML render ve parse edebilme yeteneğine sahip olmasını istiyorsanız doğrudan DRF global settings olarak belirtebilirsiniz.

# your_project/settings.py
REST_FRAMEWORK = {
    "DEFAULT_PARSER_CLASSES" : [
        "rest_framework.parsers.JSONParser",
        "rest_framework_xml.parsers.XMLParser"
    ],
    "DEFAULT_RENDERER_CLASSES" : [
        "rest_framework.renderers.JSONRenderer",
        "rest_framework_xml.renderers.XMLRenderer",
    ]
}

DRF (ve tabiki pure Django) ihtiyaçlar doğrultusunda kolay ve hızlıca genişletilebilen, topluluğu oturmuş çok kuvvetli bir web geliştirme aracı. Daha önce Python ve Django ile geliştirme yapmamış iseniz bir şans vermeniz web geliştirmeye bakış açınızı fazlasıyla değiştirebilir 🙂

Bu blogta daha fazla DRF hakkında okumak isterseniz link burada.

RestFramework-XML kütüphanesi dökümantasyonu.

Django Rest Framework dökümantasyon linki ise burada.

Keyifli ve sağlıklı günler!

Tarih:Blog

İlk Yorumu Siz Yapın

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.

Göster
Gizle