博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
django rest framework mixins小结
阅读量:6367 次
发布时间:2019-06-23

本文共 4678 字,大约阅读时间需要 15 分钟。

引言

  本篇对drf中的mixins进行简要的分析总结。

  mixins在drf中主要配合viewset共同使用,实现http方法与mixins的相关类与方法进行关联。关于可以看我另外一篇博客,这里不过多介绍。

from rest_framework import viewsets复制代码

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

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

1. 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的信号量进行解决!

2. 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一般用来获取列表页,大多数情况下比较简单,不需要重写相关的方法。

3. RetrieveModelMixin

# 源码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这个方法的重写几率比较高,例如我们在增加点击数的时候,经常要对其进行一个重写。

4. RetrieveModelMixin

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

5. DestroyModelMixin

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

小结

  mixins相对比较好理解,本篇只是简要的分析了源码的内容以及各个mixins的逻辑,最重要的还是学会去重写它们相关的方法。

  一般情况下,当我们在操作某一个model的时候,涉及到另外一个model中数据的修改,那么就需要对这个mixins下执行save的逻辑的方法进行重写。

CSDN:http://blog.csdn.net/l_vip/article/details/79142105

你可能感兴趣的文章
内存模型
查看>>
table边框设置
查看>>
IOS开发之实现App消息推送(最新)
查看>>
C++ 资源管理之 RAII
查看>>
UVA11234 Expressions
查看>>
博文参考:Java编程中“为了性能”尽量要做到的一些地方
查看>>
【JAVASCRIPT】jquery实现ajax无刷新评论
查看>>
flex---->MXML语法
查看>>
OpenCV学习笔记(30)KAZE 算法原理与源码分析(四)KAZE特征的性能分析与比较...
查看>>
linux内核模块编译
查看>>
【数据存储】操作资源文件
查看>>
数字信号处理之低通滤波器设计
查看>>
Learning Cocos2d-x for WP8(3)——文字篇
查看>>
转 AngularJS 2.0将面向移动应用并放弃旧浏览器
查看>>
Length of Last Word
查看>>
Vue 数据绑定语法
查看>>
C++课程小结 继承与派生
查看>>
SQL Server 自定义字符串分割函数
查看>>
从CMOS到触发器(二)
查看>>
linux 时间同步的2种方法
查看>>