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 __setattr__、 __getattr__、 __delattr__、__call__用法示例
Mar 06 Python
Python装饰器基础详解
Mar 09 Python
Python实现对象转换为xml的方法示例
Jun 08 Python
Python爬虫实现抓取京东店铺信息及下载图片功能示例
Aug 07 Python
numpy linalg模块的具体使用方法
May 26 Python
把vgg-face.mat权重迁移到pytorch模型示例
Dec 27 Python
python实现多进程按序号批量修改文件名的方法示例
Dec 30 Python
python实现与redis交互操作详解
Apr 21 Python
Python logging模块handlers用法详解
Aug 14 Python
python 密码学示例——凯撒密码的实现
Sep 21 Python
使用pycharm运行flask应用程序的详细教程
Jun 07 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
在Zeus Web Server中安装PHP语言支持
2006/10/09 PHP
php数组应用之比较两个时间的相减排序
2008/08/18 PHP
全面解读PHP的人气开发框架Laravel
2015/10/15 PHP
关于document.cookie的使用javascript
2008/04/11 Javascript
网页自动跳转代码收集
2009/09/27 Javascript
javascript获取当前日期时间及其它操作函数
2011/01/11 Javascript
jquery配合css简单实现返回顶部效果
2013/09/30 Javascript
Javascript玩转继承(二)
2014/05/08 Javascript
Javascript基础教程之JavaScript语法
2015/01/18 Javascript
AngularJS基础 ng-init 指令简单示例
2016/08/02 Javascript
Google 爬虫如何抓取 JavaScript 的内容
2017/04/07 Javascript
javascript简单链式调用案例分析
2017/05/10 Javascript
微信小程序实现通过js操作wxml的wxss属性示例
2018/12/06 Javascript
vue.js的双向数据绑定Object.defineProperty方法的神奇之处
2019/01/18 Javascript
vue实现点击按钮下载文件功能
2019/10/11 Javascript
微信小程序实现倒计时功能
2020/11/19 Javascript
[04:45]上海特级锦标赛主赛事第三日TOP10
2016/03/05 DOTA
Python 创建子进程模块subprocess详解
2015/04/08 Python
解决python写入带有中文的字符到文件错误的问题
2019/01/31 Python
python导入pandas具体步骤方法
2019/06/23 Python
Pytorch卷积层手动初始化权值的实例
2019/08/17 Python
Python 获取指定文件夹下的目录和文件的实现
2019/08/30 Python
Python多线程thread及模块使用实例
2020/04/28 Python
Python drop方法删除列之inplace参数实例
2020/06/27 Python
Html5新标签datalist实现输入框与后台数据库数据的动态匹配
2017/05/18 HTML / CSS
皇马官方商城:Real Madrid Store
2016/09/02 全球购物
拉斯维加斯酒店、演出、旅游、俱乐部及更多:Vegas.com
2019/02/28 全球购物
IGK Hair官网:喷雾、洗发水、护发素等
2020/11/03 全球购物
说说在weblogic中开发消息Bean时的persistent与non-persisten的差别
2013/04/07 面试题
孝敬父母的演讲稿
2014/05/14 职场文书
大学军训自我鉴定大全
2014/09/18 职场文书
无财产离婚协议书范本
2014/10/28 职场文书
领导个人查摆剖析材料
2014/10/29 职场文书
见习报告格式要求
2014/11/04 职场文书
MySQL 重命名表的操作方法及注意事项
2021/05/21 MySQL
Go语言基础切片的创建及初始化示例详解
2021/11/17 Golang