rest_framework框架的封装特点和APIView请求生命周期

rest_framework框架的封装特点:

import rest_framework
from rest_framework.views import APIView
from rest_framework.request import Request

在views.py中写出合适的api类,只需要继承rest_framework中generics中的某个类,重写我们需要的方法实现合适的逻辑即可

APIView请求生命周期

"""
APIView的as_view(局部禁用csrf)
=>走父级的as_view调用dispatch分发请求
=>APIView自己重写了dispatch,使用自己完成分发
=>分发前完成request二次封装、数据解析
=>三大认证
=>请求的实际响应(自己的视图类的处理分发)
=>出现了异常,就会交给异常模块处理异常
=>响应模块完成响应、渲染模块可以以json或浏览器两种方式渲染
APIView请求生命周期
1)APIView类继承View类,重写了as_view和dispatch方法
2)重写的as_view方法,主体还是View的as_view,只是在返回视图view函数地址时,局部禁用csrf认证
3)在执行请求逻辑前:请求模块(二次封装request)、解析模块(三种数据包格式的数据解析)
在执行请求逻辑中:异常模块(执行出任何异常交给异常模块处理)
在执行请求逻辑后:响应模块(二次封装response)、渲染模块(响应的数据能JSON和页面两种渲染)
"""

生命周期图:

请求模块

"""
request._request 被request完全兼容
request.query_params | request.data
1)将wsgi的request对象转化成drf的Request类的对象
2)封装后的request对象完全兼容wsgi的request对象,并且将原request保存在新的request._request
3)重写格式化请求数据存放位置
    拼接参数:request.query_params
    数据包参数:request.data
源码解析:
入口:APIVIew的dispatch方法的request=self.initialize_request(request,*args,**kwargs)
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
"""

解析模块

"""
解析模块:只处理数据包参数  -form-data,urlencoded,json
局部配置:parser_classes = [JSONParser, FormParser, MultiPartParser]
全局配置:
    ‘DEFAULT_PARSER_CLASSES‘: [
            ‘rest_framework.parsers.JSONParser‘,
            ‘rest_framework.parsers.FormParser‘,
            ‘rest_framework.parsers.MultiPartParser‘
        ],
1)全局配置所有视图类的解析方式,解析配置可以配置三种
2)局部配置当前视图类的解析方式,解析配置可以配置三种
3)配置的查找顺序:局部(视图类的类属性) =>全局(settings文件的drf配置)=>默认(drf的默认配置)

注:该模块了解,但是全局局部配置是重点
REST_FAMEWORK = {
    全局配置解析类:适用于所有视图类
    ‘DEFAULT_PARSER_CLASSES‘: [
    #‘rest_framework.parsers.JSONParser‘,
    #‘rest_framework.parsers.FormParser‘,
    #‘rest_framework.parsers.MultiPartParser‘
    ],
}
源码解析:
入口:APIVIew的dispatch方法的 request=self.initialize_request(request,*args,**kwargs)
获取解析类:parsers = self.get_parsers(),
进行局部全局默认配置查找顺序进行查找:return [parser() for parser in self.parser_classes]
"""

响应模块

"""
Response(data=常量|列表|字典,status=网络状态码)
data:响应数据
status:响应的网络状态码
template_name:drf完成前后台不分离返回页面,但是就不可以返回data(不需要了解)
headers:响应头,一般不规定,走默认
exception:一般异常响应,会将其设置成True,默认False(不设置也没事)
content_type:默认就是 application/json,不需要处理
"""

渲染模块

"""
局部配置:renderer_classes = [JSONRenderer, BrowsableAPIRenderer]
全局配置:
        ‘DEFAULT_RENDERER_CLASSES‘: [
            ‘rest_framework.renderers.JSONRenderer‘,
            ‘rest_framework.renderers.BrowsableAPIRenderer‘,  # 上线后尽量关闭
        ],
渲染模块(了解):Postman请求结果是json,浏览器请求结果是页面
可以全局与局部配置
局部配置解析类:只适用于当前视图类

parser_classes = [JSONParser, FormParser, MultiPartParser]
局部配置渲染类:只适用于当前视图类

renderer_classes = [JSONRenderer, BrowsableAPIRenderer]
    def post(self, request, *args, **kwargs):
        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

        return Response({
            ‘msg‘: ‘apiview post ok‘
        })
"""

异常模块

