django-tastypie czyli wystawianie RESTowego API w aplikacjach Django

django-tastypie to obecnie chyba najlepsza aplikacja do wystawiania RESTowego API dla naszych aplikacji Django. Kod znajdziemy na githubie, a dokumentację na readthedocs.org. Za pomocą tastypie w łatwy sposób możemy udostępnić dane zapisane w wybranym modelu. API może być konfigurowane - np. wzbogacone o autoryzację, czy filtrowanie danych i dostępnych operacji jakie użytkownicy API mogą wykonać.

Szybki start

Instalujemy standardowo:
pip install django-tastypie
Następnie dodajemy tastypie do INSTALLED_APPS i gotowe.

Teraz możemy zająć się tworzeniem klas definiujących API dla poszczególnych modeli. W dokumentacji zastosowano katalog "api" w katalogu aplikacji: NAZWA_APLIKACJI/api/resources.py. Można też np. użyć pliku api.py bezpośrednio w katalogu aplikacji, czy praktycznie inny dowolny układ.

Wystawiamy API

Na potrzeby przykładów wykorzystałem jedną z moich aplikacji. Posiada ona model JobOffer zawierający oferty pracy. W pliku api.py stworzyłem taki oto kod:
from tastypie.resources import ModelResource

from jobs import models

class JobOfferResource(ModelResource):
    class Meta:
        queryset = models.JobOffer.objects.all()
        resource_name = 'joboffer'

Żeby wystawić API dla danego zbioru danych (QuerySetu) trzeba zdefiniować klasę dziedziczącą po ModelResource - zasób. W meta podajemy interesujący nas QuerySet i opcjonalnie resource_name - nazwa zasobu jaka będzie stosowana w URLach.

Żeby wystawić URLe dla zasobu w urls.py dodajemy:

from tastypie.api import Api
from jobs.api import JobOfferResource

v1_api = Api(api_name='v1')
v1_api.register(JobOfferResource())
I do reguł dodajemy:
(r'^api/', include(v1_api.urls)),
Gotowe. Pod adresem http://localhost:8000/api/v1/joboffer/?format=json dostaniemy listę obiektówy wystawionych przez API. W tym przypadku ofert pracy. Dostępne są też inne linki, np. http://localhost:8000/api/v1/joboffer/schema/?format=json opisująca strukturę danych, jak i np. listująca dostępne metody - typy żądań HTTP. Struktura generowanych linków dla zasobu opisana jest w dokumentacji.

Opcje dodatkowe

Zasób można konfigurować. Za pomocą allowed_methods możemy ograniczyć metody HTTP jakie można wykorzystać do interakcji z API - np. tylko żądania GET do pobierania danych. fields może zawierać listę pól modelu jakie mają pojawić się w serializowanych danych wystawianych przez API:
class JobOfferResource(ModelResource):
    class Meta:
        queryset = models.JobOffer.objects.all()
        resource_name = 'joboffer'
        allowed_methods = ['get']
        fields = ['id', 'position', 'city', 'published_at']
Możemy użyć też metody dehydrate do dokonania zmian w poszczególnych obiektach przez ich serializacją, np wywołanie metody modelu:
from tastypie.resources import ModelResource

from jobs import models

class JobOfferResource(ModelResource):
    class Meta:
        queryset = models.JobOffer.objects.all()
        resource_name = 'joboffer'
        allowed_methods = ['get']
        fields = ['id', 'position', 'city', 'published_at']

    def dehydrate(self, bundle):
        bundle.data['unicode'] = bundle.obj.__unicode__()
        return bundle

bundle.data zawiera słownik z danymi jakie trafią do serializacji.

API obsługuje też autoryzację - np. dostęp po zalogowaniu:
from tastypie.resources import ModelResource
from tastypie.authentication import BasicAuthentication
from tastypie.authorization import DjangoAuthorization

from jobs import models

class JobOfferResource(ModelResource):
    class Meta:
        queryset = models.JobOffer.objects.all()
        resource_name = 'joboffer'
        allowed_methods = ['get']
        fields = ['id', 'position', 'city', 'published_at']
        authentication = BasicAuthentication()
        authorization = DjangoAuthorization()

    def dehydrate(self, bundle):
        bundle.data['unicode'] = bundle.obj.__unicode__()
        return bundle
Możliwości jest znacznie więcej. Wszystko opisano w dokumentacji.
RkBlog

Django, 18 September 2012

Comment article
Comment article RkBlog main page Search RSS Contact