代码目录结构:

一、使用原生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. 转:C#综合揭秘——细说多线程(上)

    原文地址:http://www.cnblogs.com/leslies2/archive/2012/02/07/2310495.html 引言 本文主要从线程的基础用法,CLR线程池当中工作者线程与I ...

  2. [IDEA_4] IDEA 从 GitHub 上 pull 项目到本地

    0. 说明 通过参考的链接我们已经知道了怎么安装配置 Git  .GitHub ,如何使用 IDEA 将本地项目上传到 GitHub. 现在是学习怎么通过 IDEA 将项目从 GitHub pull ...

  3. WCF 基于 WinForm 宿主 发布

    ServiceHost Host = new ServiceHost(typeof(ServiceHTTP)); //绑定 System.ServiceModel.Channels.Binding h ...

  4. 'javac' 不是内部或外部命令,也不是可运行的程序

    今天在命令行中运行javac命令时发现 但是运行java命令却可以 查找jdk的安装路径发现,安装目录里面同时有jdk的文件夹和jre的文件夹 查看了jdk的目录发现jdk目录中也有一个jre文件夹 ...

  5. 题解 P1312 【Mayan游戏】

    题面 过长已遮挡 题意 体面已经陈述题意(这题没有考语文阅读理解) 题解 ** 我还记得我曾经给自己找的锅,给某些人讲课的时候说过一句话:体面越长的题,越简单.** 这句话没有错,我会用接下来解决这道 ...

  6. Servlet 核心接口

    在Servlet体系结构中,除了用于实现Servlet的Servlet接口.GenericServlet类和HttpServlet类外,还有一些辅助Servlet获取相关资源信息的重要接口,了解这些接 ...

  7. FastDFS分布式文件系统设计原理

    转载自http://blog.chinaunix.net/uid-20196318-id-4058561.html FastDFS是一个开源的轻量级分布式文件系统,由跟踪服务器(tracker ser ...

  8. CentOS7+Nginx设置Systemctl restart nginx.service服务

    centos 7上是用Systemd进行系统初始化的,Systemd 是 Linux 系统中最新的初始化系统(init),它主要的设计目标是克服 sysvinit 固有的缺点,提高系统的启动速度.关于 ...

  9. C#实现之(自动更新)

    做开发的人,尤其是做客户端(C/S)系统开发的人都会遇到一个头疼的问题,就是软件的自动更新:系统发布后怎样自动的更新程序,在下有幸开发过一个自动更新程序,更新程序与任何宿主程序是完全独立的:只要在主程 ...

  10. 可以获取JVM信息的一些管理工具类

    一些可以获取JVM信息的java工具类 BufferPoolMXBean.class ClassLoadingMXBean.class CompilationMXBean.class GarbageC ...