"""

settings中配置:‘EXCEPTION_HANDLER‘: ‘api.exception.exception_handler‘,
重写exception_handler方法:
一定要在settings文件中将异常模块配置自己的异常处理函数
from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.response import Response

先交个drf处理客户端异常,如果结果response代表服务器异常,自己处理
最终一定要在日志文件中记录异常现象
def exception_handler(exc, context):
    response = drf_exception_handler(exc, context)
    detail = ‘%s - %s - %s‘ % (context.get(‘view‘), context.get(‘request‘).method, exc)
    if not response:  # 服务端错误
        response =  Response({‘detail‘: detail})
    else:
        response.data = {‘detail‘: detail}

    核心:要将response.data.get(‘datail‘)信息记录到日志文件
    logger.waringz(response.data.get(‘datail‘))

    return response
源码解析:
入口:APIVIew的handle_exception方法的
获取异常函数:exception_handler = self.get_exception_handler()
提供额外参数:context = self.get_exception_handler_context()
默认的exception_handler函数只处理客户端异常形成的response对象,
服务器异常不做处理
二次封装过后的response,处理了结果渲染
"""

原生的Django与drf比较:drf不受csrf认证限制

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‘
        })

-----------------------------------------------
from rest_framework.views import APIView
from rest_framework.response import Response
class BookAPIView(APIView):
    def get(self, request, *args, **kwargs):
        return Response({
            ‘msg‘: ‘apiview get ok‘
        })
    def post(self, request, *args, **kwargs):
        return Response({
            ‘msg‘: ‘apiview post ok‘
        })
settings文件中一定要注册drf

INSTALLED_APPS = [
    ‘rest_framework‘,
]

# drf框架自定义配置
REST_FAMEWORK = {
    #  全局配置解析类:适用于所有视图类
    ‘DEFAULT_PARSER_CLASSES‘: [
    #‘rest_framework.parsers.JSONParser‘,
    #‘rest_framework.parsers.FormParser‘,
    #‘rest_framework.parsers.MultiPartParser‘
    ],
   # 全局配置渲染类:适用于所有视图类
        ‘DEFAULT_RENDERER_CLASSES‘: [
        ‘rest_framework.renderers.JSONRenderer‘,
        #‘rest_framework.renderers.BrowsableAPIRenderer‘, 上线尽量关闭
        ],
       # 异常模块:异常处理函数
        # ‘EXCEPTION_HANDLER‘: ‘rest_framework.views.exception_handler‘,
        ‘EXCEPTION_HANDLER‘: ‘api.exception.exception_handler‘,
}
#  在api文件夹中新建exception文件

#  一定要在settings文件中将异常模块配置自己的异常处理函数
from rest_framework.views import exception_handler as drf_exception_handler
from rest-framework.response import Rseponse

def exception_handler(exc, context):
    response = drf_exception_handler(exc, context)
    detail = ‘%s - %s - %s‘ % (context.get(‘view‘), context.get(‘request‘).method, exc)
    if not response: 服务器错误
        response  = Rseponse({‘detail‘:detail})
    else:
        response.data = {‘detail‘:detail}

    #  核心:要将response.data.get(‘detail‘)信息记录到日志中
    logger.waring(response.data.get(‘detail‘))
    return response
#  utils文件夹下的views.py文件
def handle_exception(self,exc):

"""
Handle any exception that occurs, by returning an appropriate response,
or re-raising the error.
#  处理任何发生的异常,通过返回适当的响应,
#  或重新引发错误。
"""

#  出现三大认证相关异常,额外处理一下响应头
if isinstance(exc, (exceptions.NotAuthenticated,
                            exceptions.AuthenticationFailed)):

 # WWW-Authenticate header for 401 responses, else coerce to 403
            auth_header = self.get_authenticate_header(self.request)

            if auth_header:
                exc.auth_header = auth_header
            else:
                exc.status_code = status.HTTP_403_FORBIDDEN

#  获取出来异常的函数:该文件独立存在的exception_handler函数
exception_handler = self.get_exception_handler()

#  给异常处理提供额外的参数
context = self.get_exception_handler_context()

#  exc异常对象,context中用视图对象和请求对象
response = exception_handler(exc,context)

#  默认的exception_handler函数只处理客户端异常形成response对象,服务器异常不做处理,返回None
if response is None:
    self.raise_uncaught_exception(exc)

response.exception = True
return response

def dispatch(self, request, *args, **kwargs):
self.args = args
self.kwargs = kwargs
#  二次封装request对象,包含解析模块
request = self.initialize_request(request,*args,**kwargs)
self.request = request
self.headers = self.default_response_headers  # deprecate?
try:
   #   三大认证(认证、权限、频率),用来替换csrf安全认证,要比csrf认证强大得多

#  异常模块  -处理请求异常分支的
response = self.handle_exception(exc)

#  二次封装response,处理了结果渲染
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response

status文件中可以自定义网络状态码

原文地址:https://www.cnblogs.com/sweet-i/p/12116931.html

时间: 2024-10-08 03:24:23

rest_framework框架的封装特点和APIView请求生命周期的相关文章

APIView请求生命周期

