DRF之过滤排序分页异常处理
一、过滤
对于列表数据要通过字段来进行过滤,就需要添加 django-filter 模块
使用方法:
# 1、注册,在app中注册 settings.py
INSTALLED_APPS = [
'django_filters',
]
# 2、settings.py 配置
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': (
'django_filters.rest_framework.DjangoFilterBackend',
)
}
# 3、在视图中添加filter_fields属性,指定过滤的字段
class BooksView(ModelViewSet):
queryset = Books.objects.all()
serializer_class = BooksSerializer
filter_fields = ('title',) # 配置可以按照哪个字段来过滤
# http://127.0.0.1:8000/books/?title=红楼梦
二、排序
排序可以使用 Rest Framework 提供的 OrderingFilter 来快速指明数据按指定字段进行排序
使用方法:
# 1、首先视图中设置filter_backends=[OrderingFilter]
# 2、然后再视图中添加 ordering_fields 属性,指定排序字段
from rest_framework.filters import OrderingFilter
class BooksView(ModelViewSet):
queryset = Books.objects.all()
serializer_class = BooksSerializer
filter_backends = [OrderingFilter] # 第一步
ordering_fields = ['price','id'] # 第二步
# http://127.0.0.1:8000/books/?ordering=id 通过ordering查看有无指明排序的字段,并通过字段来排序
# -id 表示针对id字段进行倒序排序
# id 表示针对id字段进行升序排序
三、分页
首先 Rest Framework 提供了三种分页方式,并且
- PageNumberPagination
- LimitOffsetPagination
- CursorPagination
使用方式一:可以直接继承使用,但是配置参数需要在settings.py里面配置
使用方式二:通过子类继承父类分页器使用,直接在子类中修改父类的参数(推荐)
PageNumberPagination
子类中的属性:
- page_size:每页数目
- page_query_param:前端发送的页数关键字,默认“page”
- page_size_query_param:前端发送每页数目关键字名,默认None
- max_page_size:前端最多能设置的每页数量
如何使用:
from rest_framework.generics import ListAPIView
from rest_framework.pagination import PageNumberPagination
from app01.models import Books
from app01.ser import BooksSerializer
# 第一步:
class BookPageNumberPagination(PageNumberPagination):
page_size = 3 # 每页条数
page_query_param = 'page' # 查询第几页的key
page_size_query_param = 'size' # 每一页显示的条数
max_page_size = 5 # 每页最大条数
class BookView(ListAPIView):
queryset = Books.objects.all()
serializer_class = BooksSerializer
# 第二步:分页配置
pagination_class = BookPageNumberPagination
# url:http://127.0.0.1:8000/books/?page=1&size=5 查询第1页,一共显示五条数据
LimitOffsetPagination
子类中的属性:
- default_limit:默认限制,默认值与
PAGE_SIZE设置一致 - limit_query_param:limit参数名,默认’limit’
- offset_query_param:offset参数名,默认’offset’
- max_limit:最大limit限制,默认None
如何使用:
from rest_framework.generics import ListAPIView
from rest_framework.pagination import LimitOffsetPagination
from app01.models import Books
from app01.ser import BooksSerializer
# 第一步:
class BookLimitOffsetPagination(LimitOffsetPagination):
default_limit = 3 # 每页条数
limit_query_param = 'limit' # 往后拿几条
offset_query_param = 'offset' # 从第几条往后拿几条的标杆
max_limit = 5 # 每页最大拿几条
class BookView(ListAPIView):
queryset = Books.objects.all()
serializer_class = BooksSerializer
# 第二步:分页配置
pagination_class = BookLimitOffsetPagination
# url:http://127.0.0.1:8000/books/?limit=3&offset=4 从第三条开始往后拿4条数据
CursorPagination
子类中的属性:
- cursor_query_param:默认查询字段,不需要修改
- page_size:每页数目
- ordering:按什么排序,需要指定
如何使用:
CursorPagination的查询速度快,但是却不能定位到第几页这样查,要么往前查,要么往后查。
from rest_framework.generics import ListAPIView
from rest_framework.pagination import CursorPagination
from app01.models import Books
from app01.ser import BooksSerializer
# 第一步:
class BookCursorPagination(CursorPagination):
cursor_query_param = 'cursor' # 每页查询的key
page_size = 3 # 每页显示条数
ordering = 'id' # 排序字段
class BookView(ListAPIView):
queryset = Books.objects.all()
serializer_class = BooksSerializer
# 第二步:分页配置
pagination_class = BookCursorPagination
# url:http://127.0.0.1:8000/books/?cursor=cD0z
继承APIView使用方法
像方式一,方式二这样使用的话,就要视图类是继承 ListAPIView 然后直接配置就可以了
但是如果视图类继承的是 GenericAPIView 或者 APIView 的话,就需要用另一种方式了:
使用方法:
# 1、定义一个分页器
class BookPageNumberPagination(PageNumberPagination):
page_size = 3 # 每页条数
page_query_param = 'page' # 查询第几页的key
page_size_query_param = 'size' # 每一页显示的条数
max_page_size = 5 # 每页最大条数
class BookView(APIView):
def get(self, request, *args, **kwargs):
book_list = Books.objects.all()
# 2、实例化得到一个分页器对象
page_obj = BookPageNumberPagination()
# 3、调用paginate_queryset返回每一页的数据
book_list = page_obj.paginate_queryset(book_list, request, view=self)
# 4、获取上一页下一页链接
next_url = page_obj.get_next_link()
previous_url = page_obj.get_previous_link()
# 5、序列化
book_ser = BooksSerializer(book_list, many=True)
# 6、加入响应信息中
data = {'next_url': next_url, 'previous_url': previous_url, 'data': book_ser.data}
return Response(data=data)
四、异常处理
异常处理主要是用来统一接口返回
源码分析
异常处理在APIView的api_settings已经配置好了
'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler',
def exception_handler(exc, context):
# 先判断是不是404
if isinstance(exc, Http404): # exc是异常信息的异常对象
exc = exceptions.NotFound()
# 然后判断是不是权限的问题
elif isinstance(exc, PermissionDenied):
exc = exceptions.PermissionDenied() # 比如权限问题会返回一个字典
# 在判断你抛出的是不是API的异常——>认证权限这些都是继承了API的异常
if isinstance(exc, exceptions.APIException):
headers = {}
if getattr(exc, 'auth_header', None):
headers['WWW-Authenticate'] = exc.auth_header
if getattr(exc, 'wait', None):
headers['Retry-After'] = '%d' % exc.wait
if isinstance(exc.detail, (list, dict)):
data = exc.detail
else:
data = {'detail': exc.detail}
set_rollback()
return Response(data, status=exc.status_code, headers=headers)
# 只要是上面这些异常都做了处理
return None # 意味有些异常它没有处理,就会交给Django自己处理
如何处理
因为dir有些异常它不做处理,Django处理的又不符合我们的标准,所以就要写一个统一的异常类来替换掉它,把所有情况都处理,只要前端出异常看到的都是固定的东西。
如何写:
重写一个类,和它基本上差不多,配置的时候在 settings.py 里面全局配置
# app01_auth.py
from rest_framework.views import exception_handler
from rest_framework.response import Response
def app01_exception_handler(exc, context):
response = exception_handler(exc, context) # 原来的drf处理的我们也需要
# 两种情况,一个是None,drf没有处理,Django处理了,但是处理的不符合需求
# response对象,drf处理了我们需要的
if not response:
# 如果没处理,那么我们自己处理
return Response(data={'status': 400, 'error': str(exc)}, status=400)
else:
# drf 处理了,那么取出它处理的信息,重新处理一下
return Response(data={'status': 400, 'error': response.data.get('detail')}, status=400)
然后再全局配置一下:settings.py
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'app01.app_auth.app01_exception_handler',
}
五、封装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":'xiaoyang'},token='dsafsdfa',aa='dsafdsfdee')
return APIResponse(data={"name":'xiaoyang'})
return APIResponse(code='101',msg='错误',data={"name":'xiaoyang'},token='dsafsdfa',aa='dsafdsfdee',header={})
DRF之过滤排序分页异常处理的更多相关文章
- DRF 过滤排序分页异常处理
DRF 中如何使用过滤,排序,分页,以及报错了如何处理?10分钟get了~
- 三 drf 认证,权限,限流,过滤,排序,分页,异常处理,接口文档,集xadmin的使用
因为接下来的功能中需要使用到登陆功能,所以我们使用django内置admin站点并创建一个管理员. python manage.py createsuperuser 创建管理员以后,访问admin站点 ...
- day74:drf:drf其他功能:认证/权限/限流/过滤/排序/分页/异常处理&自动生成接口文档
目录 1.django-admin 2.认证:Authentication 3.权限:Permissions 4.限流:Throttling 5.过滤:Filtering 6.排序:OrderingF ...
- drf07 过滤 排序 分页 异常处理 自动生成接口文档
4. 过滤Filtering 对于列表数据可能需要根据字段进行过滤,我们可以通过添加django-fitlter扩展来增强支持. pip install django-filter 在配置文件sett ...
- drf框架 - 过滤组件 | 分页组件 | 过滤器插件
drf框架 接口过滤条件 群查接口各种筛选组件数据准备 models.py class Car(models.Model): name = models.CharField(max_length=16 ...
- drf_jwt手动签发与校验-drf小组件:过滤-筛选-排序-分页
签发token 源码的入口:完成token签发的view类里面封装的方法. 源码中在请求token的时候只有post请求方法,主要分析一下源码中的post方法的实现. settings源码: 总结: ...
- Contoso 大学 - 3 - 排序、过滤及分页
原文 Contoso 大学 - 3 - 排序.过滤及分页 目录 Contoso 大学 - 使用 EF Code First 创建 MVC 应用 原文地址:http://www.asp.net/mvc/ ...
- Ecside基于数据库的过滤、分页、排序
首先ecside展现列表.排序.过滤(该三种操作以下简称为 RSF )的实现原理完全和原版EC一样, 如果您对原版EC的retrieveRowsCallback.sortRowsCallback.fi ...
- Mysql 单表查询-排序-分页-group by初识
Mysql 单表查询-排序-分页-group by初识 对于select 来说, 分组聚合(((group by; aggregation), 排序 (order by** ), 分页查询 (limi ...
随机推荐
- 记一次MySQL(5.7版本)数据库的主从同步和备份
我遇到的问题 我先后在BAT三大云服务器商购买了学生机,配置如下 百度云2核/4G 阿里云1核/2G 腾讯云1核/2G 我的解决方案 由于我不知道百度云的续费规则,导致买了2核/4G的服务器之后以为像 ...
- IDEA 2019.2.4 破解安装教程
将下载的 IDEA 压缩包解压,找到 idealIU-2019.2.4.exe 安装文件,然后双击进行安装 安装完后不要运行,打开解压包中破解补丁与激活码文件夹,找到 jetbrains-agent. ...
- 6.5 scp:远程文件复制
scp命令 用于在不同的主机之间复制文件,它采用SSH协议来保证复制的安全性.scp命令每次都是全量完整复制,因此效率不高,适合第一次复制时使用,增量复制建议使用rsync命令替代. scp ...
- kind:Kubernetes in Docker,单机测试 Kubernetes 群集的最佳方案
请访问原文发布链接:https://sysin.org/article/kind/,查看最新版. 作者:gc(at)sysin.org,主页:www.sysin.org 2021.04.28 更新,k ...
- 重新整理 .net core 实践篇—————服务的配置更新[十三]
前言 前文讲述了,服务和配置直接的配合,这一节写一下,当配置文件修改了,每个服务如何感知自己的配置. 正文 服务感知到自己的配置发生变化,这就牵扯出两个东西: IoptionsMonitor<o ...
- 获取两个时间点间的随机时间&时间戳
获取两个时间点间的随机时间&时间戳 方案一 # python2 不兼容,python3正常 import datetime,random def randomtimes(start, end, ...
- setTimeout使用问题
通常禁止使用setTimeout的情况: 1.不能用于模拟异步,有的人不熟悉异步流程,而使用setTimeout伪实现,比如设置一个 setTimeout 来等待函数执行完毕,正确做法是使用回调来处理 ...
- FPGA最全科普总结
FPGA最全科普总结 FPGA 是可以先购买再设计的"万能"芯片.FPGA (Field Programmable Gate Array)现场可编程门阵列,是在硅片上预先设计实 ...
- VGG16迁移学习实现
VGG16迁移学习实现 本文讨论迁移学习,它是一个非常强大的深度学习技术,在不同领域有很多应用.动机很简单,可以打个比方来解释.假设想学习一种新的语言,比如西班牙语,那么从已经掌握的另一种语言(比如英 ...
- GitHub上开源的YOLOv5
GitHub上开源的YOLOv5 代码地址:https://github.com/ultralytics/YOLOv5 该存储库代表Ultralytics对未来的对象检测方法的开源研究,并结合了我们在 ...