一、安装djangorestframework
方式一:pip3 install djangorestframework 方式二:pycharm图形化界面安装 方式三:pycharm命令行下安装(装在当前工程所用的解释器下)
djangorestframework: 它是一个app,可以应用到项目中; 快速的构建resful规范的接口; 以后再执行的dispatch方法是APIView的dispatch方法; restframework提供了一个Request对象; Request对象继承了Django默认的HttpRequest对象,它最核心的功能就是请求数据都包含在request.data属性中, 类似于Django的request.POST,但是request.data应用范围更广: 1)request.data:返回解析之后的请求体数据,类似于Django中标准的request.POST和request.FILES属性。 request.data包含了解析之后的文件和非文件数据,包含了对POST PUT PATCH请求方式解析后的数据,利用了 REST Framework的parsers解析器,不仅支持表单类型数据,也支持json数据 2)request.query_params: 与Django标准的request.GET相同
drf使用:
在setting中配置,把rest_framework加入到app中: INSTALLED_APPS= [ 'rest_framework', ] 以后再写视图,可以都写cbv,继承APIView: from rest_framework.views import APIView class Books(APIView): pass
二、APIView源码分析
as_view方法:
@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 = super(APIView, cls).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)
dispatch:
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 = 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 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
initialize_request
def initialize_request(self, request, *args, **kwargs): """ Returns the initial request object. """ parser_context = self.get_parser_context(request) return Request( request, parsers=self.get_parsers(), authenticators=self.get_authenticators(), negotiator=self.get_content_negotiator(), parser_context=parser_context )
initial方法(内部调用认证,权限,频率)
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)
源码分析总结:
继承了APIView 之后: -1 所有的请求都没有csrf的认证了 -2 在APIView中as_view本质还是调用了父类的as_view(View的as_view) -3 as_view中调用dispatch -----》这个dispatch是APIView的dispatch -APIVIew的dispatch方法: -1 对原生request对象做了一层包装(面向对象的封装),以后再用的request对象都新的request对象 -2 在APIView中self.initial(request, *args, **kwargs),里面有频率控制,权限控制和认证相关 -3 根据请求方法执行咱们写的视图类中的相应方法 --视图类中方法的request对象,已经变成了封装后的request -Request类: -1 原生的request是self._request -2 取以post形式提交的数据,从request.data中取(urlencoded,formdata,json格式) -3 query_params 就是原生request的GET的数据 -4 上传的文件是从FILES中取 -5 (重点)其他的属性,直接request.属性名(因为重写了__getattr__方法)