Django的rest_framework的视图之Mixin类编写视图源码解析

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Django的rest_framework的视图之Mixin类编写视图源码解析 Mixin类编写视图 我们这里用auther表来做演示,先为auther和autherdetail写2个url 1 2 url(r'^autherdetail/(?P\d+)', views.

Django的rest_framework的视图之Mixin类编写视图源码解析

Mixin类编写视图

我们这里用auther表来做演示,先为auther和autherdetail写2个url

1
2
url(r '^autherdetail/(?P<id>\d+)' , views.Book_detail_cbv.as_view(), name = "autherdetail" ),
url(r '^auther/' , views.Book_cbv.as_view(),name = "auther" ),  

 

然后分别为这2个类写对应的序列化的类

1
2
3
4
class  authermodelserializer(serializers.ModelSerializer):
     class  Meta:
         model  =  models.Auther
         fields  =  "__all__"

 

下面我们开写视图函数  

需要在view文件中导入2个模块

1
2
from  rest_framework  import  mixins
from  rest_framework  import  generics

 

先介绍一下mixins类,我们主要用mixins类来对queryset对象或者model对象做操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mixins.ListModelMixin
 
这个是用来显示queryset的数据
 
mixins.CreateModelMixin
 
这个用来创建一条model对象
 
mixins.RetrieveModelMixin
 
这个是用来显示一个model对象
 
mixins.DestroyModelMixin
 
这个是用来删除一个model对象
 
mixins.UpdateModelMixin
 
这个是用来更新一个model对象

  

下面我们一个一个来看下面的类

1、看下mixins.ListModelMixin

这个类就只有一个方法,list方法,我们看下面的代码其实很熟悉,就是把一个queryset对象做序列化后,然后把序列化后的结果返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class  ListModelMixin( object ):
     """
     List a queryset.
     """
     def  list ( self , request,  * args,  * * kwargs):
         queryset  =  self .filter_queryset( self .get_queryset())
 
         page  =  self .paginate_queryset(queryset)
         if  page  is  not  None :
             serializer  =  self .get_serializer(page, many = True )
             return  self .get_paginated_response(serializer.data)
 
         serializer  =  self .get_serializer(queryset, many = True )
         return  Response(serializer.data)

  

我们这里看到get_serializer中的参数有个queryset,那么这个queryset是什么呢?

 

 

 通过上面的图,我们大致可以猜到,是由self.get_queryset()这个方法返回的结果,那么这个方法又干了什么呢?

首先我们要清楚self是什么?

 

 从上面的图我们知道,self其实就是Auther_view这个类的实例对象,这个实例对象根本就没有get_queryset这个方法,但是由于这个类继承了3个类,我们一个一个找,最终在

generics.GenericAPIView这个类中找到了get_queryset这个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def  get_queryset( self ):
     """
     Get the list of items for this view.
     This must be an iterable, and may be a queryset.
     Defaults to using `self.queryset`.
 
     This method should always be used rather than accessing `self.queryset`
     directly, as `self.queryset` gets evaluated only once, and those results
     are cached for all subsequent requests.
 
     You may want to override this if you need to provide different
     querysets depending on the incoming request.
 
     (Eg. return a list of items that is specific to the user)
     """
     assert  self .queryset  is  not  None , (
         "'%s' should either include a `queryset` attribute, "
         "or override the `get_queryset()` method."
         %  self .__class__.__name__
     )
 
     queryset  =  self .queryset
     if  isinstance (queryset, QuerySet):
         # Ensure queryset is re-evaluated on each request.
         queryset  =  queryset. all ()
     return  queryset

  

我们可以很清晰的看到get_queryset这个方法返回的结果就是self.queryset

那么self.queryset这个是什么呢?

我们在Auhter_view这个类中已经定义了这个类变量,所以我们这里定义的2个类变量的名称是固定的,不能随意修改的,属于配置项

 

 下面我们走的流程就和之前差不多了

先定义get请求的处理的函数

 

因为mixins.ListModelMixin这个类是为了显示queryset对象的类,那么下面我们进入这个类

 

 所以我们在get方法中,直接调用list方法的返回结果就是我们想要的结果

 

 

2、在来看mixin.CreateModelMixin类

这个类是为了创建一个model对象

首先进入这个类,看下具体的代码

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class  CreateModelMixin( object ):
     """
     Create a model instance.
     """
     def  create( self , request,  * args,  * * kwargs):
         serializer  =  self .get_serializer(data = request.data)
         serializer.is_valid(raise_exception = True )
         self .perform_create(serializer)
         headers  =  self .get_success_headers(serializer.data)
         return  Response(serializer.data, status = status.HTTP_201_CREATED, headers = headers)
 
     def  perform_create( self , serializer):
         serializer.save()
 
     def  get_success_headers( self , data):
         try :
             return  { 'Location' str (data[api_settings.URL_FIELD_NAME])}
         except  (TypeError, KeyError):
             return  {}

  

下面我们来分析一下代码

 

首先这里有个self.get_serializer方法,这个方法也在generics.GenericAPIView类中

下面我们在来看下get_serializer方法

1
2
3
4
5
6
7
8
def  get_serializer( self * args,  * * kwargs):
     """
     Return the serializer instance that should be used for validating and
     deserializing input, and for serializing output.
     """
     serializer_class  =  self .get_serializer_class()
     kwargs[ 'context' =  self .get_serializer_context()
     return  serializer_class( * args,  * * kwargs)

  

 

 我们在来看下get_serializer_class这个方法

 

 我们看到非常清楚,这个函数的返回值就是我们先前定义个serializer_class的类变量,所以这个类变量的名称也不能修改,必须要这么写,属于一个配置类的变量

 

 流程我们已经梳理清楚了,下面我们在看下post请求的视图函数

 

 post请求调用的mixins.CreateModelMixin类中的create方法

1
2
3
4
5
6
7
8
9
10
class  CreateModelMixin( object ):
     """
     Create a model instance.
     """
     def  create( self , request,  * args,  * * kwargs):
         serializer  =  self .get_serializer(data = request.data)
         serializer.is_valid(raise_exception = True )
         self .perform_create(serializer)
         headers  =  self .get_success_headers(serializer.data)
         return  Response(serializer.data, status = status.HTTP_201_CREATED, headers = headers)

  

 

 最后我们在看下perform.create这个方法,是不是很熟悉了,调用save方法保存

 

 3、然后来看下mixins.RetriveModelMixin类

先看下这个类的代码

1
2
3
4
5
6
7
8
class  RetrieveModelMixin( object ):
     """
     Retrieve a model instance.
     """
     def  retrieve( self , request,  * args,  * * kwargs):
         instance  =  self .get_object()
         serializer  =  self .get_serializer(instance)
         return  Response(serializer.data)

  

然后在来看下get_object这个方法干了什么,这个方法同样在generics.GenericAPIView类中,我们一猜就知道这个方法是获取一个model对象,然后对这个model对象进行序列化处理

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def  get_object( self ):
     """
     Returns the object the view is displaying.
 
     You may want to override this if you need to provide non-standard
     queryset lookups.  Eg if objects are referenced using multiple
     keyword arguments in the url conf.
     """
     queryset  =  self .filter_queryset( self .get_queryset())
 
     # Perform the lookup filtering.
     lookup_url_kwarg  =  self .lookup_url_kwarg  or  self .lookup_field
 
     assert  lookup_url_kwarg  in  self .kwargs, (
         'Expected view %s to be called with a URL keyword argument '
         'named "%s". Fix your URL conf, or set the `.lookup_field` '
         'attribute on the view correctly.'  %
         ( self .__class__.__name__, lookup_url_kwarg)
     )
 
     filter_kwargs  =  { self .lookup_field:  self .kwargs[lookup_url_kwarg]}
     obj  =  get_object_or_404(queryset,  * * filter_kwargs)
 
     # May raise a permission denied
     self .check_object_permissions( self .request, obj)
 
     return  obj

  

我们看到这个方法确实返回一个obj对象

 

 

 

 

最后看下get请求,调用mixins。RetrieveModelMixin类中的retieve方法返回我们要查询的结果

 

 4、然后我们在看下mixins.DestroyModelMixin类

 直接拿到model独享,然后调用perform_destory方法删除这个model对象

1
2
3
4
5
6
7
8
9
10
11
class  DestroyModelMixin( object ):
     """
     Destroy a model instance.
     """
     def  destroy( self , request,  * args,  * * kwargs):
         instance  =  self .get_object()
         self .perform_destroy(instance)
         return  Response(status = status.HTTP_204_NO_CONTENT)
 
     def  perform_destroy( self , instance):
         instance.delete()

  

然后我们在看下视图函数中是如何处理delete请求的

1
2
3
4
5
6
7
8
9
class  Autherdetail_view(mixins.RetrieveModelMixin,mixins.DestroyModelMixin,mixins.UpdateModelMixin,generics.GenericAPIView):
     queryset  =  models.Auther.objects. all ()
     serializer_class  =  authermodelserializer
 
     def  get( self ,request, * args, * * kwargs):
         return  self .retrieve(request, * args, * * kwargs)
 
     def  delete( self ,request, * args, * * kwargs):
         return  self .destroy(request, * args, * * kwargs)

  

直接返回mixins.DestoryModelMixins的detory函数的返回值就可以了

 

 

5、最后看下mixins.UpdateModelMixin类

同样,先获取model对象,然后获取序列化类,然后把model对象和request.data一起传递给序列化类

序列化类在调用调用sava方法保存数据 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class  UpdateModelMixin( object ):
     """
     Update a model instance.
     """
     def  update( self , request,  * args,  * * kwargs):
         partial  =  kwargs.pop( 'partial' False )
         instance  =  self .get_object()
         serializer  =  self .get_serializer(instance, data = request.data, partial = partial)
         serializer.is_valid(raise_exception = True )
         self .perform_update(serializer)
 
         if  getattr (instance,  '_prefetched_objects_cache' None ):
             # If 'prefetch_related' has been applied to a queryset, we need to
             # forcibly invalidate the prefetch cache on the instance.
             instance._prefetched_objects_cache  =  {}
 
         return  Response(serializer.data)
 
     def  perform_update( self , serializer):
         serializer.save()
 
     def  partial_update( self , request,  * args,  * * kwargs):
         kwargs[ 'partial' =  True
         return  self .update(request,  * args,  * * kwargs)

  

 

 

 

我们在看put请求的视图函数

1
2
3
4
5
6
7
8
9
10
11
12
class  Autherdetail_view(mixins.RetrieveModelMixin,mixins.DestroyModelMixin,mixins.UpdateModelMixin,generics.GenericAPIView):
     queryset  =  models.Auther.objects. all ()
     serializer_class  =  authermodelserializer
 
     def  get( self ,request, * args, * * kwargs):
         return  self .retrieve(request, * args, * * kwargs)
 
     def  delete( self ,request, * args, * * kwargs):
         return  self .destroy(request, * args, * * kwargs)
 
     def  put( self ,request, * args, * * kwargs):
         return  self .update(request, * args, * * kwargs)

  

 

原文地址https://www.cnblogs.com/bainianminguo/p/10463741.html

相关文章
|
10天前
|
数据可视化 数据挖掘 BI
团队管理者必读:高效看板类协同软件的功能解析
在现代职场中,团队协作的效率直接影响项目成败。看板类协同软件通过可视化界面,帮助团队清晰规划任务、追踪进度,提高协作效率。本文介绍看板类软件的优势,并推荐五款优质工具:板栗看板、Trello、Monday.com、ClickUp 和 Asana,助力团队实现高效管理。
32 2
|
2天前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
|
2天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
2天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是"将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。创建型模式分为5种:单例模式、工厂方法模式抽象工厂式、原型模式、建造者模式。
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
26天前
|
缓存 监控 Java
Java线程池提交任务流程底层源码与源码解析
【11月更文挑战第30天】嘿,各位技术爱好者们,今天咱们来聊聊Java线程池提交任务的底层源码与源码解析。作为一个资深的Java开发者,我相信你一定对线程池并不陌生。线程池作为并发编程中的一大利器,其重要性不言而喻。今天,我将以对话的方式,带你一步步深入线程池的奥秘,从概述到功能点,再到背景和业务点,最后到底层原理和示例,让你对线程池有一个全新的认识。
53 12
|
21天前
|
PyTorch Shell API
Ascend Extension for PyTorch的源码解析
本文介绍了Ascend对PyTorch代码的适配过程,包括源码下载、编译步骤及常见问题,详细解析了torch-npu编译后的文件结构和三种实现昇腾NPU算子调用的方式:通过torch的register方式、定义算子方式和API重定向映射方式。这对于开发者理解和使用Ascend平台上的PyTorch具有重要指导意义。
|
3天前
|
安全 搜索推荐 数据挖掘
陪玩系统源码开发流程解析,成品陪玩系统源码的优点
我们自主开发的多客陪玩系统源码,整合了市面上主流陪玩APP功能,支持二次开发。该系统适用于线上游戏陪玩、语音视频聊天、心理咨询等场景,提供用户注册管理、陪玩者资料库、预约匹配、实时通讯、支付结算、安全隐私保护、客户服务及数据分析等功能,打造综合性社交平台。随着互联网技术发展,陪玩系统正成为游戏爱好者的新宠,改变游戏体验并带来新的商业模式。
|
1月前
|
设计模式 前端开发 数据库
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
182 45
|
1月前
|
安全 数据库 开发者
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第26天】本文详细介绍了如何在Django框架下进行全栈开发,包括环境安装与配置、创建项目和应用、定义模型类、运行数据库迁移、创建视图和URL映射、编写模板以及启动开发服务器等步骤,并通过示例代码展示了具体实现过程。
65 2
|
1月前
|
安全 数据库 C++
Python Web框架比较:Django vs Flask vs Pyramid
Python Web框架比较:Django vs Flask vs Pyramid
44 1

热门文章

最新文章

推荐镜像

更多