django rest framework 自定义返回方式


Posted in Python onJuly 12, 2020

大家在用Django Rest Framework的时候会发现默认继承后,增删改查的返回信息都是一段data,这是因为我实际是状态码和信息你在调用api的时候是看不到的,仅仅如此么?并不是这样,在我前端调用后端的时候,实际上相关的code和msg是能看得到的,但是我们在普通的调用api他只是单单的返回data信息,这个是不够我们满足需求的,毕竟我们不仅仅需要用前端需调用,下面我们来自定义Response返回信息

Django(2.0)

Django Rest Framework

Python3.6

1、自定义Response,继承rest framework的Response

#这个方法py文件我们可以写到任意地方,目的是在我们需要写一个Baseview的时候将放回方法引用

from django.utils import six
from rest_framework.response import Response
from rest_framework.serializers import Serializer

class JsonResponse(Response):
 """
 An HttpResponse that allows its data to be rendered into
 arbitrary media types.
 """

 def __init__(self, data=None, code=None, msg=None,
     status=None,
     template_name=None, headers=None,
     exception=False, content_type=None):
  """
  Alters the init arguments slightly.
  For example, drop 'template_name', and instead use 'data'.
  Setting 'renderer' and 'media_type' will typically be deferred,
  For example being set automatically by the `APIView`.
  """
  super(Response, self).__init__(None, status=status)

  if isinstance(data, Serializer):
   msg = (
    'You passed a Serializer instance as data, but '
    'probably meant to pass serialized `.data` or '
    '`.error`. representation.'
   )
   raise AssertionError(msg)

  self.data = {"code": code, "message": msg, "data": data}
  self.template_name = template_name
  self.exception = exception
  self.content_type = content_type

  if headers:
   for name, value in six.iteritems(headers):
    self[name] = value

2、重写Base类,将增删改查方法重写并且返回方法为刚刚定义好的新的Response类

#Base类,将增删改查方法重写
#!/usr/bin/env python
# -*- coding:utf-8 -*-

from assets import serializers
from assets import models
from rest_framework.response import Response
from rest_framework import status
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.pagination import PageNumberPagination
from django.shortcuts import get_object_or_404
from common.utils.custom_response import JsonResponse
from rest_framework import filters
from django_filters import rest_framework
from django_filters.rest_framework import DjangoFilterBackend

class CustomViewBase(viewsets.ModelViewSet):
 # pagination_class = LargeResultsSetPagination
 # filter_class = ServerFilter
 queryset = ''
 serializer_class = ''
 permission_classes = ()
 filter_fields = ()
 search_fields = ()
 filter_backends = (rest_framework.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter,)

 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 JsonResponse(data=serializer.data,msg="success",code=201,status=status.HTTP_201_CREATED,headers=headers)

 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 JsonResponse(data=serializer.data,code=200,msg="success",status=status.HTTP_200_OK)

 def retrieve(self, request, *args, **kwargs):
  instance = self.get_object()
  serializer = self.get_serializer(instance)
  return JsonResponse(data=serializer.data,code=200,msg="success",status=status.HTTP_200_OK)

 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 JsonResponse(data=serializer.data,msg="success",code=200,status=status.HTTP_200_OK)

 def destroy(self, request, *args, **kwargs):
  instance = self.get_object()
  self.perform_destroy(instance)
  return JsonResponse(data=[],code=204,msg="delete resource success",status=status.HTTP_204_NO_CONTENT)

3、view视图继承以及测试

class BatchLoadView(CustomViewBase):
 queryset = models.Manufacturer.objects.all()
 serializer_class = serializers.ManufacturerSerializer

 def list(self, request, *args, **kwargs):
  return JsonResponse(code=200, data=[], msg="testings")

这样我们就完成了自定义返回信息,下一节将讲解自定义异常

补充知识:django rest framework 自定义异常返回

上一节给大家介绍了自定义Response返回信息,但那个只用于正确的返回success,但是当我们用到了权限

auth 401、方法不允许method 405,等等,这时候我们就用自己自定义异常返回信息

1、定义settings配置文件

#定义异常返回的路径脚本位置

REST_FRAMEWORK = {
  'EXCEPTION_HANDLER': 'common.utils.custom_execption.custom_exception_handler',
}

2、定义脚本

#注意,脚本路径需要与settings.py 定义的一样

from rest_framework.views import exception_handler

