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

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

其实,

他主要提供了两个用处:

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

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

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

详解:

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

继承APIView的写法:

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

继承GenericAPIView的写法:

class DepartmentListAPIView(GenericAPIView):
# querset与serializer_class是固定名字的!一定要指定
# queryset指定数据库全部数据的查询集
queryset = Department.objects.all()
# serializer_class指定序列化器
serializer_class = DepartmentSerializer
def get(self,request):
"""查询多条数据"""
dep = self.get_queryset()
serializer = self.get_serializer(dep,many=True)
data_dict = serializer.data
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的写法:

class DepartmentListAPIView(APIView):
def get(self,request):
"""查询多条数据"""
dep = Department.objects.all()
# 创建序列化器对象
serializer = DepartmentSerializer(instance=dep,many=True)
# 序列化:对象->字典
data_dict = serializer.data
# DRF的Response对象可以把字典转换为请求头指定的格式返回
return Response(data=data_dict) def post(self,request):
"""新增一条数据"""
# DRF的Request对象直接把接受到的值转换为字典
data_dict = request.data
# 创建序列化器对象
serializer = DepartmentSerializer(instance=None,data=data_dict)
# 校验校验不通过,抛异常(反序列化的功能)
serializer.is_valid(raise_exception=True)
# 反序列化,把字典的数据存进数据库
serializer.save()
# restful风格,新增要返回新增数据的那一列内容。用了序列化,把对象转换为字典,同时Response处理。
return Response(data=serializer.data) class DepartmentDetailAPIView(APIView):
def get(self,request,pk):
"""查询一条数据"""
# 查询出该条数据的对象
try:
dep = Department.objects.get(id=pk)
except Department.DoesNotExist:
return HttpResponse(status=status.HTTP_404_NOT_FOUND)
# 创建序列化器对象
serializer = DepartmentSerializer(instance=dep)
# 序列化,把对象转换为字典,同时Response根据请求头返回相应的格式
return Response(data=serializer.data) def post(self,request,pk):
"""修改部门"""
# DRF的Request对象直接把接受到的值转换为字典
data_dict = request.data
# 查询出要修改的数据
try:
dep = Department.objects.get(id=pk)
except Department.DoesNotExist:
return HttpResponse(status=404)
# 创建序列化器对象
serializer = DepartmentSerializer(instance=dep,data=data_dict)
# 反序列化,校验参数是否正确,若不正确,抛异常
serializer.is_valid(raise_exception=True)
# 反序列化,把字典的数据存进数据库
serializer.save()
# 序列化,把对象转换为字典。同时DRF的Response对象根据请求头返回相应的格式
return Response(serializer.data) def delete(self,request,pk):
"""删除一个部门"""
try:
dep = Department.objects.get(id=pk)
except Department.DoesNotExist:
return HttpResponse(status=404)
dep.delete()
return Response(status=status.HTTP_204_NO_CONTENT)

继承GenericAPIView的写法:

class DepartmentListAPIView(GenericAPIView):
# querset与serializer_class是固定名字的!
# queryset指定数据库全部数据的查询集
queryset = Department.objects.all()
# serializer_class指定序列化器
serializer_class = DepartmentSerializer def get(self,request):
"""查询多条数据"""
dep = self.get_queryset()
serializer = self.get_serializer(instance=dep,many=True)
data_dict = serializer.data
return Response(data=data_dict) def post(self,request):
"""新增一条数据"""
data_dict = request.data
serializer = self.get_serializer(instance=None,data=data_dict)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data) class DepartmentDetailAPIView(GenericAPIView): queryset = Department.objects.all()
serializer_class = DepartmentSerializer def get(self,request,pk):
"""查询一条数据"""
dep = self.get_object() # 有主键用get_object(),get_object()方法根据pk参数查找queryset中的数据对象
serializer = self.get_serializer(instance=dep)
return Response(data=serializer.data) def post(self,request,pk):
"""修改部门"""
data_dict = request.data
dep = self.get_object()
serializer = self.get_serializer(instance=dep,data=data_dict)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data) def delete(self,request,pk):
"""删除一个部门"""
dep = self.get_object()
dep.delete()
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. BZOJ 2946 POI2000 公共串 后缀自动机(多串最长公共子串)

    题意概述:给出N个字符串,每个串的长度<=2000(雾...可能是当年的年代太久远机子太差了),问这N个字符串的最长公共子串长度为多少.(N<=5) 抛开数据结构,先想想朴素做法. 设计一 ...

  2. sysctl -P 报错解决办法 error: "net.bridge.bridge-nf-call-ip6tables" is an unknown key

    error: "net.bridge.bridge-nf-call-ip6tables" is an unknown keyerror: "net.bridge.brid ...

  3. Linux的常用目录学习笔记

    首先,先查看一下Linuxi的一级目录结构: ls: /:表示根目录,文件系统的入口,最高一级目录. bin和sbin:命令保存目录,bin是普通用户能,sbin是root用户用的:/bin存放着系统 ...

  4. Spring Data JPA 简单查询

    一.常用规则速查 1  And 并且2  Or  或3  Is,Equals 等于4  Between  两者之间5  LessThan 小于6  LessThanEqual   小于等于7  Gre ...

  5. 【bzoj4548】小奇的糖果 STL-set+树状数组

    题目描述 平面上有n个点,每个点有一种颜色.对于某一条线段,选择所有其上方或下方的点.求:在不包含所有颜色的点的前提下,选择的点数最多是多少.(本题中如果存在某颜色没有相应的点,那么选择任何线段都不算 ...

  6. jenkins+Docker持续化部署(笔记)

    参考资料:https://www.cnblogs.com/leolztang/p/6934694.html (Jenkins(Docker容器内)使用宿主机的docker命令) https://con ...

  7. P3434 [POI2006]KRA-The Disks

    题目描述 For his birthday present little Johnny has received from his parents a new plaything which cons ...

  8. Charles 抓包发现自动跳转为https 问题梳理

    今天遇到个有点意思的问题.特此记录. 业务场景: 做了一个页面,但是对外是挂载在京东主站上.如:www.jd.com/yifu/123456.html. 现场情况: 在本地/测试环境/预发环境中,每次 ...

  9. JQuery中的each()的使用

    each()函数是基本上所有的框架都提供了的一个工具类函数,通过它,你可以遍历对象.数组的属性值并进行处理. jQuery和jQuery对象都实现了该方法,对于jQuery对象,只是把each方法简单 ...

  10. 如何在Javascript中利用封装这个特性

    对于熟悉C#和Java的兄弟们,面向对象的三大思想(封装,继承,多态)肯定是了解的,那么如何在Javascript中利用封装这个特性呢? 我们会把现实中的一些事物抽象成一个Class并且把事物的属性( ...