zoukankan      html  css  js  c++  java
  • Restful 3 -- 序列化组件(GET/PUT/DELETE接口设计)、视图优化组件

    一、序列化组件

      基于上篇随笔的表结构,通过序列化组件的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文件:

    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()

    二、视图组件引入

      前面的介绍中,我们已经通过序列化组件设计除了符合REST规范的五个常用接口,现在假设,我们有多个数据接口,比如(Book,Author,Publish...)等数据表都需要定义类似的接口,可以预见,我们需要重复定义类似上面的五个接口,这种方式将会导致大量的重复代码,显然,我们的程序还有很多需要优化的地方,那么,如果是你,将会如何进行优化呢?

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

    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

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

    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的实现,即,假设我们需要进城的时候,我们继承进程类,如果我们需要线程的时候,我们就继承线程类即可。

    三、视图组件使用

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

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

      urls.py代码:

    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的命名参数,告诉视图组件,用户需要操作的具体是据。

    2、使用视图组件的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

    3、使用视图组件的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中传入了参数,然后对参数进行映射关系绑定。

  • 相关阅读:
    gevent实现基于epoll和协程的服务器
    用greenlet实现协程消费者生产者
    More is better(MST)(求无向图中最大集合元素个数)
    小希的迷宫(MST单棵树判断法则)
    畅通工程再续(MST)
    畅通工程再续
    畅通工程
    还是畅通工程(MST)
    Minimum Inversion Number
    Who Gets the Most Candies?(线段树 + 反素数 )
  • 原文地址:https://www.cnblogs.com/wxj1129549016/p/10097653.html
Copyright © 2011-2022 走看看