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 def函数的定义、使用及参数传递实现代码
Aug 10 Python
Python中的__SLOTS__属性使用示例
Feb 18 Python
详解Python中的条件判断语句
May 14 Python
详解python进行mp3格式判断
Dec 23 Python
解决python matplotlib imshow无法显示的问题
May 24 Python
Python tkinter的grid布局及Text动态显示方法
Oct 11 Python
python数据类型之间怎么转换技巧分享
Aug 20 Python
Python aiohttp百万并发极限测试实例分析
Oct 26 Python
Django 自动生成api接口文档教程
Nov 19 Python
Python Pillow.Image 图像保存和参数选择方式
Jan 09 Python
Python super()函数使用及多重继承
May 06 Python
忆童年!用Python实现愤怒的小鸟游戏
Jun 07 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
PHP判断远程url是否有效的几种方法小结
2011/10/08 PHP
PHP实现Google plus的好友拖拽分组效果
2016/10/21 PHP
JavaScript效率调优经验
2009/06/04 Javascript
Jquery插件写法笔记整理
2012/09/06 Javascript
原生javascript图片自动或手动切换示例附演示源码
2013/09/04 Javascript
jquery(hide方法)隐藏指定元素实例
2013/11/11 Javascript
jqplot通过ajax动态画折线图的方法及思路
2013/12/08 Javascript
jQuery动态添加、删除元素的方法
2014/01/09 Javascript
js onmousewheel事件多次触发问题解决方法
2014/10/17 Javascript
js实现ifram取父窗口URL地址的方法
2015/02/09 Javascript
简介JavaScript中Boolean.toSource()方法的使用
2015/06/05 Javascript
基于Javascript实现倒计时功能
2016/02/22 Javascript
总结在前端排序中遇到的问题
2016/07/19 Javascript
Three.js获取鼠标点击的三维坐标示例代码
2017/03/24 Javascript
ubuntu编译nodejs所需的软件并安装
2017/09/12 NodeJs
微信小程序如何调用新闻接口实现列表循环
2019/07/02 Javascript
Vue data的数据响应式到底是如何实现的
2020/02/11 Javascript
Python的Django框架中的表单处理示例
2015/07/17 Python
Python在Console下显示文本进度条的方法
2016/02/14 Python
Python爬取京东的商品分类与链接
2016/08/26 Python
Python将多个excel文件合并为一个文件
2018/01/03 Python
使用python实现滑动验证码功能
2019/08/05 Python
在Python中通过threshold创建mask方式
2020/02/19 Python
django 取消csrf限制的实例
2020/03/13 Python
在spyder IPython console中,运行代码加入参数的实例
2020/04/20 Python
matplotlib 使用 plt.savefig() 输出图片去除旁边的空白区域
2021/01/05 Python
20行代码教你用python给证件照换底色的方法示例
2021/02/05 Python
Tech21美国/加拿大:英国NO.1防摔保护壳品牌
2018/01/20 全球购物
迪士尼法国在线商店:shopDisney FR
2020/12/03 全球购物
简述Linux文件系统通过i节点把文件的逻辑结构和物理结构转换的工作过程
2012/04/17 面试题
销售部主管岗位职责
2013/12/18 职场文书
《小壁虎借尾巴》教学反思
2014/02/16 职场文书
学前班评语大全
2014/05/04 职场文书
学校计划生育责任书
2015/05/09 职场文书
Nginx图片服务器配置之后图片访问404的问题解决
2022/03/21 Servers
戴尔Win11系统no bootable devices found解决教程
2022/09/23 数码科技