0x00 引言

本篇对drf中的mixins进行简要的分析总结。
Mixins在drf中主要配合viewset共同使用,实现http方法与mixins的相关类与方法进行关联。

from rest_framework import viewsets

在这个viewset中,只要有5类Minxin,他们与http方法对应如下:

下面,我们将逐个Mixins介绍!

0x01 CreateModelMixin

# 源码
class CreateModelMixin(object):
"""
Create a model instance ==>创建一个实例
"""
def create(self, request, *args, **kwargs): # 获取相关serializer
serializer = self.get_serializer(data=request.data) # 进行serializer的验证
# raise_exception=True,一旦验证不通过,不再往下执行,直接引发异常
serializer.is_valid(raise_exception=True) # 调用perform_create()方法,保存实例
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 {}

由上图可以看出这个类的一个逻辑,其中,perform_create( )对serializer直接进行save保存,当在一些情境下,我们需要对perform_create( )进行重写。 那么我们现在可能有一个下面的需要:
 

假设现在有一个course课程model,里面维持了一个数,记录课程收藏数,还存在一个用户收藏userfav的model(应当有一个外键指向course),当一个用户对课程进行收藏,理论上现在post进来的应该是userfav的instance,显然,我们还需要对相应course的收藏数进行+1。
这个时候,我们就需要重写perform_create( )方法!

def perform_create(self, serializer):
# 重写save的逻辑
instance = serializer.save()
course = instance.course
course.fav_num += 1
course.save()

显然,这不是唯一的解决方法,我们还可以在seriliazer进行设置,我们还可以使用drf的信号量进行解决!

0x02 ListModelMixin

# 源码
class ListModelMixin(object):
"""
List a queryset.==> 列表页获取
"""
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset()) # 这是一个分页功能,如果在viewset中设置了pagination_class,那么这里就会起作用
# 获取当前页的queryset,如果不存在分页,返回None
page = self.paginate_queryset(queryset) if page is not None:
# 分页不为空,那么不能简单的执行Response(serializer.data)
# 还需要将相关的page信息序列化在进行响应
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)

ListModelMixin一般用来获取列表页,大多数情况下比较简单,不需要重写相关的方法。

0x03 RetriveModelMixin

# 源码
class RetrieveModelMixin(object):
"""
Retrieve a model instance.==> 获取某一个对象的具体信息
"""
def retrieve(self, request, *args, **kwargs):
# 一般访问的url都为/obj/id/这种新式
# get_object()可以获取到这个id的对象
# 注意在viewset中设置lookup_field获取重写get_object()方法可以指定id具体对象是什么~!
instance = self.get_object()
serializer = self.get_serializer(instance)
return Response(serializer.data)

对retrieve这个方法的重写几率比较高,例如我们在增加点击数的时候,经常要对其进行一个重写。

0x04 ReriveModelMixin

# 源码
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)

RetrieveModelMixin的实现逻辑基本整合了Create以及Retrieve,先得到具体的实例,再对其进行验证以及保存,如果需要对更新这个逻辑进行自定义,那么需要重写perform_update( )方法,而尽量少去重写update( )。

0x05 DestoryModelMixin

# 源码
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()

DestroyModelMixin的逻辑也相对比较简单,我们取CreateModelMixin下面的例子,当我们取消收藏,那么我们的DestroyModelMixin就发挥作用了。同理

def perform_create(self, serializer):
instance = serializer.save()
course = instance.course
if course.fav_num > 0:
course.fav_num -= 1
else:
course.fav_num = 0
course.save()

0x05 小结

mixins相对比较好理解,本篇只是简要的分析了源码的内容以及各个mixins的逻辑,最重要的还是学会去重写它们相关的方法。
一般情况下,当我们在操作某一个model的时候,涉及到另外一个model中数据的修改,那么就需要对这个mixins下执行save的逻辑的方法进行重写。

参考

