权力组件源码分析

在上1篇作品中我们曾经分析了求证组件源码,我们再来看看权限组件的源码,权限组件相对轻巧,因为只需求回到True
和False就可以

宗旨代码结构

  url.py:

from django.conf.urls import url, includefrom app import views  urlpatterns = [    url(r'^test/', views.TestView.as_view,]

  views.py:

from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework.request import Requestfrom rest_framework import exceptions  class MyPermission:    def has_permission(request, self):    '''    权限代码编写区域    '''    return True  #权限通过 如果权限不通过 返回False   class TestView:    permission_classes = [MyPermission, ]      def get(self, request, *args, **kwargs):        pass           def post(self, request, *args, **kwargs):        pass         '''        等等一系列的视图功能方法        '''

Class-based Views

REST框架提供了1个APIView类,它是Django中View类的子类。
APIView 类和例行的View类有以下多少个地点的不一样:

  • 传递给处理程序方法的呼吁将是REST框架的伸手实例,而不是Django的HttpRequest实例。
  • 拍卖方法重回的是REST框架的Response而不是Django的HttpResponse。该视图管理content
    negotiation,并依照响应设置科学的渲染器。
  • 其他APIException非常将被抓获并被调和为方便的响应。
  • 传播请求将被证实,并且在将呼吁发送给处理程序方法此前,将运转适当的权力
    and/or throttle 检查。

动用APIView类与应用正规的View类同样,像往常一模同样,传入的呼吁会调度适当的处理程序方法,如.get()或.post()。
此外,能够在决定API计策的各类方面的类上安装重重属性。
例如:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import authentication, permissions

class ListUsers(APIView):
    """
    View to list all users in the system.

    * Requires token authentication.
    * Only admin users are able to access this view.
    """
    authentication_classes = (authentication.TokenAuthentication,)
    permission_classes = (permissions.IsAdminUser,)

    def get(self, request, format=None):
        """
        Return a list of all users.
        """
        usernames = [user.username for user in User.objects.all()]
        return Response(usernames)

Class-based
Views

代码

  说明:

    • has_permission方法的再次来到值是布尔类型,True表示权限通过,False表示权限拒绝
    • 位置的大旨结构是做一些的类的权限剖断方法,全局权限决断后文介绍。
    • permission_classes属性别变化量同样也是1个列表,列表成分是权力剖断类。

API policy attributes

以下属性调节API视图的可插入方面。

Django’s class-based views are a welcome departure from the old-style
views.

澳门葡京备用网址 1澳门葡京备用网址 2

权力组件源码分析。源码分析

  其实权限的源码流程跟认证的流程基本同样。依然要掀起通过源码要想驾驭什么样,不然就会深陷1类别的源码之中。

.renderer_classes

—Reinout van
Rees

 1 class ShoppingCarView(ViewSetMixin, APIView):
 2      permission_classes = [MyPermission, ]
 3         def list(self,request, *args, **kwargs):
 4         """
 5         查看购物车信息
 6         :param args:
 7         :param kwargs:
 8         :return:
 9         """
10         try:
11             ret = BaseResponse()
12             pay_course_list = []
13             # key = 'shoppingcar_%s_%s' % (USERID, '*')
14             key = settings.SHOPCAR_FORMAT.format( request.user.id, "*")
15             user_key_list = COON.keys(pattern=key)  # 取到这个用户对应的所有课程字典 对应的键
16             for key in user_key_list:
17                 # 对应的每个键值 去取每个课程对应的信息 和价格列表
18                 temp = {
19                     'id': COON.hget(key, 'id').decode('utf8'),
20                     'name': COON.hget(key, 'name').decode('utf8'),
21                     'img': COON.hget(key, 'img').decode('utf8'),
22                     'default': COON.hget(key, 'default').decode('utf8'),
23                     'price_dict': json.loads(COON.hget(key, 'price_dict').decode('utf8')),
24                 }
25                 pay_course_list.append(temp)
26             ret.data = pay_course_list
27         except Exception as e:
28             ret.data = '查看失败'
29             ret.code = 00000
30         return Response(ret.dict)
31 
32 视图类

– 为啥会采用permission_classes属性别变化量?

 
澳门葡京备用网址 3

  python
的面向对象编制程序中,大家第一要推行的章程确定是dispatch方法,所以我们的分析入口正是dispatch方法,在dispatch方法中,能够看到,通过initialize_request方法将django原生的request进行了二次封装。由initialize_request方法的兑现进程能够看看,将其封装实例化成了2个Request对象。但权力剖断并不曾像认证同样初步化到了Request对象中,但对django原生的request封装依然供给重申的,因为编写代码的历程中对django原生的request的行使是必不可免的。

 
澳门葡京备用网址 4

 
一样的,权限决断的有血有肉进程跟认证一样,也是在dispatch方法中所调用的initial方法中贯彻。再跳转到initial方法中去。

 
澳门葡京备用网址 5

 
在initial方法中,能够看来权限剖断的不二诀要,没有错,正是通过check_permissions方法达成的。再跳转到这么些点子中去。

 
澳门葡京备用网址 6

在check_permissions方法中,就能够知见权限的推断纵然经过这一个for循环达成的。正因为在业务代码中恐怕存在多少种档次的权柄决断,所以才会由此巡回去推行我们定义好的权能决断类来产生多少个权力系列的判别功能。那样,大家能够感到到此地的“self.get_permissions()”的重临值应该便是我们在视图类中赋值过的permissions_classes属性别变化量的值。那就跳转到那么些措施中去探望吧。

  澳门葡京备用网址 7

  在get_permissions方法中看出,跟认证同样,重回值同样是1个列表生成式,而这些列表生成式使用的性质变量正是大家赋值过的permission_classes,跟大家后边的估计完全一致。综上所述,我们为了让drf接口源码使用上我们和好定义的权杖判别类,这我们就非得遵照源码中写的借口,将permission_classes属性别变化量赋值

.parser_classes

REST framework provides anAPIViewclass, which subclasses
Django’sViewclass.

视图类

– 在权力推断类中缘何会定义3个称呼为has_permission的方法?

  澳门葡京备用网址 8

  回到check_permissions方法中,我们看if推断句,后面刚刚说过,在for中的permission其实便是我们协调定义的权限判别类,那么在if句中的“.has_permission(request,self)”不就相应正是Mypermission类中的方法吗?所以,我们温馨定义的Mypermission类中势供给促成has_permission那个主意。(要小心这么些措施的参数)    

.authentication_classes

REST框架提供了1个apiview类,那类是Django视图类。

澳门葡京备用网址 9澳门葡京备用网址 10

– has_permission方法中,为啥重临值为布尔值?

  依旧跟上三个主题素材同样的,在上海教室中的if句中,大家得以看来“permission.has_permission(request,
self)”的再次来到值不正是布尔值吗,那一个重返值不便是has_permission方法再次来到值吗?当再次来到值为False时,就会实施if句中的代码,来抛出特别。

  澳门葡京备用网址 11

.throttle_classes

APIViewclasses are different from regularViewclasses in the following
ways:

class MyPermission(BasePermission):
    message = 'VIP用户才能访问'

    def has_permission(self, request, view):
        """
        自定义权限只有VIP用户才能访问
        """
        # 因为在进行权限判断之前已经做了认证判断,所以这里可以直接拿到request.user
        if request.user and request.user.type == 2:  # 如果是VIP用户
            return True
        else:
            return False

实例

澳门葡京备用网址 12澳门葡京备用网址 13

from django.conf.urls import url, includefrom web.views import TestViewurlpatterns = [    url(r'^test/', TestView.as_view,]

urls.py澳门葡京备用网址 14澳门葡京备用网址 15

#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework.authentication import BaseAuthenticationfrom rest_framework.permissions import BasePermissionfrom rest_framework.request import Requestfrom rest_framework import exceptionstoken_list = [    'sfsfss123kuf3j123',    'asijnfowerkkf9812',]class TestAuthentication(BaseAuthentication):    def authenticate(self, request):        """        用户认证,如果验证成功后返回元组: (用户,用户Token)        :param request:         :return:             None,表示跳过该验证;                如果跳过了所有认证,默认用户和Token和使用配置文件进行设置                self._authenticator = None                if api_settings.UNAUTHENTICATED_USER:                    self.user = api_settings.UNAUTHENTICATED_USER() # 默认值为:匿名用户                else:                    self.user = None                        if api_settings.UNAUTHENTICATED_TOKEN:                    self.auth = api_settings.UNAUTHENTICATED_TOKEN()# 默认值为:None                else:                    self.auth = None            (user,token)表示验证通过并设置用户名和Token;            AuthenticationFailed异常        """        val = request.query_params.get('token')        if val not in token_list:            raise exceptions.AuthenticationFailed("用户认证失败")        return ('登录用户', '用户token')    def authenticate_header(self, request):        """        Return a string to be used as the value of the `WWW-Authenticate`        header in a `401 Unauthenticated` response, or `None` if the        authentication scheme should return `403 Permission Denied` responses.        """        passclass TestPermission(BasePermission):    message = "权限验证失败"    def has_permission(self, request, view):        """        判断是否有权限访问当前请求        Return `True` if permission is granted, `False` otherwise.        :param request:         :param view:         :return: True有权限;False无权限        """        if request.user == "管理员":            return True    # GenericAPIView中get_object时调用    def has_object_permission(self, request, view, obj):        """        视图继承GenericAPIView,并在其中使用get_object时获取对象时,触发单独对象权限验证        Return `True` if permission is granted, `False` otherwise.        :param request:         :param view:         :param obj:         :return: True有权限;False无权限        """        if request.user == "管理员":            return Trueclass TestView:    # 认证的动作是由request.user触发    authentication_classes = [TestAuthentication, ]    # 权限    # 循环执行所有的权限    permission_classes = [TestPermission, ]    def get(self, request, *args, **kwargs):        # self.dispatch        print(request.user)        print(request.auth)        return Response('GET请求,响应内容')    def post(self, request, *args, **kwargs):        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')

views.py

.permission_classes

APIView类差别于普通视图类在以下方面:

自定义权限类

增添:全局权限

  同样,跟全局认证同样,大家只须要在settings配置文件中丰裕配置项就可以。然后,我们照样须要将我们自定义的权力类也写到大家在跟views.py同级目录下新建的公文夹(小编习惯叫utils)中的权限判别文件(permision.py)中去。

  澳门葡京备用网址 16

REST_FRAMEWORK = {    "DEFAULT_PERMISSION_CLASSES" :['api.utils.permission.Mypermission',]    }

  Mypermission正是大家写在utils文件夹中permission.py文件中的一个权限类。

  注意:若果有部分类不供给权限判定的话,能够在Mypermission类中丰裕“permission_classes
= []
”,即可。 

.content_negotiation_class

Requests passed to the handler methods will be REST
framework’sRequestinstances, not Django’sHttpRequestinstances.

澳门葡京备用网址 17澳门葡京备用网址 18

API policy instantiation methods

REST框架使用以下形式实例化各样可插拔API计策。 常常不必要重写那么些措施。

因而对处理方式须求将REST框架的要求的境况下,不是Django的HttpRequest实例。

urlpatterns = [
    url(r'^payment/$', payment.PaymentView.as_view({'post': 'create','put': 'update','get':'list'})),
]
.get_renderers(self)

Handler methods may return REST framework’sResponse, instead of
Django’sHttpResponse. The view will manage content negotiation and
setting the correct renderer on the response.

路由

.get_parsers(self)

Handler方法能够再次回到REST框架的响应,而不是Django的HttpResponse。视图将管理内容协商和响应设置科学的渲染器。

跟上一篇同样,来看代码是何许走到自己自定义的权限类中的。

.get_authenticators(self)

AnyAPIExceptionexceptions will be caught and mediated into appropriate
responses.

1.首先从url中分析

.get_throttles(self)

其余APIException非常将被介导的适用的影响。

  一.先来到视图类中的as.view()方法

.get_permissions(self)

Incoming requests will be authenticated and appropriate permission
and/or throttle checks will be run before dispatching the request to the
handler method.

  澳门葡京备用网址 19

.get_content_negotiator(self)

传扬的呼吁在运转在此以前将被认证,并将适可而止的权能或节流检查后发送随处理程序的不二等秘书技。

  而大家的自定义的法子中并未有as.view()方法,那将在去父类ViewSetMixin和APIView中去找,美观源码

.get_exception_handler(self)

Using theAPIViewclass is pretty much the same as using a
regularViewclass, as usual, the incoming request is dispatched to an
appropriate handler method such as.get()or.post(). Additionally, a
number of attributes may be set on the class that control various
aspects of the API policy.

2.分析源码

API policy implementation methods

调度处理程序方法从前调用以下措施。

行使APIView类是万分日常应用的视图类,传入的呼吁被分摊到八个正好的处理格局,例如.get()or.post()。别的,能够在支配API攻略的种种方面包车型大巴类上安装若干个性。

  1.先看ViewSetMixin类中

.check_permissions(self, request)

For example:

    澳门葡京备用网址 20

.check_throttles(self, request)

fromrest_framework.viewsimportAPIViewfromrest_framework.responseimportResponsefromrest_frameworkimportauthentication,permissionsclassListUsers(APIView):”””

    

.perform_content_negotiation(self, request, force=False)

View to list all users in the system.

澳门葡京备用网址 21

Dispatch methods

以下办法直接由视图的.dispatch()方法调用。
那么些实行其余索要在调用诸如.get(),.post(),put(),patch()和.delete()之类的处理程序方法在此之前或之后发生的别样操作。

* Requires token authentication.

class ViewSetMixin(object):
    """
    This is the magic.

    Overrides `.as_view()` so that it takes an `actions` keyword that performs
    the binding of HTTP methods to actions on the Resource.

    For example, to create a concrete view binding the 'GET' and 'POST' methods
    to the 'list' and 'create' actions...

    view = MyViewSet.as_view({'get': 'list', 'post': 'create'})
    """

    @classonlymethod
    def as_view(cls, actions=None, **initkwargs):
        """
        Because of the way class based views create a closure around the
        instantiated view, we need to totally reimplement `.as_view`,
        and slightly modify the view function that is created and returned.
        """
        # The suffix initkwarg is reserved for displaying the viewset type.
        # eg. 'List' or 'Instance'.
        cls.suffix = None

        # The detail initkwarg is reserved for introspecting the viewset type.
        cls.detail = None

        # Setting a basename allows a view to reverse its action urls. This
        # value is provided by the router through the initkwargs.
        cls.basename = None

        # actions must not be empty
        if not actions:
            raise TypeError("The `actions` argument must be provided when "
                            "calling `.as_view()` on a ViewSet. For example "
                            "`.as_view({'get': 'list'})`")

        # sanitize keyword arguments
        for key in initkwargs:
            if key in cls.http_method_names:
                raise TypeError("You tried to pass in the %s method name as a "
                                "keyword argument to %s(). Don't do that."
                                % (key, cls.__name__))
            if not hasattr(cls, key):
                raise TypeError("%s() received an invalid keyword %r" % (
                    cls.__name__, key))

        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            # We also store the mapping of request methods to actions,
            # so that we can later set the action attribute.
            # eg. `self.action = 'list'` on an incoming GET request.
            self.action_map = actions

            # Bind methods to actions
            # This is the bit that's different to a standard view
            for method, action in actions.items():
                handler = getattr(self, action)
                setattr(self, method, handler)

            if hasattr(self, 'get') and not hasattr(self, 'head'):
                self.head = self.get

            self.request = request
            self.args = args
            self.kwargs = kwargs

            # And continue as usual
       # 前面都是在对传参做判断和重新赋值,重要的是下面这一步,最后return 调用了dispatch方法

            return self.dispatch(request, *args, **kwargs)
.initial(self,request,* args,** kwargs)

试行在调用处理程序方法在此以前必要执行的其余操作。此措施用于施行权限和范围,并实行content negotiation。经常不供给覆盖此方式。

* Only admin users are able to access this view.

澳门葡京备用网址 22

.handle_exception(self,exc)

处理程序方法抛出的别的尤其都将传递给此方式,该方法再次来到1个响应实例,或再度引发那么些。
暗许完结拍卖rest_framework.exceptions.APIException的其余子类,以及Django的Http40四和PermissionDenied十分,并回到适当的错误响应。
若是您须求自定义您的API再次来到的荒唐响应,则应当对此方式开始展览子类化。

“””authentication_classes=(authentication.TokenAuthentication,)permission_classes=(permissions.IsAdminUser,)defget(self,request,format=None):”””

 

.initialize_request(self,request,* args,** kwargs)

担保传递给handler方法的伸手对象是Request的八个实例,而不是普普通通的Django
HttpRequest。
平凡不要求覆盖此措施。

Return a list of all users.

   二.找dispatch方法在哪里,答案鲜明是在APIView中

.finalize_response(self,request,response,* args,** kwargs)

确定保证从处理程序方法重回的其他Response对象将被渲染为content
negotiation分明的不易内容类型。
平常不必要覆盖此格局。

“””usernames=[user.usernameforuserinUser.objects.all()]returnResponse(usernames)

  

Function Based Views

REST框架还允许你利用基于函数的例行视图。
它提供了1组大致的装饰器,用于包装基于函数的视图,以担保它们收到到Request(而不是平凡的Django
HttpRequest)的实例,并允许它们重返一个Response(而不是Django
HttpResponse),并同意你安插请求什么被处理。

API policy
attributes

澳门葡京备用网址 23

@api_view()

Signature: @api_view(http_method_names=[‘GET’],
exclude_from_schema=False)
这一个效应的中心是api_view装饰器,它富含你的视图应该响应的HTTP方法的列表。
例如,那是您什么编写3个极度轻便的视图,只需手动再次回到一些数量:

from rest_framework.decorators import api_view

@api_view()
def hello_world(request):
    return Response({"message": "Hello, world!"})

此视图将选用settings中钦点的暗中同意渲染器,解析器,验证类等。

默许情状下只接受GET方法。 别的情势将以“405 Method Not Allowed”作为响应。
要退换此行为,请内定视图允许的法子,如下所示:

@api_view(['GET', 'POST'])
def hello_world(request):
    if request.method == 'POST':
        return Response({"message": "Got some data!", "data": request.data})
    return Response({"message": "Hello, world!"})

你仍是能够使用exclude_from_schema参数将API视图标识为从其余auto-generated
schema中省略:

@api_view(['GET'], exclude_from_schema=True)
def api_docs(request):
    ...

The following attributes control the pluggable aspects of API views.

 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)
     ## request = Request(.....)
        self.request = request
        self.headers = self.default_response_headers  

        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

API policy decorators

要覆盖暗中同意settings,REST框架提供了1组能够增进到你的视图中的其余装饰器。
那些必须在(以下)@api_view装饰器之后。 例如,要创制1个应用
throttle
确认保障每一日只可以由特定用户调用一回的视图,请使用@throttle_classes装饰器,传递throttle类列表:

from rest_framework.decorators import api_view, throttle_classes
from rest_framework.throttling import UserRateThrottle

class OncePerDayUserThrottle(UserRateThrottle):
        rate = '1/day'

@api_view(['GET'])
@throttle_classes([OncePerDayUserThrottle])
def view(request):
    return Response({"message": "Hello for today! See you tomorrow!"})

那么些装饰器对应于地点描述的APIView子类上安装的性质。
可用的装饰有:

  • @renderer_classes(…)
  • @parser_classes(…)
  • @authentication_classes(…)
  • @throttle_classes(…)
  • @permission_classes(…)

这么些装饰器中的每贰个都采取三个参数,它必须是列表或元组成分。

下列属性决定API视图的可插入方面。

澳门葡京备用网址 24

.renderer_classes

 

.parser_classes

    所有的关键点都在dispatch方法里面:

.authentication_classes

    (1)  request = self.initialize_request(request, *args,
**kwargs) 

.throttle_classes

      

.permission_classes

澳门葡京备用网址 25

.content_negotiation_class

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(),    #[BasicAuthentication(),],把对象封装到request里面了
       negotiator=self.get_content_negotiator(), parser_context=parser_context )

