DRF的基类是APIView类,GenericAPIView类是APIView类的子类。

GenericAPIView类有什么存在的意义呢?

其实,

他主要提供了两个用处:

1.提供关于数据库查询的属性与方法

2.提供关于序列化器使用的属性与方法

=================================================================================================================

详解:

先看一段小代码比较好理解,(继承APIView与继承GenericAPIView的两种不同的写法,查询多条数据时)

继承APIView的写法:

  1. class DepartmentListAPIView(APIView):
  2. def get(self,request):
  3. """查询多条数据"""
  4. dep = Department.objects.all()
  5. # 创建序列化器对象
  6. serializer = DepartmentSerializer(instance=dep,many=True)
  7. # 序列化:对象->字典
  8. data_dict = serializer.data
  9. # DRF的Response对象可以把字典转换为请求头指定的格式返回
  10. return Response(data=data_dict)

继承GenericAPIView的写法:

  1. class DepartmentListAPIView(GenericAPIView):
  2. # querset与serializer_class是固定名字的!一定要指定
  3. # queryset指定数据库全部数据的查询集
  4. queryset = Department.objects.all()
  5. # serializer_class指定序列化器
  6. serializer_class = DepartmentSerializer
  7. def get(self,request):
  8. """查询多条数据"""
  9. dep = self.get_queryset()
  10. serializer = self.get_serializer(dep,many=True)
  11. data_dict = serializer.data
  12. return Response(data=data_dict)

1.提供关于数据库查询的属性与方法:

上面例子中,get_queryset()的方法,可以取得数据库查询结果的查询集queryset的内容。(注意,一定要通过get_query取得数据库查询的结果后再传给序列化器,不能直接传self.queryset给序列化器,因为get_query的源码还有“Ensure queryset is re-evaluated on each request.”这一个步骤。)

2.提供关于序列化器使用的属性与方法

上面的列子中,get_serializer()的方法,实际上就是取类属性serializer_class的值

  • 更多的继承APIView与继承GenericAPIView的写法:

继承APIView的写法:

  1. class DepartmentListAPIView(APIView):
  2. def get(self,request):
  3. """查询多条数据"""
  4. dep = Department.objects.all()
  5. # 创建序列化器对象
  6. serializer = DepartmentSerializer(instance=dep,many=True)
  7. # 序列化:对象->字典
  8. data_dict = serializer.data
  9. # DRF的Response对象可以把字典转换为请求头指定的格式返回
  10. return Response(data=data_dict)
  11.  
  12. def post(self,request):
  13. """新增一条数据"""
  14. # DRF的Request对象直接把接受到的值转换为字典
  15. data_dict = request.data
  16. # 创建序列化器对象
  17. serializer = DepartmentSerializer(instance=None,data=data_dict)
  18. # 校验校验不通过,抛异常(反序列化的功能)
  19. serializer.is_valid(raise_exception=True)
  20. # 反序列化,把字典的数据存进数据库
  21. serializer.save()
  22. # restful风格,新增要返回新增数据的那一列内容。用了序列化,把对象转换为字典,同时Response处理。
  23. return Response(data=serializer.data)
  24.  
  25. class DepartmentDetailAPIView(APIView):
  26. def get(self,request,pk):
  27. """查询一条数据"""
  28. # 查询出该条数据的对象
  29. try:
  30. dep = Department.objects.get(id=pk)
  31. except Department.DoesNotExist:
  32. return HttpResponse(status=status.HTTP_404_NOT_FOUND)
  33. # 创建序列化器对象
  34. serializer = DepartmentSerializer(instance=dep)
  35. # 序列化,把对象转换为字典,同时Response根据请求头返回相应的格式
  36. return Response(data=serializer.data)
  37.  
  38. def post(self,request,pk):
  39. """修改部门"""
  40. # DRF的Request对象直接把接受到的值转换为字典
  41. data_dict = request.data
  42. # 查询出要修改的数据
  43. try:
  44. dep = Department.objects.get(id=pk)
  45. except Department.DoesNotExist:
  46. return HttpResponse(status=404)
  47. # 创建序列化器对象
  48. serializer = DepartmentSerializer(instance=dep,data=data_dict)
  49. # 反序列化,校验参数是否正确,若不正确,抛异常
  50. serializer.is_valid(raise_exception=True)
  51. # 反序列化,把字典的数据存进数据库
  52. serializer.save()
  53. # 序列化,把对象转换为字典。同时DRF的Response对象根据请求头返回相应的格式
  54. return Response(serializer.data)
  55.  
  56. def delete(self,request,pk):
  57. """删除一个部门"""
  58. try:
  59. dep = Department.objects.get(id=pk)
  60. except Department.DoesNotExist:
  61. return HttpResponse(status=404)
  62. dep.delete()
  63. return Response(status=status.HTTP_204_NO_CONTENT)

