pip命令
pip install djangorestframework
from django.shortcuts import render, HttpResponse
from rest_framework.views import APIView
class BookView(APIView):
def get(self, request):
return HttpResponse("GET请求。。。。")
def post(self, request):
return HttpResponse("POST请求。。。。")
def delete(self, request):
return HttpResponse("delete请求。。。。")
通过源码发现,APIView在as_view()函数里面,只是在最后的使用CSRF做了一层包装
那通过上篇博客,我们分析 类视图 的源码发现,一个请求,基本就是如下步骤和流程
get 请求访问/book/ => view() 相当于访问了这个view()函数 => dispatch() => return get()
post 请求访问/book/ => view() 相当于访问了这个view()函数 => dispatch() => return post()
既然在view中没有做多大改变,
那么重写的意义以及为什么要重新写个APIView类继承一下,就在dispatch()函数中
class APIView(View):
# The following policies may be set at either globally, or per-view.
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
parser_classes = api_settings.DEFAULT_PARSER_CLASSES
authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS
metadata_class = api_settings.DEFAULT_METADATA_CLASS
versioning_class = api_settings.DEFAULT_VERSIONING_CLASS
# Allow dependency injection of other settings to make testing easier.
settings = api_settings
schema = DefaultSchema()
@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.'
)
cls.queryset._fetch_all = force_evaluation
# 执行父类View的as_view方法,得到view()函数
# 这块可以看我上篇博客里面 分析 类视图源码 就清晰了
view = super().as_view(**initkwargs)
view.cls = cls
view.initkwargs = initkwargs
# Note: session based authentication is explicitly CSRF validated,
# all other authentication is CSRF exempt.
return csrf_exempt(view)
APIView重写的dispatch()就是,进行封装一层认证、权限、限流的三件套
还有就是 新的 request对象
class APIView(View):
# The following policies may be set at either globally, or per-view.
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
parser_classes = api_settings.DEFAULT_PARSER_CLASSES
authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS
metadata_class = api_settings.DEFAULT_METADATA_CLASS
versioning_class = api_settings.DEFAULT_VERSIONING_CLASS
# Allow dependency injection of other settings to make testing easier.
settings = api_settings
schema = DefaultSchema()
@classmethod
def as_view(cls, **initkwargs):
# ......这块省略
pass
# Note: Views are made CSRF exempt from within `as_view` as to prevent
# accidental removal of this exemption in cases where `dispatch` needs to
# be overridden.
def dispatch(self, request, *args, **kwargs):
"""
`.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)
self.request = request
self.headers = self.default_response_headers # deprecate?
try:
# 初始化: 认证、权限、限流组件三件套
self.initial(request, *args, **kwargs)
# 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
# request传递最新的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
Request对象不同, 传入到视图方法中的是 REST Framework 的 Request 对象,
而不是 Django 的HttpRequest对象
视图方法可以返回 REST Framework 的 Request 对象,视图会为响应数据设置(render) 符合前端期望要求的格式
任何 APIException 异常都会被捕获到,并且处理合适格式的响应信息返回给客户端
重新声明了一个新的as_views方法并在dispatch()进行路由分发前,会对请求的客户端进行身份认证、权限检查、流量控制。
request.data 返回解析之后的请求体数据。类似于Django中标准的request.POST和request.FILES属性,但提供了以下特性:
request.query_params 与 Djangobiao标准的request.GET相同,正式更换了更为标准的名称
获取django封装的Request对象