过滤
一、过滤器下载
pip3 install django-filter
二、过滤器配置
# 注册
INSTALLED_APPS = [
'django_filters', # 注册
]
# 全局配置-settings.py
REST_FRAMEWORK = {
...
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],
}
# 局部配置,在视图函数中
DEFAULT_FILTER_BACKENDS = ['django_filters.rest_framework.DjangoFilterBackend']
# 局部禁用,在视图函数中
DEFAULT_FILTER_BACKENDS = []
三、过滤器使用
from rest_framework.generics import ListAPIView
class xxx(ListAPIView):
queryset = 模型表对象
# queryset = models.表名.objects
serializer_class = 模型表对象
# serializer_class = ZzwSerializer
filter_fields = ('字段名',...)
# 写入模型表中,使用什么字段进行过滤
排序
一、排序
from rest_framework.filters import OrderingFilter
二、排序配置
# 全局配置-settings.py
REST_FRAMEWORK = {
...
'DEFAULT_FILTER_BACKENDS': [
# 过滤组件
'django_filters.rest_framework.DjangoFilterBackend',
# 排序组件
'rest_framework.filters.OrderingFilter',
],
}
# 局部配置,在视图函数中
DEFAULT_FILTER_BACKENDS = [
# 过滤组件
'django_filters.rest_framework.DjangoFilterBackend',
# 排序组件
'rest_framework.filters.OrderingFilter',
]
# 局部禁用,在视图函数中
DEFAULT_FILTER_BACKENDS = []
三、排序使用
from rest_framework.generics import ListAPIView
class xxx(ListAPIView):
queryset = 模型表对象
# queryset = models.表名.objects
serializer_class = 模型表对象
# serializer_class = ZzwSerializer
filter_fields = ('字段名',...)
# 写入模型表中,使用什么字段进行过滤
ordering_fields = ('字段名', ...)
# 写入模型表中,使用什么字段进行排序
异常处理
一、(APIView)dispatch
'''
在观察了父类View的as_view方法后,我们发现其内部最终是调用dispatch方法(关键)
对于当前类,最近的dispatch方法,即是APIView中的dispatch方法,我们进行下一步研究:
1. 加工原生request
2. 增添三大认证模块
3. 利用反射调用请求方法的对应方法
4. 使用异常模块收集异常
5. 利用渲染模块,渲染最终数据
'''
def dispatch(self, request, *args, **kwargs):
# 对当前接收参数使用对象属性存储
self.args = args
self.kwargs = kwargs
# 将原生request,传入至initialize_request方法,进行加工后,返回加工后的request
request = self.initialize_request(request, *args, **kwargs)
# 此刻对象属性request存储的为加工后的reqeust
self.request = request
self.headers = self.default_response_headers # deprecate?
try:
# 该方法内部包含三大认证模块
self.initial(request, *args, **kwargs)
'''
反射:
1. 获取当前对象中的对应方法(get、post、put、patch、delete....)
2. 调用方法,并传入参数
判断当前请求方式,是否存在于http_method_names属性中的方式
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
如果存在,则调用对象中的对应方法,否则使用默认方法http_method_not_allowed
'''
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
# 响应模块:执行对应方法,并传入 加工后的request参数
response = handler(request, *args, **kwargs)
except Exception as exc:
# 异常模块:如果出现异常,则调用异常方法,返回对应的异常信息,而不是前端直接报错
response = self.handle_exception(exc)
# 渲染模块:将数据进行加工后,返还给前端精美的页面
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
二、全局异常源码
from rest_framework.views import exception_handler
def exception_handler(exc, context):
# 判断异常对象是否为 Http404 异常
if isinstance(exc, Http404):
# exc = 404 异常
exc = exceptions.NotFound()
# 判断异常对象是否为 PermissionDenied 异常
elif isinstance(exc, PermissionDenied):
# exc = 403 异常
exc = exceptions.PermissionDenied()
# 判断异常对象是否为 APIException 异常
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)
# 对于其他异常,不进行处理,直接交给django处理
return None
# 抛出 404 异常
class NotFound(APIException):
status_code = status.HTTP_404_NOT_FOUND
default_detail = _('Not found.')
default_code = 'not_found'
# 抛出 403 异常
class PermissionDenied(APIException):
status_code = status.HTTP_403_FORBIDDEN
default_detail = _('You do not have permission to perform this action.')
default_code = 'permission_denied'
# 抛出 500 异常
class APIException(Exception):
status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
default_detail = _('A server error occurred.')
default_code = 'error'
...
三、自定义异常处理
from rest_framework.views import exception_handler
from rest_framework.response import Response
from rest_framework import status
# 在app下创建任意名称的py文件,书写以下模板
def Zzw_exception_handler(exc, context):
# 原来rest_framework的异常类,我们依然使用,只是在其基础上扩展
response = exception_handler(exc, context)
'''
response有两种情况:
返回Response,处理了异常,但并不完整
返沪None,没有处理异常
'''
if not response:
errors = {
'status': 1000,
'msg': str(exc),
}
else:
errors = {
'status': 2000,
'msg': request.data.get('detail'),
}
return Response(data=errors, status=status.HTTP_400_BAD_REQUEST)
四、配置异常处理
# 全局配置-settings.py
REST_FRAMEWORK = {
...,
# rest_framework默认配置的异常处理类
'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler',
# 我们需要写入自己定义的,所以修改上面的代码如下
'EXCEPTION_HANDLER': 'app01.自己定义的异常类路径',
}
封装response(重要)
from rest_framework.response import Response
class APIResponse(Response):
def __init__(self, code=100, msg='成功', data=None, status=None, headers=None, content_type=None, **kwargs):
data = {'code': code, 'msg': msg,}
# 判断data是否有值
if data:
data['data'] = data
# 可以增加额外参数
data.update(**kwargs)
super.__init__(data=data, status=status, headers=headers, content_type=content_type)