django restframework 初识

匿名 (未验证) 提交于 2019-12-02 22:56:40

从后台开发的角度来说,不借助restframework框架一样可以用django来写接口。但是有了restframework之后,我们用restframework会更加方便,因为这个框架帮我们做了很多事,使用这个框架来开发接口会更加便捷。restframework里面大致实现了以下功能:

  • 权限
  • 认证
  • 访问评率限制
  • 序列化
  • 路由
  • 视图
  • 分页
  • 渲染器
  • 解析器
  • 版本

首先django不存在CBV和FBV哪种方式更好的说法,它们的本质都是一样的,写在路由里都是对应一个函数,CBV的as_view其实就是返回一个view函数。

APIView的as_view() 方法返回一个不需要csrf验证的view函数,这个view函数调用的其实就是django原生View类中的view函数,原生view函数调用的dispatch,而dispatch被APIview重写了dispatch方法

@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)

原生view,在外部是一个classonlymethod, 内部通过cls(**initkwargs)创建实例

        def view(request, *args, **kwargs):             self = cls(**initkwargs)             if hasattr(self, 'get') and not hasattr(self, 'head'):                 self.head = self.get             self.request = request             self.args = args             self.kwargs = kwargs             return self.dispatch(request, *args, **kwargs)

APIView的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

APIView有一些默认配置

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

其中api_settings是一个对象 api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)
其中DEFAULTS 是配置文件中的一个大字典,这个对象的实例方法如下

    def __init__(self, user_settings=None, defaults=None, import_strings=None):         if user_settings:             self._user_settings = self.__check_user_settings(user_settings)         self.defaults = defaults or DEFAULTS         self.import_strings = import_strings or IMPORT_STRINGS         self._cached_attrs = set()

api_settings 对象只有_user_settings, defaults,import_strings 和 _cached_attrs 四个属性,当取不是这4个属性的时候调用__getattr__方法

@property     def user_settings(self):         if not hasattr(self, '_user_settings'):             self._user_settings = getattr(settings, 'REST_FRAMEWORK', {})         return self._user_settings      def __getattr__(self, attr):         if attr not in self.defaults:             raise AttributeError("Invalid API setting: '%s'" % attr)          try:             # Check if present in user settings             val = self.user_settings[attr]         except KeyError:             # Fall back to defaults             val = self.defaults[attr]          # Coerce import strings into classes         if attr in self.import_strings:             val = perform_import(val, attr)          # Cache the result         self._cached_attrs.add(attr)         setattr(self, attr, val)         return val

从上面代码来看,是先取我们django settings中的 REST_FRAMEWORK 中的内容,取不到就去DEFAULTS这个大字典去取,所以当我们去做django restframework中的全局配置就是去django settings中配置一个key为REST_FRAMEWORK的大字典。

django restframework中对原生request进行了封装


取GET请求的数据,三种方式:

  1. request._request.GET.get(‘name‘)
  2. request.GET.get(‘name‘)
  3. request.query_params.get(‘name‘)


原文:https://www.cnblogs.com/longyunfeigu/p/9361158.html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!