Django REST Framework

本節內容html

  • Serializer前端

  • ModelSerializer git

  • API Function-Based Viewgithub

  • API Class-Based Viewdocker

  • API Mixin Viewdjango

  • API Generic Viewjson

  • Viewset和Router後端

 

微服務,先後端分離,如後端kubernetes,docker提供Api,前端AngularJS,Vue,React與Api交互更友好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 

相關文章
相關標籤/搜索