API policy instantiation
methods

 

澳门葡京备用网址,The following methods are used by REST framework to instantiate the
various pluggable API policies. You won’t typically need to override
these methods.

    (2) self.initial(request, *args, **kwargs)

.get_renderers(self)

    

.get_parsers(self)

 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)

.get_authenticators(self)

 

.get_throttles(self)

    (3)self.check_permissions(request) 

.get_permissions(self)

 def check_permissions(self, request):
        """
        Check if the request should be permitted.
        Raises an appropriate exception if the request is not permitted.
        """
        for permission in self.get_permissions():
            if not permission.has_permission(request, self):
                self.permission_denied(
                    request, message=getattr(permission, 'message', None)
                )

.get_content_negotiator(self)

 

.get_exception_handler(self)

    (4)self.get_permissions():

API policy implementation
methods

    def get_permissions(self):
        """
        Instantiates and returns the list of permissions that this view requires.
        """
        return [permission() for permission in self.permission_classes]  列表生成式,把自定义的权限类的对象,放在一个对象中

The following methods are called before dispatching to the handler
method.

 

在散发给处理程序方法此前调用以下方法。

    (5)self.permission_classes

.check_permissions(self,
request)

    澳门葡京备用网址 26

.check_throttles(self,
request)

    那里默许去settings全局中去找,假如局地配置了静态变量,就径直去找局部的静态变量

