Restful 3 -- 序列化组件(GET/PUT/DELETE接口设计)、视图优化组件

1、序列化组件

  基于上篇随笔的表结构,经过序列化组件的ModelSerializer设计以下三个接口:程序员

GET       127.0.0.1:8000/books/{id}    # 获取一条数据,返回值:{}
PUT       127.0.0.1:8000/books/{id}    # 修改数据,返回值:{}
DELETE    127.0.0.1:8000/books/{id}    # 删除数据,返回空

  urls.py文件:django

from django.urls import path, re_path
from serializer import views
urlpatterns = [
    re_path('books/(\d+)/$', views.BookFilterView.as_view())
]

  Views.py文件:编程

class BookFilterView(APIView):
    def get(self, request, nid):
        book_obj = Book.objects.get(pk=nid)
        serialized_data = BookSerializer(book_obj, many=False)
        return Response(serialized_data.data)

    def put(self, request, nid):
        book_obj = Book.objects.get(pk=nid)
        verified_data = BookSerializer(data=request.data, instance=book_obj, many=False)
        if verified_data.is_valid():
            verified_data.save()
            return Response(verified_data.data)
        else:
            return Response(verified_data.errors)

    def delete(self, request, nid):
        Book.objects.get(pk=nid).delete()
        return Response()

2、视图组件引入

  前面的介绍中,咱们已经经过序列化组件设计除了符合REST规范的五个经常使用接口,如今假设,咱们有多个数据接口,好比(Book,Author,Publish...)等数据表都须要定义相似的接口,能够预见,咱们须要重复定义相似上面的五个接口,这种方式将会致使大量的重复代码,显然,咱们的程序还有不少须要优化的地方,那么,若是是你,将会如何进行优化呢?网络

  首先回顾如下混入类和多继承的知识,有以下一个Animal类:app

class Animal(object):
    def eat(self):
        print("Eating")

    def sleepping(self):
        print("sleepping")

    def flying(self):
        print("flying")

    def wangwang(self):
        print("wangwang")

    def miao(self):
        print("miao")

class Dog(Animal):
    pass

class Cat(Animal):
    pass

  看到这里?结合上面的回顾的混合类和多继承,咱们是否可使用下面的方式优化以前的接口设计呢?socket

class GetAllData():
    def get(self, request):pass

class GetOneData():
    def get(self, request):pass

class DeleteOneData():
    def delete(self, request):pass

class UpdateOneData():
    def put(self, request):pass

class CreateData():
    def post(self, request):pass

class BookView(APIView, GetAllData, CreateData):pass

class BookFilterView(APIView, GetOneData, DeleteOneData, UpdateOneData):pass

  向上面代码这样,将每一个接口都写到独立的类中,而后是哟个多继承,或者成为mixin的这种方式,就能够对咱们程序进行优化,mixin的方式很是常见,在网络编程中学过的socketserver,其源码中就有对mixin的实现,即,假设咱们须要进城的时候,咱们继承进程类,若是咱们须要线程的时候,咱们就继承线程类便可。post

3、视图组件使用

  视图组件是用来优化接口逻辑的。性能

一、使用视图组件的mixin进行接口逻辑优化,上面五个接口能够改写以下:优化

  urls.py代码:url

from django.urls import re_path
from serializer import views

urlpatterns = [
    re_path('books/$', views.BookView.as_view()),
    re_path('books/(?P<pk>\d+)/$', views.BookFilterView.as_view()),
]

  视图views.py代码:

from rest_framework.mixins import (
    ListModelMixin,
    CreateModelMixin,
    DestroyModelMixin,
    UpdateModelMixin,
    RetrieveModelMixin
)
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
# 导入序列化类
from .app_serializers import BookSerializer
from .models import Book, Publish, Author

class BookView(ListModelMixin, CreateModelMixin, GenericAPIView):
    # queryset和serializer_class是固定写法
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    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 BookFilterView(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    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)

  注意:单条数据操做的url有变化,由于咱们在视图中,统一传的是queryset,因此,须要经过传入一个名为pk的命名参数,告诉视图组件,用户须要操做的具体是据。

二、使用视图组件的genericview进行接口逻辑优化

  上面的代码看似已经优化的很是完美了,可是,在一个对性能要求极高的项目里面,咱们的程序还能够继续优化,不断优化程序是每一个程序员必备的技能,也是帮助咱们成长的重要手段。一样的思路,一样的方法,咱们能够将多个接口封装到一个功能类中,以下代码:

from rest_framework import generics

from .app_serializers import BookSerializer
from .models import Book, Publish, Author

class BookView(generics.ListCreateAPIView):
     queryset = Book.objects.all()
     serializer_class = BookSerializer

class BookFilterView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

三、使用视图组件的viewset进行接口逻辑优化

  上面的代码已经看似很是完美了,可是,你有没有发现还有重复代码,该如何改进呢?使用viewset能够进一步优化,以下:

  urls.py文件(注意跟以前有什么不一样):

from django.urls import re_path
from serializer import views

urlpatterns = [
    re_path('books/$', views.BookView.as_view({
        'get': 'list',
        'post': 'create'
    })),
    re_path('books/(?P<pk>\d+)/$', views.BookView.as_view({
        'get': 'retrieve',
        'put': 'update',
        'delete': 'destroy'
    }))

  视图views.py部分:

from rest_framework.viewsets import ModelViewSet
from .app_serializers import BookSerializer
from .models import Book, Publish, Author

class BookView(ModelViewSet):
     queryset = Book.objects.all()
     serializer_class = BookSerializer

  使用方式是否是很简单,接下来去看如下源码都为咱们作了什么吧!其实整个viewset优化方案最重要的地方就是urls.py中传入了参数,而后对参数进行映射关系绑定。

相关文章
相关标签/搜索