Install RestFramework
$ pip install djangorestframework
# settings.py
INSTALLED_APPS = (
...
'rest_framework',
)
创建Serializer class
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='ibuler@qq.com')
>>> m = Author.objects.create(first_name='ma', last_name='ge', email='ma@magedu.com')
>>> serializer = AuthorSerializer(g)
>>> serializer.data
ReturnDict([('id', 1),
('first_name', u'guang'),
('last_name', u'hongwei'),
('email', u'ibuler@qq.com')])
>>> content = JSONRenderer().render(serializer.data)
>>> content
'{"id": 1, "first_name": "guang", "last_name": "hongwei", "email": "ibuler@qq.com"}'
>>> from django.utils.six import BytesIO
>>> content = '{"first_name": "li", "last_name": "xueming", "email": "comyn@magedu.com"}'
>>> stream = BytesIO(content)
>>> data = JSONParser().parse(stream)
>>> data
{u'email': u'comyn@magedu.com', 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', 'comyn@magedu.com')])
>>> serializer.validated_data # 转化成Python类型
OrderedDict([('first_name', 'li'),
('last_name', 'xueming'),
('email', 'comyn@magedu.com')])
>>> 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 Function View
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 And Response
- request
- request.POST # Only handles form data. Only works for ‘POST’ method.
- request.data # Handles arbitrary data. Works for ‘POST’, ‘PUT’ and ‘PATCH’ methods.
- Response(data) # Renders to content type as requested by the client.
包装API View
from rest_framework.decorators import api_view
...
@api_view(['GET', 'POST'])
def author_list(request):
pass
使用Class-based Views
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
使用Mixin
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)
使用Generic class-based views
...
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
- rest framework内置权限
- AllowAny
- IsAuthenticated
- IsAdminUser
- IsAuthenticatedOrReadOnly
- DjangoModelPermissions
- DjangoModelPermissionsOrAnonReadOnly
- DjangoObjectPermissions
- 全局配置默认权限
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
}
- view中使用鉴权
# 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,)
- Django支持认证方式
- Basic认证
- Session认证
- Token认证
- 自定义认证
djangorestframework默认是使用Basic认证
# settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
# 'rest_framework.authentication.SessionAuthentication',
)
}
- 使用Basic认证
postman请求,填写Authorization,用户名admin,密码django user admin的密码 - 使用token认证
- INSTALLED_APPS加入rest_framework.authtoken
INSTALLED_APPS = ( ... 'rest_framework.authtoken' )
- 启用TOKEN认证
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.BasicAuthentication', 'rest_framework.authentication.TokenAuthentication', ) }
- 创建token
>>> from rest_framework.authtoken.models import Token >>> token = Token.objects.create(user=...) >>> print(token.key)
- 使用Token请求postman,设置Authorization头
Authorization:Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
Viewset和Router
# 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
魏晓蕾
博客专家
发布了227 篇原创文章 · 获赞 605 · 访问量 130万+
关注