.perform_content_negotiation(self, request,
force=False)

     (陆)在探视大家后续的BasePermission

Dispatch
methods

class BasePermission(object):
    """
    A base class from which all permission classes should inherit.
    """

    def has_permission(self, request, view):
        """
        Return `True` if permission is granted, `False` otherwise.
        """
        return True

    def has_object_permission(self, request, view, obj):
        """
        Return `True` if permission is granted, `False` otherwise.
        """
        return True

The following methods are called directly by the
view’s.dispatch()method. These perform any actions that need to occur
before or after calling the handler methods such
as.get(),.post(),put(),patch()and.delete().

 

以下的形式是由视图中一直调用。dispatch()方法。那些实施此外操作,供给发出从前或调用处理办法之后,例如.get(),.post(),put(),patch()

 暗中同意是未有别的逻辑剖断的,所以我们在自定义权限类的时候,得投机写那七个主意。

.initial(self, request, *args,
**kwargs)

 其余说喜宝(Hipp)下底下这一个作案的功效  

Performs any actions that need to occur before the handler method gets
called. This method is used to enforce permissions and throttling, and
perform content negotiation.

def has_object_permission(self, request, view, obj):
        """
        Return `True` if permission is granted, `False` otherwise.
        """
        return True

在拍卖方法调用以前实行其余索要发出的操作。此办法用于强制权限和节流,并实践内容协商。

 对现阶段登入用户做些判断

