django rest framework mixins小结

栏目: Python · 发布时间: 6年前

内容简介:django rest framework mixins小结

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

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

from rest_framework import viewsets

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

django rest framework mixins小结

下面,我们将逐个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 {}

django rest framework mixins小结

由上图可以看出这个类的一个逻辑,其中,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()

以上所述就是小编给大家介绍的《django rest framework mixins小结》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Perl语言入门 第六版(中文版)

Perl语言入门 第六版(中文版)

Randal L.Schwartz、brian d foy、Tom Phoenix / 盛春 / 东南大学出版社 / 2012-3 / 62.00元

《Perl语言入门(第6版)(中文版)》根据作者施瓦茨、福瓦、菲尼克斯从1991年开始的教学经验积累汇聚而成,多年来十分畅销。此次第六版涵盖了最新的Perl5.14版本的变化。《Perl语言入门(第6版)(中文版)》每章都包含若干习题,帮助你巩固消化刚学到的知识。也许其他书籍只是想着灌输Perl编程的条条框框,但《Perl语言入门(第6版)(中文版)》不同,我们希望把你培养成一名真正的Perl程序......一起来看看 《Perl语言入门 第六版(中文版)》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

html转js在线工具
html转js在线工具

html转js在线工具