table of Contents
rest_framework
It is based on a service framework Django can help us to quickly develop an interface framework in line with RESTful specification.
功能:
1.路由
2.视图
3.版本
4.认证
5.权限
6.频率
7.解析器
8.序列化
9.分页
10.渲染器
In setting the configuration, rest_framework essentially a app, need to register before you can use
Packaging Specification frame 1. rest_framework
from rest_framework.views import APIView //视图
from rest_framework.request import Request //请求
from rest_framework.response import Response //响应
from rest_framework.exceptions import APIException //异常
from rest_framework.pagination import PageNumberPagination //分页
from rest_framework.settings import APISettings //设置settings
from rest_framework.parsers import JSONParser //解析
from rest_framework.filters import OrderingFilter //筛选
drf frame custom configuration
cbv in class directly inherited APIView
class BookAPIView(APIView):
pass
In the custom settings, which you can set the appropriate
REST_FRAMEWORK = {
}
2. APIView
Without limiting the verification csrf
Django by native csrf restrictions, limitations and drf not csrf certification
# django 的视图类
from django.views import View
from django.http import JsonResponse
class BookView(View):
def get(self,request,*args,**kwargs):
return JsonResponse({
'msg':'view get ok'
})
def post(self,request,*args,**kwargs):
return JsonResponse({
'msg':'view post ok'
})
# 使用APIView
from rest_framework.views import APIView
from rest_framework.response import Response
class BookAPIView(APIView):
def get(self,request,*args,**kwargs):
return Response({
'msg':'view get ok'
})
# post方法不需要注释csrf照样可以传递
def post(self,request,*args,**kwargs):
return Response({
'msg':'view post ok'
})
3. APIView life cycle
1.APIView class inherits from the View class, override a method and dispatch method as_view
2. The method of as_view rewritable or View, as_view body, but in view of the return address of the function view, partially disabled csrf certification
3. Rewrite the dispatch method
- Before execution request logic: requesting module (the second package request), analysis module (three types of data packet format parsing)
- In the execution request logic: abnormal module (to perform any unusual exception processing module)
- After execution of the request logic: responding module (the second package response), rendering (JSON and response data can be two kinds of page rendering) module
dispatch方法:
二次封装request对象()
包含解析模块
三大认证:
(认证.权限.频率),用来替换csrf安全认证,要比csrf认证强大的多
异常模块:
处理请求异常通知,所有的API类异常都交由它处理self.handle_exception(exc)
二次封装response
处理了结果渲染,包含许多渲染模块
Start django project
Load settings.py file
Read models.py file
Load views.py file
Load urls.py file
Urls.py file execution
url(r'^book/(?P<pk>\d+)/$',views.BookAPIView.as_view()) 执行views.BookAPIView.as_view()函数方法
3.1 requesting module
Wsgi object request object converted to the Request class drf
request object packaged fully compatible wsgi request object, and stored in the original request in the new request._request
Reformats the request data storage position
拼接参数:
request.query_params
数据包参数:
request.data
print(request._request.method) # 在内部将wsgi的request赋值给了request._request
print(request.method) # 就是通过__getattr__走的是request._request.method
print(request.query_params) # 走的是方法属性,就是给request._request.GET重新命名
print(request.data) #走的是方法属性,依赖于request._full_data
3.2 analysis module
Only process the packet parameters
json // 'rest_framework.parsers.JSONParser',
urlencoded // 'rest_framework.parsers.FormParser',
form-data // 'rest_framework.parsers.MultiPartParser',
All analytically global configuration view class, parses configuration may configure three
Current local configuration analytically view class, parses configuration may configure three
Search order arranged: topical (class attributes view class) => Global (DRF configuration settings file) => default (default configuration of the DRF)
Note: This module realize it, but the overall local configuration is the key
Local Configuration
在views中设置
from rest_framework.parsers import JSONParser,FormParser,MultiPartParser
class BookAPIView(APIView):
parser_classes = [JSONParser,FormParser,MultiPartParser]
def get(self,request,*args,**kwargs):
pass
def post(self,request,*args,**kwargs):
pass
Global Configuration
在settings中配置
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser',
],
}
default allocation
drf自身的设置
在APIView类中的rest_framework.settings.APISettings
Response module 3.3
data: 响应数据
status: 响应的网络状态码
---------------------------------------------------------
template_name: drf完成前后台不分离返回页面,但是就不可以返回data(不需要了解)
headers: 响应头,一般不规定,走默认
exception: 一般异常响应,会将其设置成true,默认为False(不设置也没事)
content_type: 默认就是application/json,不需要处理
Code
# 响应模块状态码
from rest_framework import status
class BookAPIView(APIView):
# 响应模块可以自定义返回的数据
def get(self,request,*args,**kwargs):
response = Response(
data={
'msg':'apiview get ok'
},
status=status.HTTP_404_NOT_FOUND
)
3.4 rendering module (understand)
Postman request result is json, the result is a browser requests a page
可以全局与局部配置
'rest_framework.renderers.JSONRenderer', // 渲染json
'rest_framework.renderers.BrowsableAPIRenderer', // 渲染浏览器界面,项目上线尽量关闭
Global Configuration
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
],
}
Local Configuration
# 渲染模块
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
class BookAPIView(APIView):
# 局部配置渲染类,只适用当前视图类
renderer_classes = [JSONRenderer,BrowsableAPIRenderer]
3.5 abnormal module
Source code analysis
# 异常模块:APIView类的dispatch方法中
response = self.handle_exception(exc) # 点进去
# 获取处理异常的句柄(方法)
# 一层层看源码,走的是配置文件,拿到的是rest_framework.views的exception_handler
# 自定义:直接写exception_handler函数,在自己的配置文件配置EXCEPTION_HANDLER指向自己的
exception_handler = self.get_exception_handler()
# 异常处理的结果
# 自定义异常就是提供exception_handler异常处理函数,处理的目的就是让response一定有值
response = exception_handler(exc, context)
Custom exception handling
首先在settings文件中设置
REST_FRAMEWORK = {
# 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler',
# 配置自定义的报错函数路径
'EXCEPTION_HANDLER': 'api.exception.exception_handler',
}
Needs to be rewritten exception_handle方法
, and use the system default handler
# 自定义报错的界面
# 一定要在settings文件中将异常模块配置自己的异常处理函数
from rest_framework.response import Response
# 导入异常模块处理的函数,并起了个别名
from rest_framework.views import exception_handler as drf_exception_handler
def exception_handler(exc,content):
# 获取异常模块处理过的异常信息
response = drf_exception_handler(exc,content)
# 拼接报错信息
detail = '%s - %s - %s' % (content.get('view'),content.get('request').menthod,exc)
# 如果没有信息,就是服务端错误
if not response:
response = Response({'detail':detail})
else:
response.data = {'detail':detail}
# 核心: 要将response.data.get('detail') 信息记录到日志文件
print( response.data.get('detail'))
return response
Code
from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.response import Response
from rest_framework import status
def exception_handler(exc, context):
# 1.先让drf的exception_handler做基础处理,拿到返回值
# 2.若有返回值则drf处理了,若返回值为空说明drf没处理,需要我们手动处理
response = drf_exception_handler(exc, context)
print(exc) # 错误内容 'NoneType' object has no attribute 'title'
print(context)
# {'view': <api.views.Book object at 0x000001BBBCE05B00>, 'args': (), 'kwargs': {'pk': '3'}, 'request': <rest_framework.request.Request object at 0x000001BBBCF33978>}
print(response)
# 返回值为空,做二次处理
if response is None:
print('%s - %s - %s' % (context['view'], context['request'].method, exc))
# <api.views.Book object at 0x00000242DC316940> - GET - 'NoneType' object has no attribute 'title'
return Response({
'detail': '服务器错误'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=True)
return response