Web API с помощью Django REST framework

в 1:34, , рубрики: api, django, Django REST framework, Веб-разработка, метки: , ,

Веб-cервис (англ. web service) — идентифицируемая веб-адресом программная система со стандартизированными интерфейсами. Веб-службы могут взаимодействовать друг с другом и со сторонними приложениями посредством сообщений, основанных на определённых протоколах (XML, JSON и т. д.). Веб-служба является единицей модульности при использовании сервис-ориентированной архитектуры приложения.

Одним из подходов создания веб сервиса является rest.
Rest (сокр. англ. Representational State Transfer, «передача состояния представления») — стиль построения архитектуры распределенного приложения. Данные в REST должны передаваться в виде небольшого количества стандартных форматов (например HTML, XML, JSON). Сетевой протокол (как и HTTP) должен поддерживать кэширование, не должен зависеть от сетевого слоя, не должен сохранять информацию о состоянии между парами «запрос-ответ». Утверждается, что такой подход обеспечивает масштабируемость системы и позволяет ей эволюционировать с новыми требованиями.


Django REST framework — удобный инструмент для работы с rest основанный на идеологии фреймворка Django.

Требования к окружению:
Python (2.6, 2.7)
Django (1.3, 1.4, 1.5)

По желанию:
Markdown
PyYAML
django-filter

Установка

Установить можно привычной для нас командой pip:

pip install djangorestframework

И можно поставить дополнительные пакеты:

pip install markdown  
pip install pyyaml    
pip install django-filter  

Или же сделать клон проекта с Github:

git clone git@github.com:tomchristie/django-rest-framework.git
cd django-rest-framework
pip install -r requirements.txt
pip install -r optionals.txt

Не забываем прописать приложение в INSTALLED_APPS:

INSTALLED_APPS = (
    ...
    'rest_framework',        
)

А также добавить запись в urls.py:

urlpatterns = patterns('',
    ...
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
)

Url можно ставить любой на Ваш вкус, главное подключить файл с урлами rest framework (rest_framework.urls).

Пример использования

Создадим API для работы с пользователями и их группами.

Для начала нам нужно определить некоторые Serializers, которые мы будем использовать

from django.contrib.auth.models import User, Group, Permission
from rest_framework import serializers

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'groups')

class GroupSerializer(serializers.HyperlinkedModelSerializer):
    permissions = serializers.ManySlugRelatedField(
        slug_field='codename',
        queryset=Permission.objects.all()
    )

    class Meta:
        model = Group
        fields = ('url', 'name', 'permissions')
Пропишем views.py

from django.contrib.auth.models import User, Group
from rest_framework import generics
from rest_framework.decorators import api_view
from rest_framework.reverse import reverse
from rest_framework.response import Response
from quickstart.serializers import UserSerializer, GroupSerializer

@api_view(['GET'])
def api_root(request, format=None):
    """
    The entry endpoint of our API.
    """
    return Response({
        'users': reverse('user-list', request=request),
        'groups': reverse('group-list', request=request),
    })

class UserList(generics.ListCreateAPIView):
    """
    API endpoint that represents a list of users.
    """
    model = User
    serializer_class = UserSerializer

class UserDetail(generics.RetrieveUpdateDestroyAPIView):
    """
    API endpoint that represents a single user.
    """
    model = User
    serializer_class = UserSerializer

class GroupList(generics.ListCreateAPIView):
    """
    API endpoint that represents a list of groups.
    """
    model = Group
    serializer_class = GroupSerializer

class GroupDetail(generics.RetrieveUpdateDestroyAPIView):
    """
    API endpoint that represents a single group.
    """
    model = Group
    serializer_class = GroupSerializer

Мы создали функцию api_root, которая будет отправной точкой для нашего API. И четыре класса, для связи с моделями и указали какие serializers нужно при этом использовать.

Добавим ссылки в urls.py

from django.conf.urls import patterns, url, include
from rest_framework.urlpatterns import format_suffix_patterns
from quickstart.views import UserList, UserDetail, GroupList, GroupDetail

urlpatterns = patterns('quickstart.views',
    url(r'^$', 'api_root'),
    url(r'^users/$', UserList.as_view(), name='user-list'),
    url(r'^users/(?P<pk>d+)/$', UserDetail.as_view(), name='user-detail'),
    url(r'^groups/$', GroupList.as_view(), name='group-list'),
    url(r'^groups/(?P<pk>d+)/$', GroupDetail.as_view(), name='group-detail'),
)

# Format suffixes
urlpatterns = format_suffix_patterns(urlpatterns, allowed=['json', 'api'])

# Default login/logout views
urlpatterns += patterns('',
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
)

Важный момент использование user-detail и group-detail. Для корректной связи с views.py нужно использовать именование вида {modelname}-detail.
В format_suffix_patterns мы указали суфикс для наших urls.

Settings

INSTALLED_APPS = (
    ...
    'rest_framework',
)

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAdminUser',),
    'PAGINATE_BY': 10
}
Результат

Используя curl в консоли испытаем что же получилось:

bash: curl -H 'Accept: application/json; indent=4' -u admin:password http://127.0.0.1:8000/users/ 
{
    "count": 2, 
    "next": null, 
    "previous": null, 
    "results": [
        {
            "email": "admin@example.com", 
            "groups": [], 
            "url": "http://127.0.0.1:8000/users/1/", 
            "username": "admin"
        }, 
        {
            "email": "tom@example.com", 
            "groups": [                ], 
            "url": "http://127.0.0.1:8000/users/2/", 
            "username": "tom"
        }
    ]
}

В браузере можно увидить что то подобное:
Web API с помощью Django REST framework

Ссылки:
Сайт проекта
Github

P.S. Для работы с rest в django есть еще одно не плохое приложение именуемое как django-piston. При желании можно и о нем написать, хотя в использовании оно довольно не сложное.

Автор: int22h

Источник

Поделиться

* - обязательные к заполнению поля