首页 > 编程语言 > 详细

drf-过滤排序异常处理封装Response对象

时间:2020-07-15 19:50:58      阅读:49      评论:0      收藏:0      [点我收藏+]

一 过滤Filtering

对于列表数据可能需要根据字段进行过滤,我们可以通过添加django-fitlter扩展来增强支持。

安装

pip install django-filter
注册

INSTALLED_APPS = [
    ...
    django_filters,  # 需要注册应用,
]

全局配置

REST_FRAMEWORK = {
    ...
    DEFAULT_FILTER_BACKENDS: (django_filters.rest_framework.DjangoFilterBackend,)
}
# 在视图中添加filter_fields属性,指定可以过滤的字段
class StudentListView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
    filter_fields = (age, sex)
# 127.0.0.1:8000/four/students/?sex=1

局部配置

from django_filters.rest_framework import DjangoFilterBackend
class StudentListView(ListAPIView):
    ...
    filter_backends = [DjangoFilterBackend,]
    filter_fields = (age, sex)

二 排序

对于列表数据,REST framework提供了OrderingFilter过滤器来帮助我们快速指明数据按照指定字段进行排序。

使用方法:

在类视图中设置filter_backends,使用rest_framework.filters.OrderingFilter过滤器,REST framework会在请求的查询字符串参数中检查是否包含了ordering参数,如果包含了ordering参数,则按照ordering参数指明的排序字段对数据集进行排序。

前端可以传递的ordering参数的可选字段值需要在ordering_fields中指明。

示例:

from rest_framework.generics import ListAPIView
from rest_framework.filters import OrderingFilter
from app01.models import Book
from app01.ser import BookSerializer
class Book2View(ListAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    filter_backends = [OrderingFilter]
    ordering_fields = (id, price)

#使用 
http://127.0.0.1:8000/books2/?ordering=-price
http://127.0.0.1:8000/books2/?ordering=price
http://127.0.0.1:8000/books2/?ordering=-id
-id 表示针对id字段进行倒序排序
id  表示针对id字段进行升序排序

如果需要在过滤以后再次进行排序,则需要两者结合!

from django_filters.rest_framework import DjangoFilterBackend
class Book2View(ListAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    filter_fields = (id, price)  # 过滤
    # 因为局部配置会覆盖全局配置,所以需要重新把过滤组件核心类再次声明,
    # 否则过滤功能会失效
    filter_backends = [OrderingFilter,DjangoFilterBackend] # 过滤要写在排序之后
    ordering_fields = (id, prcie) #排序

三 异常处理 Exceptions

REST framework提供了异常处理,我们可以自定义异常处理函数。

3.1 使用方式

from rest_framework.views import exception_handler

def my_exception_handler(exc, context):
    # 先调用REST framework默认的异常处理方法获得标准错误响应对象
    response = exception_handler(exc, context)

    # 在此处补充自定义的异常处理
    if not response:
        if isinstance(exc, ZeroDivisionError):
            return Response(data={status: 777, msg: "除以0的错误" + str(exc)}, status=status.HTTP_400_BAD_REQUEST)
        return Response(data={status:999,msg:str(exc)},status=status.HTTP_400_BAD_REQUEST)
    else:
        return Response(data={status:888,msg:response.data.get(detail)},status=status.HTTP_400_BAD_REQUEST)

在配置文件中声明自定义的异常处理

REST_FRAMEWORK = {
   EXCEPTION_HANDLER: app01.app_auth.my_exception_handler,
}

3.2 案例

补充上处理关于数据库的异常

from rest_framework.views import exception_handler
from rest_framework.response import Response
from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework import status
from django.db import DatabaseError

def exception_handler(exc, context):
    response = drf_exception_handler(exc, context)

    if response is None:
        view = context[view]
        print([%s]: %s % (view, exc))
        if isinstance(exc, DatabaseError):
            response = Response({detail: 服务器内部错误}, status=status.HTTP_507_INSUFFICIENT_STORAGE)
        else:
            response = Response({detail: 未知错误}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    return response
  
# 在setting.py中配置
REST_FRAMEWORK = {
    EXCEPTION_HANDLER: app01.ser.exception_handler
}

3.3 REST framework定义的异常

  • APIException 所有异常的父类
  • ParseError 解析错误
  • AuthenticationFailed 认证失败
  • NotAuthenticated 尚未认证
  • PermissionDenied 权限决绝
  • NotFound 未找到
  • MethodNotAllowed 请求方式不支持
  • NotAcceptable 要获取的数据格式不支持
  • Throttled 超过限流次数
  • ValidationError 校验失败

也就是说,很多的没有在上面列出来的异常,就需要我们在自定义异常中自己处理了。

四 封装Response对象(重要)

为了让放回的数据有一定的格式我们要使用自己封装的Response对象

from rest_framework.response import Response
class APIResponse(Response):
    def __init__(self,code=100,msg=成功,data=None,status=None,headers=None,**kwargs):
        dic = {code: code, msg: msg}
        if  data:
            dic = {code: code, msg: msg,data:data}
        dic.update(kwargs)
        super().__init__(data=dic, status=status,headers=headers)
# 使用
return APIResponse(data={"name":lqz},token=dsafsdfa,aa=dsafdsafasfdee)
return APIResponse(data={"name":lqz})
return APIResponse(code=101,msg=错误,data={"name":lqz},token=dsafsdfa,aa=dsafdsafasfdee,header={})

drf-过滤排序异常处理封装Response对象

原文:https://www.cnblogs.com/bk134/p/13306381.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!