DRF基类APIView的子类GenericAPIView
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 = DepartmentSerializerdef get(self,request):"""查询多条数据"""dep = self.get_queryset()serializer = self.get_serializer(dep,many=True)data_dict = serializer.datareturn 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 = DepartmentSerializerdef get(self,request):"""查询多条数据"""dep = self.get_queryset()serializer = self.get_serializer(instance=dep,many=True)data_dict = serializer.datareturn Response(data=data_dict)def post(self,request):"""新增一条数据"""data_dict = request.dataserializer = 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 = DepartmentSerializerdef 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.datadep = 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扩展类使用,用来快速地实现列表视图与详情视图。
转载于:https://www.cnblogs.com/chichung/p/9940697.html
DRF基类APIView的子类GenericAPIView相关推荐
- 基类指针和子类指针相互赋值
首先,给出基类animal和子类fish [cpp] view plaincopy print? //================================================= ...
- 基类Object的子类有哪些以及字符串和数组的方法
基类object的子类有: Function Ayyay Number Boolean String Date Math RegExp 都是类,本质都是函数 ...
- 写出一个类People,并由该类做基类派生出子类Employee和Teacher
写出一个类People,并由该类做基类派生出子类Employee和Teacher.其中People 类具有name.age两个保护成员变量,分别为String类型.整型,且具有公有的getAge成员函 ...
- Cpp 对象模型探索 / 多重继承下基类指针释放子类对象的原理说明(虚析构函数的作用)
源码 #include <iostream>class Base1 { public:virtual void func_1_1(){ std::cout << "B ...
- 【C++】多态问题:基类调用子类的protected或者private函数
1.问题描述 如果在基类中虚函数是public,子类中重载时标记为protected或者private函数,是否还能访问这个函数? 答案是: 基类指针指向子类时,可以访问,并且访问的是子类重载后的函数 ...
- 使用“override”声明的成员函数不能重写基类成员_C++日志(三十五)虚基类与其子类的构造函数...
第三十四篇日志中提到,子类对象调用父类同名的函数时需要使用作用域标识符进行限定,这是在任何继承情况下都可以使用的普适方法. 问题引入: 考虑一种特殊的情况:子类全部或部分的基类(称为中间基类)同是继承 ...
- 谈谈基类与子类的this指针(C++)
引入 定义一个类的对象,首先系统已经给这个对象分配了空间,然后会调用构造函数(说明:假设存在构造函数).一个类有多个对象,当程序中调用对象的某个函数时,有可能要访问到这个对象的成员变量.而对于同一个类 ...
- python定义一个类和子类_Python定义类、定义子类以及super()函数的使用
代码实验展示: # 继承关系 object -> Person -> Student -> SchoolBoy # python2的语法: # class Person(object ...
- Cpp 对象模型探索 / 含有虚基类的类的内存布局
一.栗子 class Grand { public:int i_grand_ = 8; };class Parent1 : public virtual Grand { public:int i_pa ...
- 条款七 为多态基类声明virtual析构函数
1.如果基类中的成员函数是virtual类型的,其继承类中相应的函数也是virtual类型,并且基类对象的引用指向继承类对象时, 基类就可以调用继承类函数,否则调用的是基类函数 class base ...
最新文章
- 苏宁11.11:苏宁易购订单搜索系统架构及实现
- OpenGL 基本帧缓冲对象实例
- 第六章 计算机网络与i教案,大学计算机基础教案第6章计算机网络基础与应用.docx...
- frame或者iframe的contentwindow属性
- select事件有哪些_Android 深入底层:Linux事件管理机制 epoll
- #ifdef __cplusplus是什么意思
- 如何在Vue项目中使用vw实现移动端适配
- Ext 2.0布局实例
- <Android开发> Android开发工具- 之-I2C TOOLS工具使用
- mysql网吧管理系统_网吧管理系统(数据库)
- ROS2——通信接口(十)
- 宝塔linux面板-安装golang环境,宝塔面板Linux环境-安装Golang:Go语言环境
- 朱利亚 matlab分形图,【分形之美 02】分形图像怎么画?详解曼德勃罗朱利亚分形绘制方法...
- 让游戏通过红蓝立体眼镜展现立体效果
- 新GRE阅读关于Emily Dickinson 的作品
- IDEA GoLand 问题 Contents have differences only in line separators
- linux dns主配置文件,RHEL 5下DNS的主配置文件详解
- 如何使WooCommerce产品属性更加突出
- Flask实战开发在线问答系统
- 几道特别难搞的数据库面试题