继承GenericAPIView的写法:

  1. class DepartmentListAPIView(GenericAPIView):
  2. # querset与serializer_class是固定名字的!
  3. # queryset指定数据库全部数据的查询集
  4. queryset = Department.objects.all()
  5. # serializer_class指定序列化器
  6. serializer_class = DepartmentSerializer
  7.  
  8. def get(self,request):
  9. """查询多条数据"""
  10. dep = self.get_queryset()
  11. serializer = self.get_serializer(instance=dep,many=True)
  12. data_dict = serializer.data
  13. return Response(data=data_dict)
  14.  
  15. def post(self,request):
  16. """新增一条数据"""
  17. data_dict = request.data
  18. serializer = self.get_serializer(instance=None,data=data_dict)
  19. serializer.is_valid(raise_exception=True)
  20. serializer.save()
  21. return Response(serializer.data)
  22.  
  23. class DepartmentDetailAPIView(GenericAPIView):
  24.  
  25. queryset = Department.objects.all()
  26. serializer_class = DepartmentSerializer
  27.  
  28. def get(self,request,pk):
  29. """查询一条数据"""
  30. dep = self.get_object() # 有主键用get_object(),get_object()方法根据pk参数查找queryset中的数据对象
  31. serializer = self.get_serializer(instance=dep)
  32. return Response(data=serializer.data)
  33.  
  34. def post(self,request,pk):
  35. """修改部门"""
  36. data_dict = request.data
  37. dep = self.get_object()
  38. serializer = self.get_serializer(instance=dep,data=data_dict)
  39. serializer.is_valid(raise_exception=True)
  40. serializer.save()
  41. return Response(serializer.data)
  42.  
  43. def delete(self,request,pk):
  44. """删除一个部门"""
  45. dep = self.get_object()
  46. dep.delete()
  47. return Response(status=status.HTTP_204_NO_CONTENT)
  • 总结:

从上面的代码可以看出,继承APIView和继承GenerciAPIView的代码量基本差不多。那么GenericAPIView这个类有什么实质的用处呢?

其实,

他是只是为了提供几种方法给它的扩展类而已,GenericAPIView通常结合一个或多个Mixin扩展类使用,用来快速地实现列表视图与详情视图。