def custom_exception_handler(exc, context):
  # Call REST framework's default exception handler first,
  # to get the standard error response.
  response = exception_handler(exc, context)

  # Now add the HTTP status code to the response.
  if response is not None:
    print(response.data)
    response.data.clear()
    response.data['code'] = response.status_code
    response.data['data'] = []

    if response.status_code == 404:
      try:
        response.data['message'] = response.data.pop('detail')
        response.data['message'] = "Not found"
      except KeyError:
        response.data['message'] = "Not found"

    if response.status_code == 400:
      response.data['message'] = 'Input error'

    elif response.status_code == 401:
      response.data['message'] = "Auth failed"

    elif response.status_code >= 500:
      response.data['message'] = "Internal service errors"

    elif response.status_code == 403:
      response.data['message'] = "Access denied"

    elif response.status_code == 405:
      response.data['message'] = 'Request method error'
  return response

#无需调用,报错的时候他自己会调用!!

以上这篇django rest framework 自定义返回方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
介绍Python中的一些高级编程技巧
Apr 02 Python
Python中Iterator迭代器的使用杂谈
Jun 20 Python
Python实现获取邮箱内容并解析的方法示例
Jun 16 Python
TensorFlow实现iris数据集线性回归
Sep 07 Python
配置 Pycharm 默认 Test runner 的图文教程
Nov 30 Python
Python 移动光标位置的方法
Jan 20 Python
ActiveMQ:使用Python访问ActiveMQ的方法
Jan 30 Python
python实现在函数中修改变量值的方法
Jul 16 Python
Pytorch 使用不同版本的cuda的方法步骤
Apr 02 Python
python 无损批量压缩图片(支持保留图片信息)的示例
Sep 22 Python
scrapy redis配置文件setting参数详解
Nov 18 Python
Python+Selenium自动化环境搭建与操作基础详解
Mar 13 Python
Django+RestFramework API接口及接口文档并返回json数据操作
Jul 12 #Python
Python3交互式shell ipython3安装及使用详解
Jul 11 #Python
Python QTimer实现多线程及QSS应用过程解析
Jul 11 #Python
面向新手解析python Beautiful Soup基本用法
Jul 11 #Python
基于python实现判断字符串是否数字算法
Jul 10 #Python
基于python实现计算两组数据P值
Jul 10 #Python
Python3爬虫中关于Ajax分析方法的总结
Jul 10 #Python
You might like
单一index.php实现PHP任意层级文件夹遍历(Zjmainstay原创)
2012/07/31 PHP
PHP中__FILE__、dirname与basename用法实例分析
2014/12/01 PHP
PHP中error_log()函数的使用方法
2015/01/20 PHP
Thinkphp3.2.3分页使用实例解析
2016/07/28 PHP
基于thinkPHP3.2实现微信接入及查询token值的方法
2017/04/18 PHP
php防止表单重复提交实例讲解
2019/02/11 PHP
LBS blog sql注射漏洞[All version]-官方已有补丁
2007/08/26 Javascript
为javascript添加String.Format方法
2020/08/11 Javascript
JavaScript中通过闭包解决只能取得包含函数中任何变量最后一个值的问题
2010/08/12 Javascript
关于jquery append() html时的小问题的解决方法
2010/12/16 Javascript
jquery实现很酷的网页顶部图标下拉菜单效果
2015/08/22 Javascript
javascript的函数劫持浅析
2016/09/26 Javascript
js中数组的常用方法小结
2016/12/30 Javascript
关于在vue-cli中使用微信自动登录和分享的实例
2017/06/22 Javascript
vue项目实现表单登录页保存账号和密码到cookie功能
2018/08/31 Javascript
vue elementui form表单验证的实现
2018/11/11 Javascript
浅谈Node 异步IO和事件循环
2019/05/05 Javascript
如何解决日期函数new Date()浏览器兼容性问题
2019/09/11 Javascript
Vuex modules模式下mapState/mapMutations的操作实例
2019/10/17 Javascript
vue实现设置载入动画和初始化页面动画效果
2019/10/28 Javascript
详解JavaScript原型与原型链
2020/11/16 Javascript
Python中的Classes和Metaclasses详解
2015/04/02 Python
python找出一个列表中相同元素的多个索引实例
2019/06/11 Python
利用jupyter网页版本进行python函数查询方式
2020/04/14 Python
python实现企业微信定时发送文本消息的实例代码
2020/11/25 Python
Skyscanner台湾:全球知名的旅行比价引擎
2018/07/01 全球购物
英国户外服装、鞋类和设备的领先零售商:Millets
2020/10/12 全球购物
介绍一下linux文件系统分配策略
2012/11/17 面试题
中专毕业生自我鉴定范文
2013/11/09 职场文书
建筑结构施工专业推荐信
2014/02/21 职场文书
2014最新离职证明范本
2014/09/12 职场文书
教师自查自纠材料
2014/10/14 职场文书
2014年服装销售工作总结
2014/11/27 职场文书
秋收起义观后感
2015/06/11 职场文书
2019年特色火锅店的创业计划书模板
2019/08/28 职场文书
Java 超详细讲解数据结构中的堆的应用
2022/04/02 Java/Android