今日总结 """ 1.APIView请求生命周期 APIView的as_view(局部禁用csrf) => 走父级的as_view调用dispatch分发请求 => APIView自己重写了dispatch,使用自己完成分发 => 分发前完成request二次封装.数据解析 => 三大认证 => 请求的实际响应(自己的视图类的处理分发) => 出现了异常,就会交给异常模块处理异常 => 响应模块完成响应.渲染模块可以json或浏览器两

drf框架 2 drf框架的请求生命周期(as_view和dispatch方法), 请求、解析、渲染、响应、异常, 序列化组件 ,ORM配置回顾(media文件配置),应用在settings.py中INSTALLED_APPS注册意义 ,数据库配置

应用是否需要在INSTALLED_APPS中注册 ''' 在没有使用到app的一些特殊操作时(比如数据库相关),不需要app的__init__文件注册时,文件夹可以不用注册,但是注册后,应用的所有功能都能使用 结论:所有应用都可以完成注册 ''' 数据库配置(全部在settings文件中完成即可) import pymysql pymysql.install_as_MySQLdb() DATABASES = { 'default': { 'ENGINE': 'django.db.backends

面试-Django框架请求生命周期

先看一张图吧! 1.请求生命周期 - wsgi, 他就是socket服务端,用于接收用户请求并将请求进行初次封装,然后将请求交给web框架(Flask.Django) - 中间件,帮助我们对请求进行校验或在请求对象中添加其他相关数据,例如:csrf.request.session - 路由匹配 - 视图函数,在视图函数中进行业务逻辑的处理,可能涉及到:orm.templates => 渲染 - 中间件,对响应的数据进行处理. - wsgi,将响应的内容发送给浏览器. 2.什么wsgi wsgi:

Django框架进阶7 django请求生命周期流程图, django中间件, csrf跨站请求伪造, auth认证模块

django请求生命周期流程图 djang中间件 它是django的门户 只要是全局相关的功能你都应该考虑使用django中间件来帮你完成 全局用户身份校验 全局用户访问频率校验 用户访问黑名单 用户访问白名单 # 只要以后用django开发业务 设计到全局相关的功能 你就考虑用中间件 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.Sessio

request请求生命周期

request请求生命周期 一.request请求分析 1.1. request数据请求 # views.py from rest_framework.views import APIView from rest_framework.response import Response from django.http.request import QueryDict class BookAPIView(APIView): def get(self, request, *args, **kwargs

Django请求生命周期和ORM

dajngo请求生命周期 django请求生命周期是:当用户在browser点击URL后,在django后台都发生了什么. 请求响应Http 1.发送Http请求 2.服务器接收,根据请求头中url在路由关系表中进行匹配(从上到下) 3.匹配成功后,执行指定的views函数 URL –>函数 --->FBV URL –>类     --->FBV 4.业务处理 根据个人需求自定 操作数据库 原生SQL Django ORM ---->返回给用户的结果<----- -响应

详解ASP.NET MVC的请求生命周期

本文的目的旨在详细描述asp.net mvc请求从开始到结束的每一个过程. 我希望能理解在浏览器输入url并敲击回车来请求一个asp.net mvc网站的页面之后发生的任何事情. 为什么需要关心这些?有两个原因.首先是因为asp.net mvc是一个扩展性非常强的框架.例如,我们可以插入不同的viewengine来控制网站内容呈现的方式.我们还可以定义控制器生成和分配到某个请求的 方式.因为我想发掘任何asp.net mvc页面请求的扩展点,所以我要来探究请求过程中的一些步骤. 其次,如果你对测

[译] ASP.NET 生命周期 – ASP.NET 请求生命周期(三)

使用特殊方法处理请求生命周期事件 为了在全局应用类中处理这些事件,我们会创建一个名称以 Application_ 开头,以事件名称结尾的方法,比如 Application_BeginRequest.举个例子,就像 Application_Start 和 Application_End 方法,ASP.NET 框架就会在事件触发的时候找到这些函数并触发它.下面是更新后的代码片段: 1 using System; 2 using System.Collections.Generic; 3 using

ASP.NET MVC深度接触:ASP.NET MVC请求生命周期

这篇博文的目的旨在详细描述ASP.NET MVC 请求从开始到结束的每一个过程.我希望能理解在浏览器输入URL 并敲击回车来请求一个ASP.NET MVC 网站的页面之后发生的任何事情. 为什么需要关心这些?有两个原因.首先是因为ASP.NET MVC 是一个扩展性非常强的框架.例如,我们可以插入不同的ViewEngine 来控制网站内容呈现的方式.我们还可以定义控制器生成和分配到某个请求的方式.因为我想发掘任何ASP.NET MVC 页面请求的扩展点,所以我要来探究请求过程中的一些步骤. 其次