上面的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的更多相关文章

  1. Django-rest-framework 接口实现 rest_framework 中有已经定义好的 工具类 mixins generics viewsets

    rest_framework.mixins 请求业务 的 5 种实现 ​ mixin(混合类):不能单独使用,和其它类搭配起来使用(利用了Python支持多继承) rest_framework.mix ...

  2. drf框架 - 视图家族 | GenericAPIView | mixins | generics | viewsets

    视图家族 view:视图 generics:工具视图 mixins:视图工具集 viewsets:视图集 学习曲线: APIView => GenericAPIView => mixins ...

  3. django-rest-framework-源码解析003-视图家族和路由(APIView/GenericAPIView/mixins/generics/viewsets)

    视图家族 视图家族在rest_framework源码位置和学习曲线为: rest_framework.views: 基本视图(APIView) rest_framework.generics: 工具视 ...

  4. rest_framework基于generics.CreateAPIView创建用户

    最近在写新版的devops3.0,被generics.CreateAPIView创建用户密码序列化的问题折磨的欲仙欲死.反复看源码测试,得出下面的流程,这也是做generics.CreateAPIVi ...

  5. mixins,generics(ApiView)

    #生成序列化对象class BookModelSerizter(serializers.ModelSerializer): class Meta: model=Book fields='__all__ ...

  6. 视图家族之mixins视图工具类与generics工具视图类

    视图家族之mixins视图工具类与generics工具视图类 一.mixins视图工具类 作用: 提供了几种后端视图(对数据资源进行曾删改查)处理流程的实现,如果需要编写的视图属于这五种,则视图可以通 ...

  7. REST_FRAMEWORK加深记忆-三种CLASS VIEW的进化史

    一层一层的封装,又能到底层,就会有全局感啦... from rest_framework import status from rest_framework.response import Respo ...

  8. Python之Django rest_Framework(3)

    补充:  为什么要前后端分离:       a.因为前端它有自己框架,这样它的效率就非常高       b.不做前后端分离,公司如果既有客户端,又有app这种情况下你就的写两遍 django rest ...

  9. rest_framework之视图及源码剖析

    最初形态(工作中可能会使用) 引子 Django的CBV我们应该都有所了解及使用,大体概括一下就是通过定义类并在类中定义get post put delete等对应于请求方法的方法,当请求来的时候会自 ...

随机推荐

  1. GUI应用程序架构的十年变迁:MVC,MVP,MVVM,Unidirectional,Clean

    十年前,Martin Fowler撰写了 GUI Architectures 一文,至今被奉为经典.本文所谈的所谓架构二字,核心即是对于对于富客户端的 代码组织/职责划分 .纵览这十年内的架构模式变迁 ...

  2. r.js压缩打包

    AMD模块化开发中的代码压缩打包工具——r.js 环境搭建基于nodejs:用于AMD模块化开发中的项目文件压缩打包,不是AMD模式也是可以的 javascript部分 压缩javascript项目开 ...

  3. centOs升级

    因为军佬放弃制作Centos7的网络重装包,又Centos7的安装引导和6有较大区别所以,选择曲线救国(技术不行,只能这样乱搞)前文:Centos6.9一键重装包https://ppx.ink/net ...

  4. 在 Eclipse Juno 上安装 Marketplace

    Select Help/Install new software... from the menu, select the Juno update site (http://download.ecli ...

  5. Microsoft BI - SSRS

    1. Shared Dataset 功能在 SQL Server 2008 R2 / 2012 / 2014 的下列三个版本中不支持,详情请参考此处: Express Edition with Adv ...

  6. 基于ArcGIS Runtime 100.x 的移动应用程序开发框架 开源

    ArcGIS Runtime作为新一代的轻量GIS应用开发产品,它提供多种API,可以使用Android,iOS,Java,Mac OS X(Objective-C/Swift)..NET,Qt(C+ ...

  7. requireJS的优化工具 ---- r.js

    requireJS是javascript的模块加载器,是基于AMD规范实现的. r.js是其提供的对模块进行打包和构建的一个工具 下载 r.js 创建r.js 的配置文件 build.js build ...

  8. HQL(Hibernate Query Language)

    1. NativeSQL > HQL > EJB QL(JP QL 1.0) > QBC(Query By Criteria) > QBE(Query By Example)2 ...

  9. C#设计模式之代理模式(一)

    原文地址:http://blog.csdn.net/lovelion/article/details/8227953 代理模式是常用的结构型设计模式之一,当无法直接访问某个对象或访问某个对象存在困难时 ...

  10. Linux--Bind服务搭建

    Bind域名解析服务 服务功能:提供域名解析 构建主从域名服务器 1)环境部署 ip=192.168.1.50(主) ip=192.168.1.51(从) [root@localhost Packag ...