@classmethod #实例和类都可以调用
def as_view(cls, **initkwargs):
"""
Store the original class on the view function.
This allows us to discover information about the view when we do URL
reverse lookups. Used for breadcrumb generation.
"""
if isinstance(getattr(cls, 'queryset', None), models.query.QuerySet):
def force_evaluation():
raise RuntimeError(
'Do not evaluate the `.queryset` attribute directly, '
'as the result will be cached and reused between requests. '
'Use `.all()` or call `.get_queryset()` instead.'
)#这个是为了限制你只能动态地创建 queryset ,而不能是一个常量
cls.queryset._fetch_all = force_evaluation
view = super().as_view(**initkwargs)#调用父类的 as_view() 方法,父类的as_view()里面为装饰器,作用为分发
#下面是记录
view.cls = cls
view.initkwargs = initkwargs
# Note: session based authentication is explicitly CSRF validated,
# all other authentication is CSRF exempt.
return csrf_exempt(view)
首先在路由中 调用 as_view()方法,这个方法也是一个装饰器,是直接免除 csrf 检测的
父类的 as_view() 里使用的 dispatch 方法 调用的为 APIView 中的 方法
def dispatch(self, request, *args, **kwargs):
#参数有 request ,对原生的 rquest 对象做了包装
"""
`.dispatch()` is pretty much the same as Django's regular dispatch,
but with extra hooks for startup, finalize, and exception handling.
"""
self.args = args #对象
self.kwargs = kwargs
#将原本的 request 封装后返回
request = self.initialize_request(request, *args, **kwargs)#初始化 request
self.request = request #赋值
self.headers = self.default_response_headers #默认头
try:
self.initial(request, *args, **kwargs)#这个函数功能很强大,本处的 request 为封装后的
# Get the appropriate handler method
#如果请求方法在 列表中
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
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
#初始化 request
def initialize_request(self, request, *args, **kwargs):
"""
Returns the initial request object.
返回一个初始化的 request 对象
使用Django的Request生成REST中的Request
"""
parser_context = self.get_parser_context(request)
#返回的是 drf 的 request 类 并且叫做 _request
return Request(
request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(),
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)
def initial(self, request, *args, **kwargs):
"""
Runs anything that needs to occur prior to calling the method handler.
"""
self.format_kwarg = self.get_format_suffix(**kwargs)
# Perform content negotiation and store the accepted info on the request
neg = self.perform_content_negotiation(request)
request.accepted_renderer, request.accepted_media_type = neg
# Determine the API version, if versioning is in use.
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme
# Ensure that the incoming request is permitted
self.perform_authentication(request) #执行认证
self.check_permissions(request) # 检查权限
self.check_throttles(request) #检查 频率
initial
- 获取格式化后缀
- 进行内容决策
- 进行版本决策
- 执行认证
- 检查权限
- 检查节流
Request 类
class Request(object):
def __init__(self, request, parsers=None, authenticators=None,
negotiator=None, parser_context=None):
...
#将原始的WSGIReqeust对象赋值给_request
self._request = request
....
#调用旧的request.GET
@property
def query_params(self):return self._request.GET
#调用旧的request.POST
@property
def POST(self):return QueryDict('', encoding=self._request._encoding)
"""
1.views.Book.as_view()
2.Book类中没有 as_view方法,去其父类APIView中找
3.在APIView中的as_view 方法中 执行了这样一句代码
view = super(APIView, cls).as_view(**initkwargs)
因此最终的as_view 还是从View 中的as_view来
4. 执行View里面的as_view()方法,返回view函数
5. url和视图函数之间建立绑定关系完毕,等待用户请求
6. 接收到用户请求,执行 Book--as_view(此处的as_view出处已再说上面,再次不再赘述)--View.as_view
7.执行self.dispatch()的时候,执行结果是什么就返回什么
8.开始找dispatch方法,self里面没有,Book类中也没有,在 APIView 中
9.开始执行APIView 中的 dispatch方法
10.最后找到http方法(get,post,put,delete)
11. 开始执行找到的方法(GET),self.get(),此时的self代表Book的实例化对象
12. 假设 请求为POST 请求,
request.data --->获取POST请求前端发送过来的数据
request.FILES ----> 获取POST请求前端发送过来的文件
13. 开始执行reqeust.data
@property
def data(self):
if not _hasattr(self, '_full_data'):
self._load_data_and_files()
return self._full_data
14. 执行该函数里面的 self._load_data_files()
15. 执行 self._load self.files=self.parse()
16. 执行 parser = self.negotiator.select_parser(self, self.parsers)
17. 查找:self.parsers
18. 执行 并向上返回结果
"""
来源:CSDN
作者:扣剑书生
链接:https://blog.csdn.net/weixin_44038167/article/details/103462337