Django REST Framework
本节内容
-
Serializer
-
ModelSerializer
-
API Function-Based View
-
API Class-Based View
-
API Mixin View
-
API Generic View
-
Viewset和Router
微服务,前后端分离,如后端kubernetes,docker提供Api,前端AngularJS,Vue,React与Api交互更友好
Django Rest Framework 是Django用来写Restful Api框架,风格完全和Django一样,使用起来好像是Django本身提供的
Github star 已超过8500,是Django下最可靠的Restful框架
官方网站:http://www.django-rest-framework.org/
Serializer
Serializer和Form功能一样,都可以将用户提交的数据转换为Python数据结构,同样可以完成校验操作
Form用在POST提交的form表单
Serializer用在用户提交的json
1. Serializer的定义
# books.models.py class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField() def __str__(self): return '%s %s' % (self.first_name, self.last_name) # books.api_serailizer.py from rest_framework import serializers from books.models import Author 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)
2. Serializer提供的接口
serializer = AuthorSerializer(author),得到serializer.data,再把该数据渲染成前端的json格式,JSONRenderer().render(serializer.data)
data=JSONParse().parse(stream); serializer=AuthorSerailizer(data=data),可以对serializer进行操作
ModelSerializer
ModelSerializer类似ModelForm
class AuthorSerializer(serializers.ModelSerializer): class Meta: model = Author fields = ('id', 'first_name', 'last_name', 'email')
API Function-Based View
实现列表、详情,以及对应的 GET、POST、PUT、DELETE方法
# app/api_func_views.py 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 .api_serializers import AuthorSerializer class JSONResponse(HttpResponse): 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) return JSONResponse('Request metho not support', status=400) @csrf_exempt def author_detail(request, pk): try: author = Author.objects.get(pk=pk) except Author.DoesNotExist: return JSONResponse("Not found", status=404) if request.method == 'GET': serializer = AuthorSerializer(author) return JSONResponse(serializer.data) elif request.method == "PUT": 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) elif request.method == "DELETE": author.delete() return JSONResponse('Delete successfully',status=204) # books.urls.py from django.conf.urls import url from . import views from . import api_views urlpatterns = [ url(r'^api/v1/authors/$', api_views.author_list, name='api-author-list'), url(r'^api/v1/authors/(?P<pk>[0-9]+)/$', api_views.author_detail, name='api-author-detail'), ]
说明:
1. JSONRenderer 和 JSONParser
2. 对象 ---> JSON 单个、多个
3. 返回到前端,内容类型定义 kwargs['content_type']='application/json'
4. from rest_framework.resonse import Response 可以根据请求方式的不同,返回html还是json
调用结果展示
包装api view
from rest_framework.decorators import api_view @api_view(['GET', 'POST']) def author_list(request): pass
API Class-Based View
# app/api_class_views.py from django.http import Http404 from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from .models import Author, Publisher, Book from .api_serializers import AuthorSerializer, PublisherSerializer, BookSerializer 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) # urls.py urlpatterns = [ # api_class_views url(r'^api/v2/authors/$', api_class_views.AuthorList.as_view(), name='api-author2-list'), url(r'^api/v2/authors/(?P<pk>[0-9]+)/$', api_class_views.AuthorDetail.as_view(), name='api-author2-detail'), ]
说明:
-
APIView类似Django Class Based View中的View
-
注意url的规范
API Mixin View
# app/api_mixin_views.py from .models import Author, Publisher, Book from .api_serializers import AuthorSerializer, PublisherSerializer, BookSerializer from rest_framework import mixins 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 put(self, request, *args, **kwargs): return self.update(request, *args, **kwargs) def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs) # urls.py urlpatterns = [ # api_mixin_views url(r'^api/v3/authors/$', api_mixin_views.AuthorList.as_view(), name='api-author3-list'), url(r'^api/v3/authors/(?P<pk>[0-9]+)/$', api_class_views.AuthorDetail.as_view(), name='api-author3-detail'), ]