zoukankan      html  css  js  c++  java
  • django restframework 初识

    简介

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

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

    CBV和FBV

    首先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
    

    restframework的全局配置

    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的大字典。

    对request的封装

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


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

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


  • 相关阅读:
    【BigData】Java基础_ArrayList的使用
    【BigData】Java基础_构造方法的使用
    【BigData】Java基础_类和对象的基本使用
    【BigData】Java基础_冒泡排序
    【BigData】Java基础_数组
    【BigData】Java基础_循环
    【BigData】Java基础_终端输入2个数字并求和
    Navicat自动断开连接处理方式
    名字修饰约定extern "C"与extern "C++"浅析
    qt study 元对象,属性和反射编程
  • 原文地址:https://www.cnblogs.com/longyunfeigu/p/9361158.html
Copyright © 2011-2022 走看看