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实现)
Dec 09 Python
Python处理PDF及生成多层PDF实例代码
Apr 24 Python
python爬虫入门教程--正则表达式完全指南(五)
May 25 Python
使用Python的package机制如何简化utils包设计详解
Dec 11 Python
Java编程迭代地删除文件夹及其下的所有文件实例
Feb 10 Python
python中使用iterrows()对dataframe进行遍历的实例
Jun 09 Python
Python绘制的二项分布概率图示例
Aug 22 Python
对python中的乘法dot和对应分量相乘multiply详解
Nov 14 Python
更新升级python和pip版本后不生效的问题解决
Apr 17 Python
python3美化表格数据输出结果的实现代码
Apr 14 Python
python如何利用traceback获取详细的异常信息
Jun 05 Python
Python语法学习之进程的创建与常用方法详解
Apr 08 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
在WordPress的后台中添加顶级菜单和子菜单的函数详解
2016/01/11 PHP
PHP数组操作实例分析【添加,删除,计算,反转,排序,查找等】
2016/12/24 PHP
thinkPHP5框架分页样式类完整示例
2018/09/01 PHP
jQuery实现动画效果circle实例
2015/08/06 Javascript
jQuery实现气球弹出框式的侧边导航菜单效果
2015/09/22 Javascript
JS正则匹配URL网址的方法(可匹配www,http开头的一切网址)
2017/01/06 Javascript
bootstrap中添加额外的图标实例代码
2017/02/15 Javascript
JavaScript实现父子dom同时绑定两个点击事件,一个用捕获,一个用冒泡时执行顺序的方法
2017/03/30 Javascript
Vue项目使用CDN优化首屏加载问题
2018/04/01 Javascript
jQuery实现炫丽的3d旋转星空效果
2018/07/04 jQuery
javascript对HTML字符转义与反转义
2018/12/13 Javascript
ES6的解构赋值实例详解
2019/05/06 Javascript
layui框架与SSM前后台交互的方法
2019/09/12 Javascript
[48:51]完美世界DOTA2联赛PWL S2 Magma vs InkIce 第一场 11.28
2020/12/02 DOTA
浅谈Python中列表生成式和生成器的区别
2015/08/03 Python
Python文件的读写和异常代码示例
2017/10/31 Python
python 接收处理外带的参数方法
2018/12/03 Python
python利用ffmpeg进行录制屏幕的方法
2019/01/10 Python
python实现beta分布概率密度函数的方法
2019/07/08 Python
Tensorflow获取张量Tensor的具体维数实例
2020/01/19 Python
PyQt5 QDockWidget控件应用详解
2020/08/12 Python
中国跨境电商:Tomtop
2017/03/16 全球购物
Nayomi官网:沙特阿拉伯王国睡衣和内衣品牌
2020/12/19 全球购物
德国户外商店:eXXpozed
2020/07/25 全球购物
毕业研究生的自我鉴定
2013/11/30 职场文书
《望洞庭》教学反思
2014/02/16 职场文书
幼儿园毕业园长感言
2014/02/24 职场文书
2014年道德讲堂实施方案
2014/03/05 职场文书
部队个人年终总结
2015/03/02 职场文书
公司酒会致辞
2015/07/30 职场文书
公司客户答谢酒会祝酒词
2015/08/11 职场文书
教师个人工作总结范文2015
2015/10/14 职场文书
《这片土地是神圣的》教学反思
2016/02/16 职场文书
导游词之太行山青龙峡
2020/01/14 职场文书
基于JavaScript实现年月日三级联动
2021/06/22 Javascript
php去除数组中为0的元素的实例分析
2021/11/17 PHP