1、认证

1.1 认证类的构建

新建一个自定义类,该类继承rest_framework.authentication中的BaseAuthentication 类,重写其中的authenticate 方法。将需要的认证逻辑写在里面。当认证通过是需要返回两个值,其中一个值最终给了Requestuser 。认证失败时,抛出异常:APIException或者AuthenticationFailed 。其中该方法必须重写,如不重写其中没有认证逻辑,则直接抛出异常。

为方便管理,认证类写在新建的.py文件中。

from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed

from app01 import models	# 自定义模型


class MyAuthentication(BaseAuthentication):
    def authenticate(self, request):
        # 从META中取出请求中带的登录接口返回给前端的token
        token = request.META.get('HTTP_TOKEN')
        if token:
            user_token = models.Token.objects.filter(Token=token).first()
            if user_token:
                return user_token.user, token
            else:
                raise AuthenticationFailed('认证失败')
        else:
            raise AuthenticationFailed('需要认证')

1.2 认证类的使用

  • 全局使用:

    在settings.py 中的REST_FRAMEWORK中添加DEFAULT_AUTHENTICATION_CLASSES 。如下所示:

REST_FRAMEWORK={
    "DEFAULT_AUTHENTICATION_CLASSES":["app01.user_auth.MyAuthentication",] #可以有多个
}
  • 局部使用:

    在需要进行认证的视图类中添加authentication_classes 。如下所示:

class BookAPIView(ModelViewSet):
    authentication_classes = [MyAuthentication, ]  
    '''
    可以是元组也可以是列表,里面可以有多个值,当有多个值的时候,从左到右依次认证。其中第一个认证不能有两个返回值,否则只能进行第一个认证。有多个认证时,需要将返回值为两个的放到最后
    '''
    queryset = models.Book.objects.all()
    serializer_class = BookModelSerializer
  • 局部禁用:

    在需要禁用认证的视图类中,将authentication_classes 设置为空。如下所示:

    class LoginView(APIView):
        authentication_classes = ()  
        def post(self, request):
           ...
    

2 权限

2.1 权限类的构建

新建一个类,继承rest_framework.permissions中的BasePermission,并重写其中的has_permission方法,其中是验证权限的逻辑。如果验证通过则return True,如果验证失败则返回False。

示例:

from rest_framework.permissions import BasePermission

class UserPermission(BasePermission):
    def  has_permission(self, request, view):
        '''
        在进行权限验证之前,drf会首先对请求进行认证操作,当其认证通过时之后才会进行权限认证。此时request中已经包含了登录用户的信息,我们可以将其取出进行权限验证。
        '''
        user=request.user  # 当前登录用户
        if user.user_type==1:
            return True
        else:
            return False

2.2 权限类的使用

同认证类相似,权限类也有全局使用,局部使用和局部禁用。

其中全局使用的配置是:

REST_FRAMEWORK={
    "DEFAULT_AUTHENTICATION_CLASSES":["app01.app_auth.MyAuthentication",],
    'DEFAULT_PERMISSION_CLASSES': [
        'app01.app_auth.UserPermission',
    ],
}

局部使用则是在相应的视图类中添加 permission_classes 属性。比如:

class TestView(APIView):
	permission_classes = [app_auth.UserPermission,]
    pass

将视图类中的permission_classes 设置为空即可在全局配置了权限的情况下实现,权限的局部禁用。

2.3 drf内置的权限类

drf为我们内置了几个权限类,当我们的的需求类似时,可以直接使用其内置的权限类,避免代码冗余。这几个权限类依次是

  • IsAdminUser 校验Django自带用户表中的is_staff字段,判断认证用户是否是管理员(注意:其判断的不是is_superuser字段,而是is_staff,即该用户是职员状态是就可以通过权限认证)。
  • IsAuthenticated 所有通过认证的请求都可以通过权限验证,都会返回True。
  • IsAuthenticatedOrReadOnly 当请求通过认证或者请求是'GET', 'HEAD', 'OPTIONS'方式时,可以通过权限验证。
  • AllowAny 所有请求都可以通过权限校验,当你没有配置权限类的时候就会默认使用AllowAny 。

权限的校验依靠于认证类返回的结果,所以我们使用时必须要搭配相应的认证类使用。

3 频率

3.1 频率类的构建

新建一个频率类。继承rest_framework.throttling中的SimpleRateThrottle,重写get_cache_key 方法。其中可以取出请求中的ip,user,设备信息等,将选用的频率限制标准返回即可。即返回ip即按照ip限制访问频率,返回用户名或用户对象即根据用户进行限制。

示例:

from rest_framework.throttling import SimpleRateThrottle
class MyThrottle(SimpleRateThrottle):
    scope='ip' 
    '''
    其中scope属性为配置中访问频率设置的关键字,必须在频率类中对该属性进行赋值,且与sttings中要一一对应。
    '''
    def get_cache_key(self, request, view):
        return request.META.get('REMOTE_ADDR')

3.2 频率类的使用

  • 全局使用

    REST_FRAMEWORK={
        'DEFAULT_THROTTLE_CLASSES': (
            'utils.throttling.MyThrottle',
        ),
        'DEFAULT_THROTTLE_RATES': {
            'ip': '3/m'  # key要跟类中的scop对应 格式可为'3/m','3/h','3/d'等
        },
         'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
    }
    
  • 局部使用:在相应的类中添加throttle_classes 属性即可。示例:

    class TestView(APIView):
    	throttle_classes = [MyThrottle,]
        pass
    
  • 将视图类中的throttle_classes 设置为空即可在全局配置了频率限制的情况下实现,频率限制的局部禁用。

3.3 df内置的频率限制类

drf为我们内置了几个权限类,依次为:

  • UserRateThrottle :对登录用户进行频率限制。如果登录用户经过了认证,则限制的依据是该用户的user_id,否则就是该请求的ip地址。setting中的scope为user
  • AnonRateThrottle :对未登录用户进行频率限制,限制依据是用户请求中的ip地址,setting中的scope为anon

4 过滤与排序

4.1 过滤

  1. 安装第三方插件:pip3 install django-filter

  2. 在Django中注册app

  3. 全局配置或者局部配置。

    示例:

    REST_FRAMEWORK={
         'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
    }
    
    class BookView(ListAPIView):
        ...
        filter_fields = ('name',)  #配置可以按照哪个字段来过滤
    

4.2 排序

示例:

# 视图
from rest_framework.filters import OrderingFilter

class BooksView(ListAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    filter_backends = [OrderingFilter]
    ordering_fields = ('id', 'price')
    
# urls.py
path('books/', views.BooksView.as_view()),

# 使用
http://127.0.0.1:8000/books/?ordering=-price
http://127.0.0.1:8000/books/?ordering=price
http://127.0.0.1:8000/books/?ordering=-id

Author:Laoqi