# 原创,转载请留言联系

如果要把同一种http请求方法的多个接口放在同一个视图中,比如:查询多条数据和一条数据都是get请求,放在同一个视图里,应该怎么做呢???

如果直接放在一起,会怎样呢?

# 视图:
class DepartmentTestView(ListAPIView, RetrieveAPIView):
queryset = Department.objects.all()
serializer_class = DepartmentSerializer # 路由:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^departments$',views.DepartmentTestView.as_view()),
url(r'^departments/(?P<pk>\d+)$',views.DepartmentTestView.as_view())
]

当访问/departments时,匹配对路由,然后到达视图,找get请求的视图,先找到了ListAPIView,执行,正确的返回了数据。

当访问/departments/1时,匹配对路由,然后到达视图,找get请求的视图,先找到ListAPIView,执行,返回了查找全部数据的结果。不是我们想要的结果。

解决办法:使用视图集

1.ViewSet

  • 继承自APIView与ViewSetMixin
  • 继承ViewSetMixin的作用是实现在调用as_view()时传入字典(如{'get':'list'})的映射处理工作。
  • 在ViewSet中,没有提供任何 action方法,需要我们自己实现 action方法(和继承APIView一样,要自己创建序列化器对象,自己校验数据,自己存数据库,自己序列化等...)

示例:

首先是视图的代码:

class DepartmentViewSet(ViewSet):
def list(self,request):
"""查询全部部门"""
dep = Department.objects.all()
serializer = DepartmentSerializer(instance=dep,many=True)
return Response(data=serializer.data) def create(self,request):
"""新增一个部门"""
data_dict = request.data
serializer = DepartmentSerializer(instance=None,data=data_dict)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data) def retrieve(self,request,pk):
"""查询一个部门"""
try:
dep = Department.objects.get(id=pk)
except Department.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
serializer = DepartmentSerializer(instance=dep)
return Response(serializer.data) def update(self,request,pk):
"""修改一个部门"""
try:
dep = Department.objects.get(id=pk)
except Department.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
data_dict = request.data
serializer = DepartmentSerializer(instance=dep,data=data_dict)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data) def delete(self,request,pk):
"""删除一个部门"""
try:
dep = Department.objects.get(id=pk)
except Department.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
dep.delete()
return Response(status=status.HTTP_204_NO_CONTENT)

然后是路由的配置:

urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^departments$',views.DepartmentViewSet.as_view({'get':'list','post':'create'})),
url(r'^departments/(?P<pk>\d+)$',views.DepartmentViewSet.as_view({'get':'retrieve','post':'update','delete':'delete'}))
]

注意:

函数名(list、create、retrieve、update、delete)可以自定义的,也可以根据实际情况定义函数。

2.GenericViewSet

  • 使用ViewSet通常并不方便,因为list、retrieve、create、update、destory等方法都需要自己编写
  • 因为这些方法与前面讲过的Mixin扩展类提供的方法同名,所以我们可以通过继承Mixin扩展类来复用这些方法,而Mixin扩展类依赖与GenericAPIView,所以还需要继承GenericAPIView
  • GenericViewSet就帮助我们完成了这样的继承工作,继承自GenericAPIView与ViewSetMixin,在实现了调用as_view()时传入字典(如{'get':'list'})的映射处理工作的同时,还提供了GenericAPIView提供的基础方法,可以直接搭配Mixin扩展类使用。

示例:

首先是视图的代码:

class DepartmentViewSet(ListModelMixin,CreateModelMixin,RetrieveModelMixin,
UpdateModelMixin,DestroyModelMixin,GenericViewSet): queryset = Department.objects.all()
serializer_class = DepartmentSerializer

然后是路由的配置:

urlpatterns = [
url(r'^departments$',views.DepartmentViewSet.as_view({'get':'list','post':'create'})),
url(r'^departments/(?P<pk>\d+)$',views.DepartmentViewSet.as_view({
'get':'retrieve','put':'update','delete':'destroy'
}))
]

注意:

路由配置中,例如'get':'list',对应的是请求方法,ListModelMixin里面的方法。特别是‘list’,一定要点进类里面,看下方法名是什么,再写在路由里面,不然无法调用类里面的方法,也就返回不了响应对象。

拓展:

如果这几个类满足不了需求,可以仿照ViewSet的方法自定义方法。如果自定义的方法要用到不同的序列话器,可以这样做:

def get_serializer_class(self):
"""修改部门名称的接口,使用不同的序列化器"""
if self.action == '[方法名]':
return [自定义的序列器]
else:
return DepartmentSerializer

3.ModelViewSet

  • 继承自GenericViewSet
  • 包括了 ListModelMixinRetrieveModelMixinCreateModelMixinUpdateModelMixinDestroyModelMixin
  • 和第2点的用法一样

4.ReadOnlyModelViewSet

  • 继承自 GenericViewSet
  • 包括了 ListModelMixinRetrieveModelMixin
  • 和第2点的用法一样