You won’t typically need to override this method.

def has_object_permission(self, request, view, obj):
    """
    判断当前评论用户的作者是不是你当前的用户
    只有评论的作者才能删除自己的评论
    """
      print('这是在自定义权限类中的has_object_permission')
      print(obj.id)
      if request.method in ['PUT', 'DELETE']:
          if obj.user == request.user:
            # 当前要删除的评论的作者就是当前登陆的用户
              return True
          else:
              return False
      else:
          return True

.handle_exception(self,
exc)

 

Any exception thrown by the handler method will be passed to this
method, which either returns aResponseinstance, or re-raises the
exception.

 

拍卖方法抛出的别的非常都将传递给该办法,该办法重返响应实例,或重复掀起那么些。

总结:

The default implementation handles any subclass
ofrest_framework.exceptions.APIException, as well as
Django’sHttp404andPermissionDeniedexceptions, and returns an appropriate
error response.

(1)使用

暗许的达成拍卖的其余子类rest_framework.exceptions.apiexception,像Django的Http40四和PermissionDenied例外,并再次来到适当的不当响应。

  • 和谐写的权限类:一.务必再而三BasePermission类; 
    贰.务必兑现:has_permission方法

If you need to customize the error responses your API returns you should
subclass this method.

(2)返回值

若是须求自定义API重返的失实响应,则应将该形式的子类化为子类。

  • True   有权访问
  • False  无权访问

