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'),
]
View Code

说明:

  • 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'),
]
View Code

API Generic View (推荐)

# app/api_generic_views.py

from .models import Author, Publisher, Book
from .api_serializers import AuthorSerializer, PublisherSerializer, BookSerializer
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

# urls.py

urlpatterns = [
    # api_generic_views
    url(r'^api/v4/authors/$', api_generic_views.AuthorList.as_view(), name='api-author4-list'),
    url(r'^api/v4/authors/(?P<pk>[0-9]+)/$', api_generic_views.AuthorDetail.as_view(), name='api-author4-detail'),
]
View Code

Viewset和Router(推荐)

# app/api_viewsets.py
from .models import Author, Publisher, Book
from .api_serializers import AuthorSerializer, PublisherSerializer, BookSerializer
from rest_framework import viewsets


class AuthorViewSet(viewsets.ModelViewSet):
    # 封装增、删、改、查
    queryset = Author.objects.all()
    serializer_class = AuthorSerializer


# urls.py
from app import api_viewsets
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'authors', api_viewsets.AuthorViewSet)

urlpatterns += [
    url(r'^api/v5/', include(router.urls)),
]

相关配置

# settings.py
REST_FRAMEWORK = {
    # 分页
    'PAGE_SIZE': 3,

    # 认证
    'DEFAULT_AUTHENTICATION_CLASSES': {
        'rest_framework.authentication.BasciAuthenticaion',
        # 'rest_framework.authentication.SessionAuthentication',
        # 'rest_framework.authentication.TokenAuthentication',
    },

    # 授权
    'DEFAULT_PERMISSION_CLASSES': {
        'rest_framework.permissions.IsAuthenticated',
    },
}

'''
# token认证其他配置
INSTALLED_APPS = [
    ......
    'rest_framework.authtoken',
]
'''

代码示例请参考

https://github.com/Jonathan1314/LearnAPI 

原文地址:https://www.cnblogs.com/jonathan1314/p/7553277.html