DRF基类APIView的子类GenericAPIView的更多相关文章

  1. DRF基类APIView提供的Request、Response和序列化器的综合使用

    关于DRF基类APIView提供的Request和Response对象的作用,可以看我的另一篇博文:https://www.cnblogs.com/chichung/p/9939864.html 综合 ...

  2. DRF自带的Request和Response对象(DRF基类APIView)

    # 转载请留言联系 1.Request对象 DRF传入视图的request对象,不再是Django默认的HttpRequest对象,而是扩展了HttpRequest类的Request类的对象. RES ...

  3. C++ 基类指针,子类指针,多态

    基类指针和子类指针之间相互赋值(1)将子类指针赋值给基类指针时,不需要进行强制类型转换,C++编译器将自动进行类型转换.因为子类对象也是一个基类对象. (2)将基类指针赋值给子类指针时,需要进行强制类 ...

  4. C++ 基类指针和子类指针相互赋值

    首先,给出基类animal和子类fish [cpp] view plaincopy //======================================================== ...

  5. C++获取基类指针所指子类对象的类名

    我们在程序中定义了一个基类,该基类有n个子类,为了方便,我们经常定义一个基类的指针数组,数组中的每一项指向都指向一个子类,那么在程序中我们如何判断这些基类指针是指向哪个子类呢? 关键字 typeid, ...

  6. .NET Core中基类可以反射子类的成员

    我们定义一个类DemoA,再定义一个类DemoB继承DemoA.当构造一个DemoB类对象后,我们可以通过其调用基类DemoA中的方法来反射子类DemoB的成员. 新建一个.NET Core控制台项目 ...

  7. Java: 基类、子类、构造函数、程序块的初始化顺序

    初始化顺序 基类static block 子类static block 基类non-static block 子类non-static block 基类constructor 子类constructo ...

  8. C++ | 继承(基类,父类,超类),(派生类,子类)

    转载:https://blog.csdn.net/Sherlock_Homles/article/details/82927515 文章参考:https://blog.csdn.net/war1111 ...

  9. [Django REST framework - 视图组件之视图基类、视图扩展类、视图子类、视图集]

    [Django REST framework - 视图组件之视图基类.视图扩展类.视图子类.视图集] 视图继承关系 详图见文章末尾 视图组件可点我查看 两个视图基类:APIView.GenericAP ...

随机推荐

  1. 成为IT精英,我奋斗7年【转】

    这些日子 我一直在写一个实时操作系统内核,已有小成了,等写完我会全部公开,希望能够为国内IT的发展尽自己一份微薄的力量.最近看到很多学生朋友和我当年一样没 有方向 ,所以把我的经历写出来与大家共勉,希 ...

  2. DFS(5)——hdu1728逃离迷宫

    一.题目回顾 题目链接:逃离迷宫 Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地 ...

  3. windows2008 R2 系统 安装wampserver提示“缺少msvcr110.dll文件”处理办法

    windows2008 R2 系统 安装wampserver提示“缺少msvcr110.dll文件”处理办法 原因分析: 因缺少Visual C++ Redistributable for Visua ...

  4. UVA215 Spreadsheet

    这道题题目大意就是计算带有单元格引用的各单元格的值. 这道题本身不难,有以下几个关键点: 1.如何判断一个单元格循环引用 2.注意对字符串的细致处理 我出现的错误出现在以上两个方面,思路本身是不难的. ...

  5. centos7 centos6中 更改默认的系统启动级别

    centos6中更改默认的启动级别 方法: 1.vi /etc/inittab 2.找到id:x:initdefault:,我的系统是id:3:initdefault:,即默认以字符模式启动. 3.将 ...

  6. Android调用Java WebSevice篇之二

    1.创建Activity. package com.web; import org.ksoap2.SoapEnvelope; import org.ksoap2.serialization.SoapO ...

  7. 多线程 定时器 Timer TimerTask

    定时器是一种特殊的多线程,使用Timer来安排一次或者重复执行某个任务 package org.zln.thread; import java.util.Date; import java.util. ...

  8. GET传值

    发送页: <form id="form1" runat="server"> <div> <asp:TextBox ID=</ ...

  9. BZOJ4487 JSOI2015染色问题(组合数学+容斥原理)

    逐个去除限制.第四个限制显然可以容斥,即染恰好c种颜色的方案数=染至多c种颜色的方案数-染至多c-1种颜色的方案数+染至多c-2种颜色的方案数…… 然后是限制二.同样可以容斥,即恰好选n行的方案数=至 ...

  10. [POJ1631]Bridging signals

    题目大意:不知,根据样例猜测为最长上升子序列(竟然还对了) 题解:$O(n log_2 n)$,求二维偏序,(q为存答案的序列,a存原序列,len为答案) for(int i = 1; i <= ...