代码目录结构:

一、使用原生APIView

使用rest-framework原生的APIView实现过程:

以url(r'^books/$', views.BookView.as_view(),name="books")为例进行流程分析,

  • 1、views.BookView.as_view()==>APIView的as_view方法==>父类【View】的as_view方法
  • 2、View的as_view方法实际上是返回了View下的view方法
  • 3、view实际上是执行了dispatch方法
  • 4、dispatch执行过程是去找对应的get/post/put/delete/patch方法

代码实现如下:

urls文件

PublishView用于处理publishes的get和post,获取多个资源的情况

PublishDetailView用于处理publishes/1/的get、put、delete,获取单个资源的情况

url(r'^publishes/$', views.PublishView.as_view(),name="publish"),
url(r'^publishes/(?P<pk>\d+)/$', views.PublishDetailView.as_view(),name="detailpublish"),

  

views文件

使用rest-framework原生的APIView,按照上面说的流程,最后进入dispatch方法,所以只需要我们自己重写get/post/put/delete等方法即可。

from rest_framework.views import APIView
# Publish表
class PublishView(APIView):
def get(self,request): publish_list = Publish.objects.all()
ps = PublishModelSerializers(publish_list, many=True)
return Response(ps.data) def post(self,request): # post请求的数据
ps = PublishModelSerializers(data=request.data)
if ps.is_valid():
print(ps.validated_data)
ps.save() # create方法
return Response(ps.data)
else:
return Response(ps.errors)
class PublishDetailView(APIView):
def get(self, request, pk): publish = Publish.objects.filter(pk=pk).first()
ps = PublishModelSerializers(publish)
return Response(ps.data) def put(self, request, pk):
publish = Publish.objects.filter(pk=pk).first()
ps = PublishModelSerializers(publish, data=request.data)
if ps.is_valid():
ps.save()
return Response(ps.data)
else:
return Response(ps.errors) def delete(self, request, pk):
Publish.objects.filter(pk=pk).delete() return Response()

  

serializer文件

通过ModelSerializer类,指定model和fields进行序列化操作。

from rest_framework import serializers

from app01.models import *
# 为queryset,model对象做序列化
class PublishSerializers(serializers.Serializer):
name = serializers.CharField()
email = serializers.CharField() class PublishModelSerializers(serializers.ModelSerializer):
class Meta:
model=Publish
fields="__all__"

  

原生APIView的缺点

针对每个model,需要自己写API的各种方法,代码重复程度很高。

进一步解决办法:使用mixins

二、使用mixins

mixins在上一步的基础上进行了进一步的封装,也就是把多资源情况下的GET/POST以及单资源情况下的GET/POST/PUT/DELETE进行了再次封装,只要我们指定集成的类,然后重写对应的方法即可,urls也不用变更。

from rest_framework import mixins
from rest_framework import generics class AuthorView(mixins.ListModelMixin,mixins.CreateModelMixin,generics.GenericAPIView):
queryset=Author.objects.all()
serializer_class =AuthorModelSerializers 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 AuthorDetailView(mixins.RetrieveModelMixin,mixins.DestroyModelMixin,mixins.UpdateModelMixin,generics.GenericAPIView):
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers def get(self,request,*args, **kwargs):
return self.retrieve(request,*args, **kwargs) def delete(self,request,*args, **kwargs):
return self.destroy(request,*args, **kwargs) def put(self,request,*args, **kwargs):
return self.retrieve(request,*args, **kwargs)

  

使用mixins还是有代码重复的缺点,每个model表都需要重写这一堆方法和类。

三、使用generics

使用generics可以很好的避免上面的问题,他直接包含了多资源和单资源情况下的所有方法,而不需要重写get、post、put、delete方法,甚至还包括patch方法。

from rest_framework import mixins
from rest_framework import generics class AuthorView(generics.ListCreateAPIView):
queryset=Author.objects.all()
serializer_class =AuthorModelSerializers class AuthorDetailView(generics.RetrieveUpdateDestroyAPIView):
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers

  但是这里还有一个缺点,就是单资源和多资源的视图函数以及url都是两份,是不是可以进行一步封装呢?

四、使用viewsets

使用viewsets可以通过在as_view中传参进一步简化操作。

在as_view中传入{动作:方法}的字典给action参数,然后通过getattr和setattr方法进行参数解析,然后通过dispatch中执行对应的方法。

urls文件

url(r'^books/$', views.BookViewSet.as_view({"get":"list","post":"create"}),name="book_list"),
url(r'^books/(?P<pk>\d+)$', views.BookViewSet.as_view({
'get': 'retrieve',
'put': 'update',
'patch': 'partial_update',
'delete': 'destroy'
}),name="book_detail"),

  

views文件

class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializers

  

这就是最终版本,对于一个model表,url两个,一个ModelViewSet类就可以轻易的实现一个API!

进一步简化

我们可以看到urls里面看上去是不是很乱的样子,其实,rest-framework也已经解决了这个脏乱差的问题,通过使用routers!

urls文件修改

以books为例:

from django.conf.urls import url,include
from django.contrib import admin
from rest_framework import routers
from app01 import views #router实例化,并将Viewset进行注册
router = routers.DefaultRouter()
router.register(r'books',views.BookViewSet) #路由控制
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^publishes/$', views.PublishView.as_view(),name="publish"), # View:view(request)=====APIView:dispatch()
url(r'^publishes/(?P<pk>\d+)/$', views.PublishDetailView.as_view(),name="detailpublish"), # View:view(request)=====APIView:dispatch() url(r'',include(router.urls)), ]

  

其他Viewset需要实例化,同样的操作即可,urls的最终结果为:

