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自动化测试之setUp与tearDown实例
Sep 28 Python
零基础写python爬虫之使用Scrapy框架编写爬虫
Nov 07 Python
Linux 下 Python 实现按任意键退出的实现方法
Sep 25 Python
python利用OpenCV2实现人脸检测
Apr 16 Python
浅谈Scrapy框架普通反爬虫机制的应对策略
Dec 28 Python
python简单鼠标自动点击某区域的实例
Jun 25 Python
用python写一个定时提醒程序的实现代码
Jul 22 Python
基于python实现学生信息管理系统
Nov 22 Python
python实现差分隐私Laplace机制详解
Nov 25 Python
Python 为什么推荐蛇形命名法原因浅析
Jun 18 Python
Python3+Django get/post请求实现教程详解
Feb 16 Python
基于Python实现nc批量转tif格式
Aug 14 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
GD输出汉字的函数的分析
2006/10/09 PHP
php遍历所有文件及文件夹的方法深入解析
2013/06/08 PHP
PHP实现自动登入google play下载app report的方法
2014/09/23 PHP
PHP输出九九乘法表代码实例
2015/03/27 PHP
javascript for循环设法提高性能
2010/02/24 Javascript
兼容IE和Firefox的javascript获取iframe文档内容的函数
2011/08/15 Javascript
JQuery筛选器全系列介绍
2013/08/27 Javascript
快速查找数组中的某个元素并返回下标示例
2013/09/03 Javascript
js中的caller和callee属性介绍和例子
2014/06/07 Javascript
Jquery仿IGoogle实现可拖动窗口示例代码
2014/08/22 Javascript
网站基于flash实现的Banner图切换效果代码
2014/10/14 Javascript
jQuery实现可展开折叠的导航效果示例
2016/09/12 Javascript
vue异步axios获取的数据渲染到页面的方法
2018/08/09 Javascript
解决layui的使用以及针对select、radio等表单组件不显示的问题
2019/09/05 Javascript
autojs 蚂蚁森林能量自动拾取即给指定好友浇水的实现方法
2020/05/03 Javascript
JS+CSS实现动态时钟
2021/02/19 Javascript
[41:52]DOTA2-DPC中国联赛 正赛 CDEC vs Dynasty BO3 第二场 2月22日
2021/03/11 DOTA
用Python输出一个杨辉三角的例子
2014/06/13 Python
Windows下搭建python开发环境详细步骤
2020/07/20 Python
Python实现图片转字符画的示例代码
2017/08/21 Python
Python实现自动上京东抢手机
2018/02/06 Python
python图书管理系统
2020/04/05 Python
python 操作hive pyhs2方式
2019/12/21 Python
python爬虫开发之urllib模块详细使用方法与实例全解
2020/03/09 Python
Django多个app urls配置代码实例
2020/11/26 Python
python 用Matplotlib作图中有多个Y轴
2020/11/28 Python
加拿大在线隐形眼镜专家:PerfectLens.ca
2016/11/19 全球购物
奥地利时尚、美容、玩具和家居之家:Kastner & Öhler
2020/04/26 全球购物
存储过程的优点有哪些
2012/09/27 面试题
科室工作个人总结的自我评价
2013/10/29 职场文书
行政主管岗位职责
2013/11/18 职场文书
专科文秘应届生求职信
2013/11/18 职场文书
趣味运动会加油词
2015/07/18 职场文书
关于军训的感想
2015/08/07 职场文书
解决SpringBoot跨域的三种方式
2021/06/26 Java/Android
React更新渲染原理深入分析
2022/12/24 Javascript