.initialize_request(self, request, *args,
**kwargs)

(3)局部

Ensures that the request object that is passed to the handler method is
an instance ofRequest, rather than the usual DjangoHttpRequest.

  • permission_classes = [MyPremission,] 

保障传递给处理程序方法的央求对象是请求的二个实例,而不是惯常的HttpRequest。

 (4)全局

You won’t typically need to override this method.

REST_FRAMEWORK = {
   #权限
    "DEFAULT_PERMISSION_CLASSES":['API.utils.permission.SVIPPremission'],
}

.finalize_response(self, request, response, *args,
**kwargs)

 

Ensures that anyResponseobject returned from the handler method will be
rendered into the correct content type, as determined by the content
negotiation.

管教从处理程序方法重回的此外响应对象将被突显为科学的剧情类型,由内容协商分明。

You won’t typically need to override this method.

Function Based
Views

Saying [that class-based views] is always the superior solution is a
mistake.

—Nick
Coghlan

REST framework also allows you to work with regular function based
views. It provides a set of simple decorators that wrap your function
based views to ensure they receive an instance ofRequest(rather than the
usual DjangoHttpRequest) and allows them to return aResponse(instead of
a DjangoHttpResponse), and allow you to configure how the request is
processed.

REST框架允许你使用基于正则函数的视图。它提供了壹套简单的装裱,把您的意义观确定保证他们接受请求的实例(而不是平凡的Django
HttpRequest)并同意她们回去响应(而不是贰个Django
HttpResponse),并允许你安插如何处理请求。

