1224 rest_framework框架的封装特点

rest_framework

它是基于Django的一种服务框架,可以帮助我们快速开发符合RESTful规范的接口框架。

功能:

1.路由

2.视图

3.版本

4.认证

5.权限

6.频率

7.解析器

8.序列化

9.分页

10.渲染器

在setting中配置,rest_framework实质上是一个app,需要注册才可以使用

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框架自定义配置

cbv中的类直接继承APIView

class BookAPIView(APIView):
    pass

在settings中自定义,里面可以设置相应的

REST_FRAMEWORK = {
	
}

2. APIView

csrf验证不限制

原生django受csrf限制,而drf不受csrf认证限制

# 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生命周期

1.APIView类继承了View类,重写了as_view方法和dispatch方法

2.重写的as_view方法,主体还是View的as_view,只是在返回视图view函数地址时,局部禁用csrf认证

3.重写了dispatch方法

  • 在执行请求逻辑前:请求模块(二次封装request),解析模块(三种数据包格式的数据解析)
  • 在执行请求逻辑中:异常模块(执行出现任何异常交给异常处理模块处理)
  • 在执行请求逻辑后:响应模块(二次封装response),渲染模块(响应的数据能被JSON和页面两种渲染)
dispatch方法:
        二次封装request对象()
            包含解析模块
        三大认证:
            (认证.权限.频率),用来替换csrf安全认证,要比csrf认证强大的多
        异常模块:
            处理请求异常通知,所有的API类异常都交由它处理self.handle_exception(exc)
        二次封装response
            处理了结果渲染,包含许多渲染模块

技术图片

  1. 启动django项目

  2. 加载settings.py文件

  3. 读取models.py文件

  4. 加载views.py文件

  5. 加载urls.py文件

  6. 执行urls.py文件

    url(r'^book/(?P<pk>\d+)/$',views.BookAPIView.as_view())
    执行views.BookAPIView.as_view()函数方法
    

    技术图片

3.1 请求模块

  • 将wsgi的request对象转化成drf的Request类的对象

  • 封装后的request对象完全兼容wsgi的request对象,并且将原request保存在新request._request中

  • 重新格式化请求数据存放位置

拼接参数:
	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

img

img

img

img

img

img

img

img

img

img

img

img

3.2 解析模块

img

只处理数据包参数

json				// 'rest_framework.parsers.JSONParser',
urlencoded			// 'rest_framework.parsers.FormParser',
form-data			// 'rest_framework.parsers.MultiPartParser',
  • 全局配置所有视图类的解析方式,解析配置可以配置三种

  • 局部配置当前视图类的解析方式,解析配置可以配置三种

  • 配置的查找顺序: 局部(视图类的类属性) => 全局(settings文件的drf配置) => 默认(drf的默配置)

注: 该模块了解,但是全局局部配置是重点

局部配置

在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

全局配置

	在settings中配置
        REST_FRAMEWORK = {
            'DEFAULT_PARSER_CLASSES': [
                'rest_framework.parsers.JSONParser',
                'rest_framework.parsers.FormParser',
                'rest_framework.parsers.MultiPartParser',
            ],
        }

默认配置

drf自身的设置
在APIView类中的rest_framework.settings.APISettings

3.3 响应模块

img

data: 响应数据

status: 响应的网络状态码

---------------------------------------------------------

template_name: drf完成前后台不分离返回页面,但是就不可以返回data(不需要了解)

headers: 响应头,一般不规定,走默认

exception: 一般异常响应,会将其设置成true,默认为False(不设置也没事)

content_type: 默认就是application/json,不需要处理

代码

# 响应模块状态码
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 渲染模块(了解)

Postman请求结果是json,浏览器请求结果是页面

可以全局与局部配置
'rest_framework.renderers.JSONRenderer', 	// 渲染json
'rest_framework.renderers.BrowsableAPIRenderer',	// 渲染浏览器界面,项目上线尽量关闭

全局配置

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ],
}

局部配置

# 渲染模块
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
class BookAPIView(APIView):
    # 局部配置渲染类,只适用当前视图类
    renderer_classes = [JSONRenderer,BrowsableAPIRenderer]

3.5 异常模块

源码分析

# 异常模块: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)

img

img

img

img

img

img

img

img

自定义异常处理

首先在settings文件中设置

REST_FRAMEWORK = {
    # 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler',
    # 配置自定义的报错函数路径
    'EXCEPTION_HANDLER': 'api.exception.exception_handler',
}

需要重写exception_handle方法,并使用系统默认的处理函数

# 自定义报错的界面
# 一定要在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

代码

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
posted @ 2019-12-24 23:10  fwzzz  阅读(404)  评论(0编辑  收藏  举报