RestFramework 설치
$ pip install djangorestframework
# settings.py
INSTALLED_APPS = (
...
'rest_framework',
)
만들기 시리얼 클래스
from rest_framework import serializers
from .models import Book, Author, Publisher
class AuthorSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
first_name = serializers.CharField(max_length=100)
last_name = serializers.CharField(required=False, allow_blank=True, max_length=100)
email = serializers.EmailField(required=False, allow_blank=True, max_length=100)
def create(self, validated_data):
# Create and return a new 'Snippet' instance, given the validated data.
return Author.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.first_name = validated_data.get('first_name', instance.first_name)
instance.last_name = validated_data.get('last_name', instance.last_name)
instance.email = validated_data.get('email', instance.email)
instance.save()
return instance
제공되는 API를 사용하여
>>> from books.serializers import *
>>> from rest_framework.renderers import JSONRenderer
>>> from rest_framework.parsers import JSONParser
>>> g = Author.objects.create(first_name='guang', last_name='hongwei', email='[email protected]')
>>> m = Author.objects.create(first_name='ma', last_name='ge', email='[email protected]')
>>> serializer = AuthorSerializer(g)
>>> serializer.data
ReturnDict([('id', 1),
('first_name', u'guang'),
('last_name', u'hongwei'),
('email', u'[email protected]')])
>>> content = JSONRenderer().render(serializer.data)
>>> content
'{"id": 1, "first_name": "guang", "last_name": "hongwei", "email": "[email protected]"}'
>>> from django.utils.six import BytesIO
>>> content = '{"first_name": "li", "last_name": "xueming", "email": "[email protected]"}'
>>> stream = BytesIO(content)
>>> data = JSONParser().parse(stream)
>>> data
{u'email': u'[email protected]', u'first_name': u'li', u'last_name': u'xueming'}
>>> serializer = AuthorSerializer(data=data)
>>> serializer.is_valid()
>>> serializer.data # 不是Python类型
ReturnDict([('first_name', 'li'),
('last_name', 'xueming'),
('email', '[email protected]')])
>>> serializer.validated_data # 转化成Python类型
OrderedDict([('first_name', 'li'),
('last_name', 'xueming'),
('email', '[email protected]')])
>>> serializer.save()
>>> serializer = AuthorSerializer(Author.objects.all(), many=True)
>>> serializer.data
사용 ModelSerializers
class AuthorSerializer(serializers.ModelSerializer):
class Meta:
model = Author
fields = ('id', 'first_name', 'last_name', 'email')
API 함수보기
from django.http import HttpResponse
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
from .models import Author
from .serializers import AuthorSerializer
class JSONResponse(HttpResponse):
# An HttpResponse that renders its content into JSON.
def __init__(self, data, **kwargs):
content = JSONRenderer().render(data)
kwargs['content-type'] = 'application/json'
super(JSONResponse, self).__init__(content, **kwargs)
@csrf_exempt
def author_list(request):
if request.method == 'GET':
authors = Author.objects.all()
serializer = AuthorSerializer(authors, many=True)
return JSONResponse(serializer.data)
elif request.method == 'POST':
data = JSONParser().parse(request)
serializer = AuthorSerializer(data=data)
if serializer.is_valid():
serializer.save()
return JSONResponse(serializer.data, status=201)
return JSONResponse(serializer.errors, status=400)
@csrf_exempt
def author_detail(request, pk):
# Retrieve, update or delete a code snippet.
try:
author = Author.objects.get(pk=pk)
except Author.DoesNotExist:
return JSONResponse('', status=404)
if request.method == 'GET':
serializer = AuthorSerializer(author)
return JSONResponse(serializer.data)
elif request.method == 'PUT':
data = JSONParser().parse(request)
serializer = AuthorSerializer(author, data=data)
if serializer.is_valid():
serializer.save()
return JSONResponse(serializer.data)
return JSONResponse(serializer.errors, status=400)
elif request.method == 'DELETE':
author.delete()
return JSONResponse('', status=204)
# urls.py
urlpatterns = [
url(r'^authors/$', views.author_list, name='author_list'),
url(r'^authors/(?P<pk>[0-9]+)/$', views.author_detail, name='author_detail'),
]
요청 및 응답
- 의뢰
- request.POST # 만 핸들이 데이터를 형성한다. 만 'POST'방법을 작동합니다.
- request.data # 핸들 데이터를 임의. 'PUT'과 '패치'방법 'POST'에 대한 작품.
- 클라이언트의 요청에 따라 응답 (데이터) # 콘텐츠 유형에 렌더링합니다.
API보기를 포장
from rest_framework.decorators import api_view
...
@api_view(['GET', 'POST'])
def author_list(request):
pass
사용 클래스 기반의 뷰
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
class AuthorList(APIView):
def get(self, request, format=None):
authors = Author.objects.all()
serializer = AuthorSerializer(authors, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = AuthorSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class AuthorDetail(APIView):
def get_object(self, pk):
try:
return Author.objects.get(pk=pk)
except Author.DoesNotExist:
return Http404
def get(self, request, pk, format=None):
author = self.get_object(pk)
serializer = AuthorSerializer(author)
return Response(serializer.data)
def put(self, request, pk, format=None):
author = self.get_object(pk)
serializer = AuthorSerializer(author, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
author = self.get_object(pk)
author.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
- APIView
사용 믹스 인
from rest_framework import mixins
# from rest_framework.mixins import CreateModelMixin, ListModelMixin
from rest_framework import generics
class AuthorList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
queryset = Author.objects.all()
serializer_class = AuthorSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
class AuthorDetail(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView):
queryset = Author.objects.all()
serializer_class = AuthorSerializer
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
class AuthorDetail(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView):
queryset = Author.objects.all()
serializer_class = AuthorSerializer
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
使用 일반 클래스 기반 뷰
...
from rest_framework import generics
class AuthorList(generics.ListCreateAPIView):
queryset = Author.objects.all()
serializer_class = AuthorSerializer
class AuthorDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Author.objects.all()
serializer_class = AuthorSerializer
페이징
# settings.py
REST_FRAMEWORK = {
'PAGE_SIZE': 10
}
인증 및 권한 부여
참조 : HTTP : //www.django-rest-framework.org/api-guide/permissions/#api-reference
- 나머지 프레임 워크에 내장 된 허가
- AllowAny
- IsAuthenticated는
- IsAdminUser
- IsAuthenticatedOrReadOnly
- DjangoModelPermissions
- DjangoModelPermissionsOrAnonReadOnly
- DjangoObjectPermissions
- 글로벌 기본 권한
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
}
- 인증 사용을보고
# views.py
from rest_framework import permissions
class UserList(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (permissions.IsAuthenticated, )
- 사용자 권한
from rest_framework import permissions
class IsSuperUser(permissions.BasePermission):
def has_permission(self, request, view):
return request.user.is_superuser()
# views
from .permissions import IsSuperUser
class UserList(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (IsSuperUser,)
- 장고 지원 인증
- 기본 인증
- 세션 인증
- 토큰 인증
- 사용자 정의 인증
djangorestframework 기본값은 기본 인증을 사용하는 것입니다
# settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
# 'rest_framework.authentication.SessionAuthentication',
)
}
- 사용 기본 인증의
우편 배달부 요청, 권한 부여, 사용자 이름 admin에 채우기, 사용자 관리자 암호 장고 비밀번호 - 사용 토큰 인증
- INSTALLED_APPS 加入 rest_framework.authtoken
INSTALLED_APPS = ( ... 'rest_framework.authtoken' )
- 인증을 사용 TOKEN
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.BasicAuthentication', 'rest_framework.authentication.TokenAuthentication', ) }
- 토큰을 생성
>>> from rest_framework.authtoken.models import Token >>> token = Token.objects.create(user=...) >>> print(token.key)
- 인증 헤더에서 제공하는 사용 토큰 요청 우편 배달부,
Authorization:Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
뷰셋 및 라우터
# views.py
from rest_framework import viewsets
from .models import Author
from .serializers import AuthorSerializer
# version 1
class AuthorViewSet(viewsets.ReadOnlyModelViewSet):
# This viewset automatically provides 'list' and 'detail' actions.
queryset = Author.objects.all()
serializer_class = AuthorSerializer
# version 2
class AuthorViewSet(viewsets.ModelViewSet):
# This viewset automatically provides 'list', 'create', 'retrieve', 'update' and 'destroy' actions.
queryset = Author.objects.all()
serializer_class = AuthorSerializer
permission_classes = (permissions.IsAuthenticationOrReadOnly,)
#urls.py
from . import views
from rest_framework import renders
# version 1
author_list = AuthorViewSet.as_view({
'get': 'list',
'post': 'create',
})
author_detail = AuthorViewSet.as_view({
'get': 'retrieve',
'put': 'update',
'patch': 'partial_update',
'delete': 'destroy',
})
urlpatterns += [
url(r'^authors/$', author_list, name='author-list'),
url(r'^authors/(?P<pk>[0-9]+)/$', author_detail, name='author-detail'),
]
# version 2 user Routers
from django.conf.urls import url, include
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'authors', views.AuthorViewSet)
urlpatterns = [
url(r'^publisher/(?P<pk>[0-9]+)/$', views.PublisherDetail.as_view()),
]
urlpatterns += [
url(r'^', include(router.urls)),
]
urlpatterns += router.urls