@api_view()

Signature:@api_view(http_method_names=[‘GET’],
exclude_from_schema=False)

The core of this functionality is theapi_viewdecorator, which takes a
list of HTTP methods that your view should respond to. For example, this
is how you would write a very simple view that just manually returns
some data:

此意义的主旨是api_view装饰,以多个列表的HTTP方法视图应该应对。例如,您将怎么样编写二个卓殊轻便的视图,该视图只手动重回壹些数据:

fromrest_framework.decoratorsimportapi_view@api_view()defhello_world(request):returnResponse({“message”:”Hello,
world!”})

This view will use the default renderers, parsers, authentication
classes etc specified in
thesettings.

那种视图将使用暗中认可的renderers, parsers, authentication等类的安装钦赐

By default onlyGETmethods will be accepted. Other methods will respond
with “405 Method Not Allowed”. To alter this behaviour, specify which
methods the view allows, like so:

那种暗中认可只适用于GET方法,其余艺术将回来”40伍 Method Not
Allowed”,若要改换此表现,请内定视图允许的不2秘诀,例如:

@api_view([‘GET’,’POST’])defhello_world(request):ifrequest.method==’POST’:returnResponse({“message”:”Got
some data!”,”data”:request.data})returnResponse({“message”:”Hello,
world!”})

