drf过滤和排序及异常处理的包装
过滤和排序(4星)
查询所有才需要过滤(根据过滤条件),排序(按某个规律排序) 使用前提: 必须继承的顶层类是GenericAPIView
内置过滤类
内置过滤类使用,在视图类中配置,是模糊查询 使用前提: 必须继承的顶层类是GenericAPIView
使用方法
设置
from rest_framework.filters import SearchFilter
class BookAPIView(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
# 在视图类中配置 最顶层的类至少是GenericAPIView
filter_backends = [SearchFilter, ] # 设置这个
# 过滤条件,按名字过滤
search_fields = ['title', 'price'] # 取决于models里的字段
查询
http://127.0.0.1:8000/books/?search=22 # 书名中或者价格中有22就能查询出来

第三方插件过滤(可以有and关系)
下载模块pip3 install django-filter 并且这个是精准查询 使用前提: 必须继承的顶层类是GenericAPIView
使用方法
注册
INSTALLED_APPS = [
...
'django_filters',
]
设置
from django_filters.rest_framework import DjangoFilterBackend
class BookAPIView(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
filter_backends = [DjangoFilterBackend, ] # 写上面导入的类
# 过滤条件,按名字过滤
filter_fields =['name', 'price']
查询
http://127.0.0.1:8000/books/?name=红 # 返回空列表
http://127.0.0.1:8000/books/?name=红楼梦
http://127.0.0.1:8000/books/?name=红楼梦&price=33 # &符号是and关系
http://127.0.0.1:8000/books/?name=红楼梦&price=32 # 返回空列表


自定义过滤类
使用方法
写一个类,继承BaseFilterBackend 基类,重写filter_queryset方法,返回的qs对象,是过滤后的对象 使用前提: 必须继承的顶层类是GenericAPIView
# 在自己创建的untils.py中
from rest_framework.filters import BaseFilterBackend
class BookFilter(BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
query = request.query_params.get('title')
if query:
queryset = queryset.filter(title__contains=query) # 根据过滤条件筛选数据
return queryset
# 在views.py中
from .untils import BookFilter
class BookAPIView(GenericViewSet, ListModelMixin):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
filter_backends = [BookFilter, ] # 设置自定义过滤类 自己定义的过滤类就不需要写类属性了
查询
http://127.0.0.1:8000/books/?title=红 # 模糊匹配 ,自己定义的

源码分析
#### 源码分析----》GenericAPIView----》查询所有,调用了list---》self.filter_queryset(self.get_queryset())----》查看GenericAPIView的filter_queryset方法:
def filter_queryset(self, queryset):
for backend in list(self.filter_backends): # 去视图类里取自定义过滤类名
# 自定义过滤类名实例化得到对象调用filter_queryset方法 而这个就是我们自己写的方法,返回值就是过滤后的数据
queryset = backend().filter_queryset(self.request, queryset, self)
return queryset
内置排序类(既有排序,又有过滤)
使用前提: 必须继承的顶层类是GenericAPIView
使用方法
设置
from rest_framework.filters import OrderingFilter,SearchFilter
class BookAPIView(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
filter_backends = [SearchFilter, OrderingFilter]
# 过滤条件,按名字过滤
search_fields = ['title', 'price']
# 按哪个字段排序
ordering_fields = ['price', 'id']
查询
http://127.0.0.1:8000/books/?ordering=price,-id
# 上面这句话的意思是按价格升序,如果遇到相同的,就按id降序

过滤加排序
过滤和排序可以同时用--->因为他们本质是for循环一个个执行,所有优先使用过滤,再使用排序
filter_backends = [SearchFilter,OrderingFilter]
ordering_fields=['price','id']
search_fields=['name','author']
查询
http://127.0.0.1:8000/books/?search=22&ordering=-id

异常处理(4星)
全局统一捕获异常,返回固定的格式 {code:999,msg:'未知错误'}(类似这种格式)
使用方法
在一个新的py文件内:
from rest_framework.views import exception_handler # 默认没有配置,出了异常会走它
from rest_framework.response import Response
def common_exception_handler(exc, context):
# 取出出错的IP,可以不用
print(context['request'].META.get('REMOTE_ADDR'))
######################################重点##########################################
# exception_handler方法会返回Response对象或者None
res = exception_handler(exc, context)
if res: # 这表示已经处理了异常,它只处理APIExcepiton的异常
res = Response(data={'code': 998, 'msg': res.data.get('detail', '服务器异常')})
else: # 返回None,表示是出了不知道的异常
res = Response(data={'code': 999, 'msg': str(exc)})
# 注意:在这里,可以记录日志---》只要走到这,说明程序报错了,记录日志,以后查日志---》尽量详细
# 出错时间,错误原因,哪个视图类出了错,什么请求地址,什么请求方式出了错
request = context.get('request') # 这个request是当次请求的request对象
view = context.get('view') # 这个viewt是当次执行的视图类对象
# 下面的打印只是举例让你看日志的大概数据
print('错误原因:%s,错误视图类:%s,请求地址:%s,请求方式:%s' % (str(exc), str(view), request.path, request.method))
return res
配置文件配置:
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'app01.untils.common_exception_handler'
}
源码分析






drf过滤和排序及异常处理的包装的更多相关文章
- drf权限,频率,过滤,排序,异常处理
目录 一.权限 1 权限源码分析 2 自定义权限类 3 内置权限类 二.频率 1 内置频率设置 三.过滤 四.排序 五.异常处理 一.权限 1 权限源码分析 # APIView---->disp ...
- DRF 过滤排序分页异常处理
DRF 中如何使用过滤,排序,分页,以及报错了如何处理?10分钟get了~
- django-rest-framework 基础四 过滤、排序、分页、异常处理
django-rest-framework 基础四 过滤.排序.分页.异常处理 目录 django-rest-framework 基础四 过滤.排序.分页.异常处理 1. 过滤 1.1 内置过滤类 1 ...
- drf_jwt手动签发与校验-drf小组件:过滤-筛选-排序-分页
签发token 源码的入口:完成token签发的view类里面封装的方法. 源码中在请求token的时候只有post请求方法,主要分析一下源码中的post方法的实现. settings源码: 总结: ...
- Django(67)drf搜索过滤和排序过滤
前言 当我们需要对后台的数据进行过滤的时候,drf有两种,搜索过滤和排序过滤. 搜索过滤:比如我们想返回sex=1的,那么我们就可以从所有数据中进行筛选 排序过滤:比如我们想对价格进行升序排列,就可以 ...
- drf--搜索、过滤、排序组件
目录 drf--搜索.过滤.排序组件 过滤 DjangoFilterBackend 自定义过滤器django-filter模块 自定义过滤类 搜索SearchFilter 排序OrderingFilt ...
- ModelViewSet里的过滤、排序、分页、序列化设置
1.DRF初始化 1.认证 2.权限 3.限流 4.序列化 5.分页 6.版本 7.过滤 8.排序 1.1安装DjangoRestFramework pip install djangoresfra ...
- 在ASP.NET MVC5中实现具有服务器端过滤、排序和分页的GridView
背景 在前一篇文章<[初学者指南]在ASP.NET MVC 5中创建GridView>中,我们学习了如何在 ASP.NET MVC 中实现 GridView,类似于 ASP.NET web ...
- 《Entity Framework 6 Recipes》中文翻译系列 (27) ------ 第五章 加载实体和导航属性之关联实体过滤、排序、执行聚合操作
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-9 关联实体过滤和排序 问题 你有一实体的实例,你想加载应用了过滤和排序的相关 ...
随机推荐
- 在微信小程序中使用 echarts 图片-例 折线图
首先进入echarts官方[https://echarts.apache.org/handbook/zh/get-started/].这边只需要在小程序中简单应用一下echarts折线图 所以不需要把 ...
- 使用pyautogui自动在某网站投票的脚本
网页自动投票: # !/usr/bin/env python # -*- coding:utf-8 -*- # Author:Hiuhung Wan import re import pypercli ...
- ansible 三配置和命令集
一.Ansible配置 Ansible安装好之后的配置文件有如下两种: 1.yum安装,配置文件默认路径为: /etc/ansible/ansible.cfg 2.源码包安装,配置文件路径需要从软件包 ...
- 07模块化设计之top_down
一设计功能:(一)用两个分频模块,实现16分频,且让输入a 和b在16个系统时钟内,相与一次. (二)模块化设计思想(结构化思维) 拆分,即把一个系统划分成多个功能模块,控制模块,组合模块.然后从功能 ...
- SpringDataJdbc命名查询
当使用SpringDataJdbc命名查询时,需要配置几处:官方文档:https://docs.spring.io/spring-data/jdbc/docs/2.0.4.RELEASE/refere ...
- 一个 Redis 实例最多能存放多少的 keys?List、Set、 Sorted Set 他们最多能存放多少元素?
理论上 Redis 可以处理多达 232 的 keys,并且在实际中进行了测试,每个实 例至少存放了 2 亿 5 千万的 keys.我们正在测试一些较大的值.任何 list.set. 和 sorted ...
- 哪个类包含 clone 方法?是 Cloneable 还是 Object?
java.lang.Cloneable 是一个标示性接口,不包含任何方法,clone 方法在 object 类中定义.并且需要知道 clone() 方法是一个本地方法,这意味着它是由 c 或 c++ ...
- Python - Python函数简介
- State Lattice Planner(状态栅格规划)
参考文献: Efficient constrained path planning via search in state lattices Differentially Constrained Mo ...
- ubuntu root密码问题
安装完Ubuntu后忽然意识到没有设置root密码,不知道密码自然就无法进入根用户下.到网上搜了一下,原来是这麽回事.Ubuntu的默认root密码是随机的,即每次开机都有一个新的root密码.我们可 ...