rest_framework -- mixins&generics
上面的mixins、generics都是rest_framework里的模块,我们可以继承其中的某些类,达到代码量减少的效果,这里充分体现出了面向对象的继承
一、mixins模块
mixins : from rest_framework import mixins #导入方式
存放一些增删改查的一些类
CreateModelMixin,ListModelMixin,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin
二、generics模块
generics: from rest_framework import generics # 导入方式
首先mixins文件中就是一个一个类,写着某些方法,但是你想用于CBV,必须继承django的View,这里我们用rest_framework则需继承APIView,
这个py文件里定义了许多类,但是有一个最基本的类GenericAPIView(views.APIView),里面其他的类都会继承这个类,因为这个类定义的一些
方法是专门提供于mixins文件里的类的,再看其他generics模块里的其他类,你会发现那么类全是基于mixins模块和GenericAPIView之间的组
合,那么你想用rest_framework提供给我们的简便方法,那么必须要继承GenericAPIView,和mixins模块里的类。
三、通过一个简单的例子,顺带写mixins,generics的用处
eg:写一个接口,获取到所有书籍的数据,这里我只写视图类里的代码
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import ListModelMixin
from app import models
from write_serializers import BooksSerializers class Books(GenericAPIView,ListModelMixin):
queryset = models.Book.objects.all()
serializer_class = BooksSerializers def get(self,request,*args,**kwargs):
return self.list(request, *args, **kwargs)
好了,上面就是我们通过rest_framework提供的方法之一,完成了一个简单的接口,
来一个GET请求,便会执行这个视图类的get方法,最终返回了self.list方法的执行结果,那我们去看看list方法是怎么执行的,
那么我们顺着继承的基类去找list方法,基于深度查询,我们找完GenericAPIView继承的基类们,并没有找到,那么我们去ListModelMixin
这个类中找,这个类很简单,就写了一个list方法。
先看list方法,里面有self.filter_queryset(),self.paginate_queryset(),self.get_serializer()等等方法,很明显视图类中
没有写这些方法,ListModelMixin这个类里也没有,那么肯定在GenericAPIView,所以我之前就说了,GenericAPIView类是为mixins模块里
类提供方法的,所以二者必须一起使用。
分析1: queryset = self.filter_queryset(self.get_queryset())
queryset = self.filter_queryset(self.get_queryset())
这行代码整体意思应该能看得懂吧,filter_queryset这个方法的返回值赋值给queryset,而filter_queryset的参数是get_queryset
的返回值,那么我们先去看filter_queryset这方法的参数是什么,也就是get_queryset的返回值
首先,断言self.queryset这个属性的布尔值必须是True的,不是的话便会抛异常,我们先看GenericAPIView类中有没有这个属性(这并不是
属性的查找顺序),我们可以找到queryset = None,这样的话,我们再写视图类的话(前提是继承了这个类),没有写queryset这个属性或者值
为False,那么便会出错,所以queryset这个属性必须在视图类中为True。
根据这个我想到一点分享下,你可以用断言这种方法,指定它的子类必须要有该属性且值为True,对吧,方法也是一样,定义一个方法,在该方法
内写一个raise异常,rest_framework里很多就是通过这种方法,比如rest_framework.throttling.BaseThrottle这个类里的方法为allow_request。
接着上面继续,能走到return,就代表self.queryset肯定为True吧,前面的逻辑处理就不多说了。从现在看的话,那么这个queryset可以为
任何值吧,参数的值是什么了,继续看self.filter_queryset()这个方法的返回值
这个你可以看它的注释,大概意思是将传来的参数queryset,再过滤一遍,self.filter_backends它的值为None,前提不进行任何设置,而
这个设置是在settings文件里的REST_FRAMEWORK,也就是之前进行全局设置登陆认证,权限认证的地方。不进行设置的话,还是会返回之前的
传进来的参数。最终赋值给queryset
分析2:page = self.paginate_queryset(queryset)
page = self.paginate_queryset(queryset)
参数我们知道是什么,直接看paginate_queryset方法吧
self.paginator它是被装饰成属性的方法,self.paginator它的返回不是None就是一个对象(这个对象是进行分页的),上面我们列举的例子
视图类中并没有写pagination_class这个属性,那么就会去找到默认pagination_class,默认值为None,如果你再视图类中写了该属性,
值应该是是一个类,最后会返回这个类的对象回去。如果self.paginator为True,那么self.paginator就是一个对象了,就会执行该对象
下面的paginate_queryset这个方法。
提醒:不管self.paginator这个对象是自定义的类产生的,还是rest_framework自带的,那么肯定会有paginate_queryset方法。它的返
回值肯定是某一页的对象列表。
分析3:serializer = self.get_serializer(queryset, many=True)
不管有没有进行分页,都会执行get_serializer这个方法,返回值为serializer,最终返回serializer.data
不难可以看出,我们写的视图类中必须要有serializer_class属性,且有值,这个和前面queryset这属性是一样的。最终返回序列化的对象
总结下:我们写的视图类必须要有serializer_class --->> 写序列化类
queryset ---->> queryset的对象
可有可无看需求:pagination_class ---->> 进行分页的类
在GenericAPIView还有一个方法再说下get_object方法,这个方法在RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin都用上了,看方法名就差不多知道,返回一个对象。
分析1: queryset = self.filter_queryset(self.get_queryset()) 这个跟之前分析的一样,(见上面的分析1) 分析2: lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
这个其实没啥好说的,就说一点or,and的用法,我博客也写了这个,可以去看看 分析3: lookup_url_kwarg in self.kwargs
这句话很简单,判断lookup_url_kwarg这个值在不在self.kwargs这个容器里,但是这个self.kwargs到底是什么呢?self就是
当前的视图类的对象,它有kwargs这个属性?
先自己思考下,我在后面再写出来 分析4: obj = get_object_or_404(queryset, **filter_kwargs)
首先我们要弄清传的参数的是什么,filter_kwargs是一个字典({'pk':1}),那么**filter_kwargs就是pk=1,queryset这个就不
用在介绍了,看看这个方法get_object_or_404,
利用get方法,如果get里的参数不能找到唯一的一条数据的话,便会抛异常,通过捕捉异常去处理。程序顺利进行的话,那么返回的就是get
到的对象。
注意:属性的查看顺序,不要直接ctrl+鼠标左键,上面这个方法我就是直接ctrl+左键点进去的,虽然最后还是执行的这个方法,但是这是
误打误撞,在generics这个模块里,就有get_object_or_404方法。所以先去generics这个模块里get_object_or_404,再去
上面的get_object_or_404方法。。。 分析5: self.check_object_permissions(self.request, obj)
上面这行代码其实很熟悉,这个和之前进行用户权限认证差不多一样,不一样的是对谁进行权限认证,一个是用户,一个是一条记录(数据
库),也就是这里的obj。
permission就是一个进行权限认证的对象,那么该对象必须要有has_object_permission方法,进行一系列判断,权限许可的话,
就返回True,不许可的话,返回False。光这么说,也不知道用在哪个地方,我想了个例子:首先obj就是我们从数据库拿到的数据
(对象),其实数据也分等级,也有不同权限的数据,我们可以再根据判断,再进行数据的返回。
提醒:这里我们是继承了GenericAPIView,它里面的get_object里做的权限认证,我们不继承GenericAPIView,也一样可以去
调用这个方法。但check_object_permissions方法是rest_framework提供的。 对于get_object方法的分析差不多了,再讲上面的分析3,self.kwargs哪里来的。
我们回到APIView中的dispatch方法就知道了
generics这个模块里还有其他类,可以去看看,很简单就是类的继承问题。
好了,这块就写到这里了
rest_framework -- mixins&generics的更多相关文章
- Django-rest-framework 接口实现 rest_framework 中有已经定义好的 工具类 mixins generics viewsets
rest_framework.mixins 请求业务 的 5 种实现 mixin(混合类):不能单独使用,和其它类搭配起来使用(利用了Python支持多继承) rest_framework.mix ...
- drf框架 - 视图家族 | GenericAPIView | mixins | generics | viewsets
视图家族 view:视图 generics:工具视图 mixins:视图工具集 viewsets:视图集 学习曲线: APIView => GenericAPIView => mixins ...
- django-rest-framework-源码解析003-视图家族和路由(APIView/GenericAPIView/mixins/generics/viewsets)
视图家族 视图家族在rest_framework源码位置和学习曲线为: rest_framework.views: 基本视图(APIView) rest_framework.generics: 工具视 ...
- rest_framework基于generics.CreateAPIView创建用户
最近在写新版的devops3.0,被generics.CreateAPIView创建用户密码序列化的问题折磨的欲仙欲死.反复看源码测试,得出下面的流程,这也是做generics.CreateAPIVi ...
- mixins,generics(ApiView)
#生成序列化对象class BookModelSerizter(serializers.ModelSerializer): class Meta: model=Book fields='__all__ ...
- 视图家族之mixins视图工具类与generics工具视图类
视图家族之mixins视图工具类与generics工具视图类 一.mixins视图工具类 作用: 提供了几种后端视图(对数据资源进行曾删改查)处理流程的实现,如果需要编写的视图属于这五种,则视图可以通 ...
- REST_FRAMEWORK加深记忆-三种CLASS VIEW的进化史
一层一层的封装,又能到底层,就会有全局感啦... from rest_framework import status from rest_framework.response import Respo ...
- Python之Django rest_Framework(3)
补充: 为什么要前后端分离: a.因为前端它有自己框架,这样它的效率就非常高 b.不做前后端分离,公司如果既有客户端,又有app这种情况下你就的写两遍 django rest ...
- rest_framework之视图及源码剖析
最初形态(工作中可能会使用) 引子 Django的CBV我们应该都有所了解及使用,大体概括一下就是通过定义类并在类中定义get post put delete等对应于请求方法的方法,当请求来的时候会自 ...
随机推荐
- Windows无法启动MySQL服务,错误1067
问题:mysql服务启动异常 找出原因 检查D:\mysql-5.6.20-winx64\data目录下client-02.err文件的错误信息(以err为后缀名的文件是mysql的日志文件) 修改配 ...
- IO流之流的操作规律
流的操作规律 IO流中对象很多,解决问题(处理设备上的数据时)到底该用哪个对象呢? 把IO流进行了规律的总结(四个明确): l 明确一:要操作的数据是数据源还是数据目的. 源:InputStream ...
- 关于Java中的线程安全(线程同步)
java中的线程安全是什么: 就是线程同步的意思,就是当一个程序对一个线程安全的方法或者语句进行访问的时候,其他的不能再对他进行操作了,必须等到这次访问结束以后才能对这个线程安全的方法进行访问 什么叫 ...
- App更新(Android)
App更新(Android) 前言:现在一般的Android软件都是需要不断更新的,当你打开某个app的时候,如果有新的版本,它会提示你有新版本需要更新.该项目实现的就是这个功能.并且有强制更新和更 ...
- Android应用开发基础之一:数据存储和界面展现(一)
Android项目的目录结构 Activity:应用被打开时显示的界面 src:项目代码 R.java:项目中所有资源文件的资源id Android.jar:Android的jar包,导入此包方可使用 ...
- SQL Server ->> 存储过程sp_rename重命名数据对象
1) 表转移Schema和重命名表 ALTER SCHEMA Stage TRANSFER dbo.Stage_AAA; EXEC sp_rename 'Stage.Stage_AAA', 'AAA' ...
- LAB2 软件测试 Selenium上机实验 2017
1.安装SeleniumIDE插件 打开Firefox——>菜单栏——>附加组件——>获取附加组件——>查看更多附加组件——>搜索框输入SeleniumIDE并查找——& ...
- CSS基础语法(一) CSS的3种引入
CSS样式表 CSS可算是网页设计的一个突破,它解决了网页界面排版的难题.可以这么说,HTML的Tag主要是定义网页的内容(Content),而CSS决定这些网页内容如何显示(Layout). Web ...
- 【转载】#457 Converting Between enums and their Underlying Type
When you declare an enum, by default each enumerated value is represented internally with an int. (S ...
- [原]Android打包之Eclipse打包
Android自动打包流程详细图: 步骤一: 在工程中新建一个build.xml. 步骤二: 给工程配置ant工具. 选择ant工具的步骤如下: Windows->Shown view-> ...