RESTful源码笔记之RESTful Framework的Mixins小结的更多相关文章

  1. RESTful源码笔记之RESTful Framework的基本组件

    快速实例 Quickstart 序列化 创建一个序列化类 简单使用 开发我们的Web API的第一件事是为我们的Web API提供一种将代码片段实例序列化和反序列化为诸如json之类的表示形式的方式. ...

  2. RESTful源码笔记之RESTful Framework的APIview, Viewset总结分析

    0x00  引言 官方文档:http://www.django-rest-framework.org/drf为我们提供强大的通用view的功能,本博客对这些view进行简要的总结分析.首先,我们看一下 ...

  3. Django框架(十八)—— CBV源码分析、restful规范、restframework框架

    目录 CBV源码分析.restful规范.restframework框架 一.CBV源码分析 1.url层的使用CBV 2.as_view方法 3.view方法 4.dispatch方法(可以在视图层 ...

  4. Zepto源码笔记(一)

    最近在研究Zepto的源码,这是第一篇分析,欢迎大家继续关注,第一次写源码笔记,希望大家多指点指点,第一篇文章由于首次分析原因不会有太多干货,希望后面的文章能成为各位大大心目中的干货. Zepto是一 ...

  5. redis源码笔记(一) —— 从redis的启动到command的分发

    本作品采用知识共享署名 4.0 国际许可协议进行许可.转载联系作者并保留声明头部与原文链接https://luzeshu.com/blog/redis1 本博客同步在http://www.cnblog ...

  6. AsyncTask源码笔记

    AsyncTask源码笔记 AsyncTask在注释中建议只用来做短时间的异步操作,也就是只有几秒的操作:如果是长时间的操作,建议还是使用java.util.concurrent包中的工具类,例如Ex ...

  7. Java Arrays 源码 笔记

    Arrays.java是Java中用来操作数组的类.使用这个工具类可以减少平常很多的工作量.了解其实现,可以避免一些错误的用法. 它提供的操作包括: 排序 sort 查找 binarySearch() ...

  8. Tomcat8源码笔记(八)明白Tomcat怎么部署webapps下项目

    以前没想过这么个问题:Tomcat怎么处理webapps下项目,并且我访问浏览器ip: port/项目名/请求路径,以SSM为例,Tomcat怎么就能将请求找到项目呢,项目还是个文件夹类型的? Tom ...

  9. Tomcat8源码笔记(七)组件启动Server Service Engine Host启动

    一.Tomcat启动的入口 Tomcat初始化简单流程前面博客介绍了一遍,组件除了StandardHost都有博客,欢迎大家指文中错误.Tomcat启动类是Bootstrap,而启动容器启动入口位于 ...

随机推荐

  1. PHP虚拟主机的配置

    今天配置了一下虚拟目录,以下是我的配置方法. 1  编辑httpd.conf,查找Include conf/extra/httpd-vhosts.conf,把前面注释符号“#”删掉. 2  编辑htt ...

  2. php 连接mongdb的类

    <?php/** * php 连接mongdb的类的封装 * @author 李秀然 */ class mongdb{ private $host;//"mongodb://admin ...

  3. C++11-新增正则表达式

    #include <regex> #include <iostream> #include <string> #include <atlstr.h> s ...

  4. 网络子系统46_ip协议数据帧的转发

    //调用路径ip_rcv->ip_rcv_finish->dst_input->(skb->dst->input) //ip_forward以回调函数的形式,保存在skb ...

  5. OpenGL ES2学习笔记(6)-- Line Strip和Line Loop

    Line Strip 上一篇文章画了两条线段,但是用了4个点.如果几条线段首尾相接的话,可以让OpenGL把他们当成Line Strip来画,这样就可以用n+1个点来画n条线段. 代码 import ...

  6. JS-运动基础——案例应用:淡入淡出效果

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. MyBatis官方文档——XML 映射配置文件

    XML 映射配置文件 MyBatis 的配置文件包含了影响 MyBatis 行为甚深的设置(settings)和属性(properties)信息.文档的顶层结构如下: configuration 配置 ...

  8. strace命令的使用

    author: headsen  chen date: 2018-08-28   21:25:48 跟踪一个命令的过程: [root@zabbix-test ~]# yum -y install st ...

  9. ELK平台介绍

    在搜索ELK资料的时候,发现这篇文章比较好,于是摘抄一小段: 以下内容来自:http://baidu.blog.51cto.com/71938/1676798 日志主要包括系统日志.应用程序日志和安全 ...

  10. 【BZOJ1568】[JSOI2008]Blue Mary开公司 线段树

    [BZOJ1568][JSOI2008]Blue Mary开公司 Description Input 第一行 :一个整数N ,表示方案和询问的总数.  接下来N行,每行开头一个单词“Query”或“P ...