DRF视图集的使用的更多相关文章

  1. 使用DRF视图集时自定义action方法

    在我们用DRF视图集完成了查找全部部门,创建一个新的部门,查找一个部门,修改一个部门,删除一个部门的功能后,views.py的代码是这样子的: class DepartmentViewSet(Mode ...

  2. DRF视图集的路由设置

    在使用DRF视图集时,往往需要配一大堆路由,例如: # views.py class DepartmentViewSet(ListModelMixin,CreateModelMixin,Retriev ...

  3. 068.Python框架Django之DRF视图集使用

    一 视图集与路由的使用 使用视图集ViewSet,可以将一系列逻辑相关的动作放到一个类中: list() 提供一组数据 retrieve() 提供单个数据 create() 创建数据 update() ...

  4. 对drf视图集的理解

    视图集ViewSet 使用视图集ViewSet,可以将一系列逻辑相关的动作放到一个类中: list() 提供一组数据 retrieve() 提供单个数据 create() 创建数据 update() ...

  5. DRF中的视图集的使用

    1.说明:DRF框架中的视图集: 在drf开发接口中,使用GenericAPIView和视图扩展类结合起来完成接口功能是一件很常见的事情,所以,drf的作者帮我们提前把  GenericAPIView ...

  6. DRF中五大扩展类及视图集的介绍

    五个扩展类 (1)ListModelMixin 列表视图扩展类,提供list(request, *args, **kwargs)方法快速实现列表视图,返回200状态码. 该Mixin的list方法会对 ...

  7. drf04 drf视图类

    REST framework 提供了众多的通用视图基类与扩展类,以简化视图的编写. 1.2个视图基类 1.1. APIView rest_framework.views.APIView APIView ...

  8. day73:drf:drf视图相关类&路由Routers&创建虚拟环境

    目录 1.APIView 2.GenericAPIView:通用视图类 3.5个视图扩展类:ListModelMixin,CreateModelMixin,RetrieveModelMixin,Upd ...

  9. DRF 视图组件

    目录 DRF 视图组件 视图组件大纲 两个视图基本类 五个扩展类 九个子类视图 视图集 常用视图集父类 魔法类 一览表 DRF中视图的"七十二变" 第一层:基于APIview的五个 ...

随机推荐

  1. BZOJ 4012 HNOI2015 开店 树的边分治+分治树

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4012 题意概述:给出一颗N点的树,保证树上所有点的度不超过3,树上每个点有权值,每条边有权 ...

  2. Alpha阶段展示

    程序员杀产品经理祭天(SacrificePM)团队 1.团队成员简介和个人博客地址 故事 我们队伍的建立过程稍具戏剧性,大家看我们也颇为奇怪,这么一支8人队伍是怎么诞生的呢?其实我们原本分属三组,而第 ...

  3. powerdesigner 外键生成sql语句设置在创建表里面

    根据情况需要将创建外键表的sql语句生成在创建表的sql语句中,如下设置:

  4. EF to linq 左连接

    如果连接的数据不存在用 null 表示,则可以左连接查询,但是如果数据类型为 int 则会出错. var ng = (from g in _db.NET_NEWS_GROUP join z in _d ...

  5. [洛谷P3195][HNOI2008]玩具装箱TOY

    题目大意:有n个物体,大小为$c_i$.把第i个到第j个放到一起,容器的长度为$x=j-i+\sum\limits_{k-i}^{j} c_k$,若长度为x,费用为$(x-L)^2$.费用最小. 题解 ...

  6. Visual Studio调试之断点技巧篇

    原文链接地址:http://blog.csdn.net/Donjuan/article/details/4618717 函数断点 在前面的文章Visual Studio调试之避免单步跟踪调试模式里面我 ...

  7. 【COGS 461】[网络流24题] 餐巾 最小费用最大流

    既然是最小费用最大流我们就用最大流来限制其一定能把每天跑满,那么把每个表示天的点向T连流量为其所需餐巾,费用为0的边,然后又与每天的餐巾对于买是无限制的因此从S向每个表示天的点连流量为INF,费用为一 ...

  8. 【bzoj2141】排队 [国家集训队2011]排队(魏铭) 树套树 线段树套替罪羊树

    这个题就是动态偏序对,每次操作做两个删除两个插入就好了. #include<cstdio> #include<iostream> #include<cstring> ...

  9. volatile的原理分析

    前言:Volatile作为一个多线程开发中的强有力的轻量级的线程协助工具,在实际编程中随处可见,它比synchronized更加轻量和方便,消耗的资源更少,了解Volatile对后面了解多线程有很重要 ...

  10. [hdu 6069]素数筛+区间质因数分解

    给[L,R]区间的每一个数都质因数分解的复杂度可以达到(R-L)logR,真的涨姿势…… 另外,质因数分解有很重要的一点,就是只需要打sqrt(R)以内的素数表就够了……因为超过sqrt(R)的至多只 ...