You can also mark an API view as being omitted from anyauto-generated
schema,
using theexclude_from_schemaargument.:

您也足以标识1个API视图是从任何自动生成的架构略,使用exclude_from_schema。

@api_view([‘GET’],exclude_from_schema=True)defapi_docs(request):…

API policy
decorators

To override the default settings, REST framework provides a set of
additional decorators which can be added to your views. These must
comeafter(below) the@api_viewdecorator. For example, to create a view
that uses
athrottleto
ensure it can only be called once per day by a particular user, use
the@throttle_classesdecorator, passing a list of throttle classes:

为了掩盖暗中认可设置,REST框架提供了1套额外的点缀能够被增多到你视图里。那几个必须经过@api_view装饰。例如,成立七个视图,使用油门确定保障它只好由特定用户每一日叁次,使用@throttle_classes装饰,通过节流阀类的列表:

fromrest_framework.decoratorsimportapi_view,throttle_classesfromrest_framework.throttlingimportUserRateThrottleclassOncePerDayUserThrottle(UserRateThrottle):rate=’1/day’@api_view([‘GET’])@throttle_classes([OncePerDayUserThrottle])defview(request):returnResponse({“message”:”Hello
for today! See you tomorrow!”})

These decorators correspond to the attributes set onAPIViewsubclasses,
described above.

The available decorators are:

@renderer_classes(…)

@parser_classes(…)

@authentication_classes(…)

@throttle_classes(…)

@permission_classes(…)

Each of these decorators takes a single argument which must be a list or
tuple of classes.

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website