from django.conf.urls import url,include
from django.contrib import admin
from rest_framework import routers
from app01 import views #router实例化,并将Viewset进行注册
router = routers.DefaultRouter()
router.register(r'books',views.BookViewSet)
router.register(r'books',views.PublishViewSet) #路由控制
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'',include(router.urls)), ]

  是不是很简洁?

REST-framework快速构建API--四部曲的更多相关文章

  1. 5分钟APIG实战: 使用Rust语言快速构建API能力开放

    序言:Rust语言简介 参与过C/C++大型项目的同学可能都经历过因为Null Pointer.Memory Leak等问题“被” 加班了不知道多少个晚上.别沮丧,你不是一个人,Mozilla Fir ...

  2. Django Rest Framework 教程及API向导

    Django Rest Framework 教程及API向导. 一.请求(Request)REST_FRAMEWORK 中的 Request 扩展了标准的HttpRequest,为 REST_FRAM ...

  3. 快速构建第三方api应用

    1.使用框架和扩展 详细请看composer.json "php": "^7.1.3", "laravel-admin-ext/config" ...

  4. 使用Asp.net WebAPI 快速构建后台数据接口

    现在的互联网应用,无论是web应用,还是移动APP,基本都需要实现非常多的数据访问接口.其实对一些轻应用来说Asp.net WebAPI是一个很快捷简单并且易于维护的后台数据接口框架.下面我们来快速构 ...

  5. 利用Nodejs快速构建应用原型

    利用Nodejs快速构建应用原型 开发一个应用往往需要快速的构建原型,然后在此基础上设计和改进,前端可能立马能看到效果,但是后端业务逻辑不会那么快,这个时候其实我们需要额只是一些模拟数据,所以不需要真 ...

  6. 快速构建Windows 8风格应用12-SearchContract概述及原理

    原文:快速构建Windows 8风格应用12-SearchContract概述及原理 本篇博文主要介绍Search Contract概述.Search Contract面板结构剖析.Search Co ...

  7. 快速构建Windows 8风格应用35-触控输入

    原文:快速构建Windows 8风格应用35-触控输入 引用 Windows 8设备通常具有多点触摸屏,用户可以同时使用多个手指来进行不同的输入交互,如点击.拖动或收缩等手势操作.另外Windows ...

  8. 快速构建Windows 8风格应用33-构建锁屏提醒

    原文:快速构建Windows 8风格应用33-构建锁屏提醒 引言 Windows Phone(8&7.5)和Windows 8引入了锁屏概念,其实做过Windows Phone 7.5应用开发 ...

  9. 快速构建Windows 8风格应用31-构建磁贴

    原文:快速构建Windows 8风格应用31-构建磁贴 引言 磁贴是吸引用户经常使用应用重要手段之一.我们可将应用程序内较好的内容使用磁贴进行展示. 另外应用程序磁贴是应用程序中的核心部分,而且很可能 ...

  10. 快速构建Windows 8风格应用29-捕获图片与视频

    原文:快速构建Windows 8风格应用29-捕获图片与视频 引言 本篇博文主要介绍Windows 8中相机的概念.捕获图片与视频的基本原理.如何实现捕获图片与视频.相机最佳实践. 一.相机 关于相机 ...

随机推荐

  1. 在Eclipse中运行Jboss时出现java.lang.OutOfMemoryError:PermGen space及其解决方法

    在Eclipse中运行Jboss时出现java.lang.OutOfMemoryError:PermGen space及其解决方法 在Eclipse中运行Jboss时,时间太长可能有时候会出现java ...

  2. FFmpeg实现监控摄像头的RTSP协议转RTMP协议直播

    文章来源:http://www.cuplayer.com/player/PlayerCode/RTSP/2014/0706/1419.html FFmpeg实现监控摄像头的RTSP协议转RTMP协议直 ...

  3. tikv性能参数调优

    tiKV 最底层使用的是 RocksDB(tidb3.0版本中将使用tian存储引擎) 做为持久化存储,所以 TiKV 的很多性能相关的参数都是与 RocksDB 相关的.TiKV 使用了两个 Roc ...

  4. NOIP2018考前抱佛脚——搜索复习

    目录 搜索 DFS 例1 P1101 单词方阵 题目描述 输入输出格式 输入输出样例 标程 例2 P1605 迷宫 题目背景 输入输出格式 输入输出样例 标程 例3 P1019 单词接龙 题目描述 输 ...

  5. MySQL5.7通过压缩包方式安装与配置

    首先下载MySQL5.7的压缩包:https://dev.mysql.com/downloads/mysql/5.7.html#downloads 1.解压缩到目标文件夹,解压后有许多文件,介绍一下用 ...

  6. git 的一般使用

    git安装 git初始化一个仓库 命令:git init; 想在哪个目录创建.git目录,就是哪个目录打开工具然后写命令. 一般是在项目的根目录执行这个命令. 配置用户名 : git config u ...

  7. word怎样从第三页开始设置页码

    一般的文件都是有封面,目录.然后才是正文.所以基本上第一页的封面,第二页是目录,第三页才是正文的开始.但是默认的页码会从第一页开始的,封面上海有页码这会很难看,今天和小编一起来看看怎样将页码从第三页开 ...

  8. Actor模式初步入门

    Actor模型概念 Actor模型为并行而生,简单说是未解决高并发的一种编程思路.在Actor模型中,主角是Actor,类似一种worker,Actor彼此之间直接发送消息,不需要经过什么中介,消息是 ...

  9. RMAN 备份数据库到DISK后进行数据恢复

    RMAN 备份数据库到DISK,然后进行数据恢复 一.rman备份 1. 全备脚本 vi bakup_level0.sql connect target / run { allocate channe ...

  10. leetcode16—3 Sum Closet

    Given an array nums of n integers and an integer target, find three integers in nums such that the s ...