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等对应于请求方法的方法,当请求来的时候会自 ...
随机推荐
- js数组与字符串相互转换
一.数组转字符串(将数组元素用某个字符连接成字符串) var a, b;a = new Array(0,1,2,3,4);b = a.join("-"); 二.字符串转数组(将字符 ...
- 关于controller和apicontroller的跨域实现过滤器的不同
1.controller的跨域访问 filter的实现请继承System.Web.Mvc.ActionFilterAttribute 2.apicontroller的跨域访问 filter的实现请继承 ...
- PHP json数据的运用
今天这里总结一下json数据的使用实例,从5.2版本开始,PHP原生提供json_encode()和json_decode()函数,前者用于编码,后者用于解码. 一.json_encode() 1 2 ...
- Sharepoint学习笔记—修改SharePoint的Timeouts (Execution Timeout)
有时在Sharepoin中有些执行任务可能会超过Sharepoint环境默认的Timout限制,这种情况下系统会报"Request Timed out"错误.对此我们可以在两个层次 ...
- 15分钟完成基于Azure公有云搭建远程测试环境
- SSM整合的简单实现
整合需要的jar包和源码将在文末给出 本文参考黑马程序员视频,由于视频用的环境和我使用的环境不同,建议使用我的环境及jar包(比较新) 一 整合思路 第一步 整合dao层 mybatis和spring ...
- Struts2学习-拦截器2
1.做一个登陆页面(loginView.jsp,才用Action来访问),2.登陆成功后,可以跳转到系统的首页(index.jsp),3.首页有一个链接(testOtherAction访问其它的功能模 ...
- msysGit删除github文件
首先打开msysGit命令行工具 首先使用命令 git rm xxx 删除远程文件 提交删除操作 git commit -m "test" ,并推送到远程仓库 git push o ...
- June 14th 2017 Week 24th Wednesday
Love looks not with the eyes, but with the mind. 爱,不在眼里,而在心中. Staring in her eyes and you will find ...
- 字符串相关函数-strcpy()与strcmp()
一些小问题,避免出现低级错误. 1.strcmp(s1,s2): 字符串指针不见'\0'不回头,这个常在与单个字符作比较时写着写着就忘了. char* p_ch1="this is an e ...