django rest framework mixins小结
本篇对drf中的mixins进行简要的分析总结。
from rest_framework import viewsets
在这个viewsets中,只有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的逻辑的方法进行重写。
django rest framework mixins小结的更多相关文章
- django rest framework serializers小结
注:转载至https://blog.csdn.net/l_vip/article/details/79156113 引言 serializers是什么?官网是这样的”Serializers allow ...
- django rest framework mixins
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAXQAAAEZCAIAAAAIa0mAAAAU/0lEQVR4nO2d247cxoGG5y3yKH6AAf
- Django rest framework的基本用法
今天在网上看到几篇比较不错的drf基本功能介绍,本来想自己写一篇,后来发现脱不开原作者的思路,遂卒,直接扔链接小伙伴自己去看吧.... 1.django rest framework apiview. ...
- Django序列化&django REST framework
第一章.Django序列化操作 1.django的view实现商品列表页(基于View类) # 通过json来序列化,但手写字典key代码量较大,容易出错:还有遇到时间,图片序列化会报错 from g ...
- Django REST framework+Vue 打造生鲜超市(四)
五.商品列表页 5.1.django的view实现商品列表页 (1)goods/view_base.py 在goods文件夹下面新建view_base.py,为了区分django和django res ...
- Django REST framework+Vue 打造生鲜超市(五)
六.商品类别数据展示 6.1. 商品类别数据接口 (1)商品分类有两个接口: 一种是全部分类:一级二级三级 一种是某一类的分类以及商品详细信息: 开始写商品分类的接口 (2)序列化 给分类添加三级分类 ...
- Django REST framework+Vue 打造生鲜超市(十二)
十三.首页.商品数量.缓存和限速功能开发 13.1.轮播图接口实现 首先把pycharm环境改成本地的,vue中local_host也改成本地 (1)goods/serializer class B ...
- django rest framework serializers
django rest framework serializers序列化 serializers是将复杂的数据结构变成json或者xml这个格式的 serializers有以下几个作用:- 将qu ...
- Django REST framework基础:视图和路由
DRF中的Request 在Django REST Framework中内置的Request类扩展了Django中的Request类,实现了很多方便的功能--如请求数据解析和认证等. 比如,区别于Dj ...
随机推荐
- db2开启监控monitor 查看快照snapshot
ths https://blog.csdn.net/huaishu/article/details/9671771 #查看监控器 db2 get monitor switches #打开监控器db ...
- 九、Brideg 桥接模式
设计原理: 代码清单: 抽象类 DisplayImpl public abstract class DisplayImpl { public abstract void rawOpen(); publ ...
- 【VBA】杨辉三角
Private Sub Workbook_Open() Dim loopA As Integer Dim loopB As Integer Dim loopNum As Integer Dim top ...
- python list中append()方法和extend()方法区别
共同点 只能作用于list类型(不能作用于tuple等其他类型) 单参数限制(不支持多参数) 不同点 list.append(object) 向列表中添加一个对象object. 使用append的时候 ...
- 从零开始学spring cloud(一) -------- spring cloud 简介
1.微服务简介 1.1.单体架构 一个归档包(例如war格式)包含了应用所有功能的应用程序,我们通常称之为单体应用.架构单体应用的方法论,我们称之为单体应用架构. 缺点:1. 复杂性高以笔者经手的一个 ...
- 【计算机网络】TCP的流量控制和拥塞控制
TCP的流量控制 1. 利用滑动窗口实现流量控制 如果发送方把数据发送得过快,接收方可能会来不及接收,这就会造成数据的丢失.所谓流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收. 利用滑动 ...
- python基础(二)列表与字典
列表list-数组stus=['苹果','香蕉','橘子','红枣',111.122,]# 下标 0 1 2 3 4#下标,索引,角标#print(stus[4]) #st=[]#空list#st=l ...
- python脚本批量复制文件
1.拷贝一个目录下的所有文件及文件夹到另一个目录下(递归拷贝) # cat /home/test.py #!/usr/bin/python import os import shutil def ...
- PHP并发之CURL
<?php $start_time = microtime(true); $url = array(); for ($i=0;$i<1000;$i++){ $url[] = "h ...
- JVM 字节码(三)异常在字节码中的处理(catch 和 throws)
JVM 字节码(三)异常在字节码中的处理(catch 和 throws) 在 ClassFile 中到底是如何处理异常的呢? 一.代码块异常 catch catch 中的异常代码块在异常是如何处理的呢 ...