博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
DRF(3) - 序列化组件(GET/PUT/DELETE接口设计)、视图优化组件
阅读量:2240 次
发布时间:2019-05-09

本文共 5230 字,大约阅读时间需要 17 分钟。

一、序列化组件

  基于上篇随笔的表结构,通过序列化组件的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_pathfrom serializer import viewsurlpatterns = [    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") class Bird(Animal):  def flying(self):      print("flying")class Bee(Animal):  def flying(self):      print("flying")

  此时,我们可以改为如下代码(python支持多继承,不是所有语言都有这个特点):

class Animal(object):    def eat(self):        print("Eating")    def sleepping(self):        print("sleepping")class Flying(object):    def flying(self):      print("flying")class Bird(Animal, Flying):  passclass Bee(Animal, Flying):  pass

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

class GetAllData():    def get(self, request):passclass GetOneData():    def get(self, request):passclass DeleteOneData():    def delete(self, request):passclass UpdateOneData():    def put(self, request):passclass CreateData():    def post(self, request):passclass BookView(APIView, GetAllData, CreateData):passclass BookFilterView(APIView, GetOneData, DeleteOneData, UpdateOneData):pass

  像上面代码这样,将每个接口都写到独立的类中,然后使用多继承,或者成为mixin的这种方式,就可以对我们的程序进行优化,mixin的方式非常常见,在网络编程中学过的socketserver,其源码中就有对mixin的实现,即,假设我们需要进程的时候,我们继承进程类,如果我们需要线程的时候,我们就继承线程类即可。

三、视图组件使用

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

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

  urls.py代码:

from django.urls import re_pathfrom serializer import viewsurlpatterns = [    re_path('books/$', views.BookView.as_view()),    re_path('books/(?P
\d+)/$', views.BookFilterView.as_view()),]

  视图views.py代码:

from rest_framework.mixins import (    ListModelMixin,    CreateModelMixin,    DestroyModelMixin,    UpdateModelMixin,    RetrieveModelMixin)from rest_framework.generics import GenericAPIViewfrom rest_framework.response import Response# 导入序列化类from .app_serializers import BookSerializerfrom .models import Book, Publish, Authorclass 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 genericsfrom .app_serializers import BookSerializerfrom .models import Book, Publish, Authorclass BookView(generics.ListCreateAPIView):     queryset = Book.objects.all()     serializer_class = BookSerializerclass BookFilterView(generics.RetrieveUpdateDestroyAPIView):    queryset = Book.objects.all()    serializer_class = BookSerializer

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

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

  urls.py文件(注意跟之前有什么不同):

from django.urls import re_pathfrom serializer import viewsurlpatterns = [    re_path('books/$', views.BookView.as_view({        'get': 'list',        'post': 'create'    })),    re_path('books/(?P
\d+)/$', views.BookView.as_view({ 'get': 'retrieve', 'put': 'update', 'delete': 'destroy' }))

  视图views.py部分:

from rest_framework.viewsets import ModelViewSetfrom .app_serializers import BookSerializerfrom .models import Book, Publish, Authorclass BookView(ModelViewSet):     queryset = Book.objects.all()     serializer_class = BookSerializer

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

转载于:https://www.cnblogs.com/li-li/p/10082573.html

你可能感兴趣的文章
十个值得一试的开源深度学习框架
查看>>
【LEETCODE】240-Search a 2D Matrix II
查看>>
【LEETCODE】53-Maximum Subarray
查看>>
【LEETCODE】215-Kth Largest Element in an Array
查看>>
【LEETCODE】241-Different Ways to Add Parentheses
查看>>
【LEETCODE】312-Burst Balloons
查看>>
【LEETCODE】232-Implement Queue using Stacks
查看>>
【LEETCODE】225-Implement Stack using Queues
查看>>
【LEETCODE】155-Min Stack
查看>>
【LEETCODE】20-Valid Parentheses
查看>>
【LEETCODE】290-Word Pattern
查看>>
【LEETCODE】36-Valid Sudoku
查看>>
【LEETCODE】205-Isomorphic Strings
查看>>
【LEETCODE】204-Count Primes
查看>>
【LEETCODE】228-Summary Ranges
查看>>
【LEETCODE】27-Remove Element
查看>>
【LEETCODE】66-Plus One
查看>>
【LEETCODE】26-Remove Duplicates from Sorted Array
查看>>
【LEETCODE】118-Pascal's Triangle
查看>>
【LEETCODE】119-Pascal's Triangle II
查看>>