Django框架之drf:7、认证组件,权限组件,频率组件,过滤的多种用法,排序,分页,

时间:2023-02-07 22:11:01

一、认证组件

简介

​ 登录认证的限制

​ 认证组件是drf框架给我们提供的认证接口,它能够在请求进入视图函数/类前进验证(例如:认证用户是否登录),对不符合认证的请求进行拦截并返回校验失败的信息

1、认证组件使用步骤

模块地址:

from rest_framework.authentication import BaseAuthentication

用法简介:

# 1、创建一个专门用于认证的py文件,写一个类继承BaseAuthentication
# 2、重写authenticate方法,在方法内验证token
# 3、如果认证成功,返回两个值【返回None或两个值(当前登录的对象和token)】
# 4、认证不通过,抛异常AuthenticationFailed(异常信息)
# 5、局部使用和全局使用
	-局部使用:# 在需要使用认证的视图类下管理接口
        class BookDetailView(ViewSetMixin, RetrieveAPIView):
           authentication_classes = [LoginAuth] # 列表,可以添加多个
    
	-全局使用:# 在django的setting.py文件种添加配置
       		REST_FRAMEWORK = {
    	'DEFAULT_AUTHENTICATION_CLASSES':['app01.authenticate.LoginAuth']
				}
 
	-局部禁用:# 全局开启,局部禁用
    	class BookDetailView(ViewSetMixin, RetrieveAPIView):
            authentication_classes = [] 

2、代码用法

认证类代码:(authentica.py)

class LoginAuth(BaseAuthentication):
    # 在这里实现认证,如果是登录的,继续往后走返回两个值,如果不是抛异常
    def authenticate(self, request):
        # 请求中是否携带token,判断是否登录,放在地址栏中
        token = request.query_params.get('token', None)
        # 判断前端是否传入token
        if token:  
            # 去表中查找token
            user_token = UserToken.objects.filter(token=token).first()
            # 判断是否查到token
            if user_token:
                # 找到了返回两个值:登录的对象和token
                return user_token.user, token
            else:
                # 没有登录抛异常
                raise AuthenticationFailed('token认证失败')
        else:
            raise AuthenticationFailed('token没传')	

视图类代码

# 查询所有
class BookView(ViewSetMixin, ListAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # 控制认证的接口(列表,可以在认证的py文件下编写多个认证)
    authentication_classes = [LoginAuth]  # 局部认证

路由代码

from django.urls import path, include
from app01 import views

# 第一步:导入模块
from rest_framework.routers import SimpleRouter

# 第二步:实例化对象
router = SimpleRouter()

# 第三步:注册路由
router.register('books', views.BookView, 'books')

urlpatterns = [
    path('', include(router.urls))
]

Django框架之drf:7、认证组件,权限组件,频率组件,过滤的多种用法,排序,分页,

Django框架之drf:7、认证组件,权限组件,频率组件,过滤的多种用法,排序,分页,

二、权限组件

简介:

​ 在我们使用的一些app或者网页中(爱奇艺,腾讯视频),都会有一些会员接口(需要购买会员才能够使用或者观看),权限组件就是对用户的这一权限进行验证,在请求进入视图类/函数代码前进行校验,校验失败后直接将请求拦截,并返回校验失败的信息

1、权限组件的使用步骤

模块地址:

from rest_framework.permissions import BasePermission

用法简介:

# 1、创建一个专门用于编写权限组件的py文件,写一个权限类,继承BasePermission
# 2、重写has_permission方法(在该方法在中实现权限认证,在这方法中,request.user就是当前登录用户)
# 3、如果有权限,返回True
# 4、没有权限,返回False(定制返回的中文: self.message='中文')
# 5、局部使用和全局使用
	-局部使用: # 在某个视图类中设置接口(不会影响别的视图类)
        class BookDetailView(ViewSetMixin, RetrieveAPIView):
            permission_classes = [CommonPermission]

	-全局使用:  # django的settings.py中配置,影响全局
    	REST_FRAMEWORK = {
            'DEFAULT_PERMISSION_CLASSES': [
                'app01.permissions.CommonPermission',
            ],
        }
  
	-局部禁用:# 全局配置局部禁用
        class BookDetailView(ViewSetMixin, RetrieveAPIView):
            permission_classes = [] 

2、代码用法

权限类代码(perssion.py)

# 写权限类,写一个类,继承基类BasePermission,重写has_permission方法,在方法中实现权限认证,如果有权限return True ,如果没有权限,返回False
from rest_framework.permissions import BasePermission


class CommonPermission(BasePermission):
    def has_permission(self, request, view):
        # 实现权限的控制  ---》知道当前登录用户是谁?当前登录用户是  request.user
        if request.user.user_type == 1:
            return True
        else:
            # 没有权限,向对象中放一个属性 message
            # 如果表模型中,使用了choice,就可以通过  get_字段名_display()  拿到choice对应的中文
            self.message = '您是【%s】,您没有权限' % request.user.get_user_type_display()
            return False

视图类代码:

class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # 局部认证
    authentication_classes = [LoginAuth]
    # 权限认证(将编写的频率类导入过来)
    permission_classes = [CommentPermission]

Django框架之drf:7、认证组件,权限组件,频率组件,过滤的多种用法,排序,分页,

三、频率

简介:

​ 频率是指,控制某个接口访问频率(次数)

1、频率组件的使用步骤

模块地址:

from rest_framework.throttling import BaseThrottle, SimpleRateThrottle
# BaseThrottle:需要手动编写的代码较多
# SimpleRateThrottle: 需要手动编写的代码较少(用这个)

用法简介

# 1、创建一个专门用来编写频率组件的py文件,写一个频率类,继承SimpleRateThrottle
# 2、重写get_cache_key方法,返回什么,就以什么做限制----》ip(用户id做限制)
# 3、配置一个类属性scope = 'book_5_m'
# 4、在django的配置文件中编写频率次数
	REST_FRAMEWORK = {
          'DEFAULT_THROTTLE_RATES': {
            'book_5_m': '5/m',  # 一分钟五次 
        },
    	}
# 5、局部使用和全局使用
	-局部使用: # 只影响当前的视图类
    class BookView(ModelViewSet):
        throttle_classes = [CommentThrottle]
     
    -全局配置:影响全局
    	REST_FRAMEWORK = {
             'DEFAULT_THROTTLE_CLASSES': ['app01.throttling.CommonThrottle'],

        }
     
    -局部禁用:
      class BookView(ModelViewSet):
         throttle_classes = [CommentThrottle]

2、代码用法

频率类代码(throttle.py)

from rest_framework.throttling import BaseThrottle, SimpleRateThrottle


class CommentThrottle(SimpleRateThrottle):
    # 创建一个用于控制频率的变量名(需要传入配置文件)
    scope = 'book_5_m'

    def get_cache_key(self, request, view):
        # 返回什么就以什么做限制(request.META.get('REMOTE_ADDR')以IP做限制)
        return request.META.get('REMOTE_ADDR')

视图类代码

class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # 频率组件
    throttle_classes = [CommentThrottle]

django配置文件

REST_FRAMEWORK = {
    # 控制访问频率
    'DEFAULT_THROTTLE_RATES': {
        'book_5_m': '5/m',  # 一分钟五次
    },
}

Django框架之drf:7、认证组件,权限组件,频率组件,过滤的多种用法,排序,分页,

四、过滤的多种用法

简介:

​ 过滤是指在使用查询的时候,我们可以通过条件来过滤掉不需要的内容(例如:使用淘宝购物时,购买某种物品,过滤掉价格低于100元的商品)

# restful规范中,要求了,请求地址中带过滤条件
	-5个接口中,只有一个接口需要有过滤和排序,查询所有接口

1、继承APIView自己写

class BookView(APIView):
    def get(self,request):
        # 获取get请求携带的参数
        name=request.query_params.get('name')
        # 通过filter进行过滤
        books = Book.objects.filter(name=name)

2、使用drf的内置过滤(继承GenericAPIview)

模块地址:

-该方法为模糊查询

from rest_framework.filters import SearchFilter

代码用法:

class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # 实例化过滤对象
    filter_backends = [SearchFilter]
    # 指定过滤的字段(模糊查询)
    search_fields = ['name', 'price']

搜索方式:

# name或price中只要有关键字就会搜出来 (只能用search=xxx的方式)
	http://127.0.0.1:8000/api/v1/books/?search=西游记

Django框架之drf:7、认证组件,权限组件,频率组件,过滤的多种用法,排序,分页,

3、使用第三方插件过滤(精准过滤)

第三方插件:

# 插件名称:
	django-filter
    
# 安装插件:
	pip3.8 install django-filter

模块地址:

from django_filters.rest_framework import DjangoFilterBackend

代码用法:

from rest_framework.viewsets import ModelViewSet
from .models import Book
from .serializer import BookSerializer
from django_filters.rest_framework import DjangoFilterBackend


class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    # 第三方过滤插件
    filter_backends = [DjangoFilterBackend]
    # 查询的字段
    filterset_fields = ['pk','name', 'price']

搜索方式:

http://127.0.0.1:8000/api/books/?price=99
http://127.0.0.1:8000/api/books/?price=99&name=呐喊

Django框架之drf:7、认证组件,权限组件,频率组件,过滤的多种用法,排序,分页,

4、使用过滤组件

4、1.定制过滤组件的使用方式与步骤

模块地址:

from rest_framework.filters import BaseFilterBackend

用法简介:

# 1、创建一个专门用于过滤的py文件,写一个类继承BaseFilterBackend
# 2、重写filter_queryset方法,在方法内部进行过滤
# 3、直接返回过滤后的对象
# 4、如果没有过滤直接返回所有数据
# 5、局部使用
	 -局部使用:
    class BookView(ViewSetMixin, ListAPIView):
        queryset = Book.objects.all()
        serializer_class = BookSerializer
        # 在类表内填写过滤的类
        filter_backends = [CommonFilter]  # 可以定制多个,从左往右,依次执行

4、2.代码用法

过滤类代码(filters.py)

from rest_framework.filters import BaseFilterBackend


class CommonFilter(BaseFilterBackend):
    # 重写的类,编写过滤吧的内容
    def filter_queryset(self, request, queryset, view):
        # 获取过滤的条件
        filter_comment = request.query_params.get('price_gt', None)
        # 判断前端是否传入过滤条件
        if filter_comment:
            # 根据条件进行赛选内容
            books_queryset_filter = queryset.filter(price__gt=100)
            # 返回过滤后的数据
            return books_queryset_filter
        return queryset

视图类代码

class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    # 第三方过滤插件
    filter_backends = [CommonFilter]

五、排序

1、用法简介

用法简介:

排序需要和自定义过滤继承同一个父类,需要将排序的对象填入在过滤的列表内,并且放在其他参数的前方

模块地址:

from rest_framework.filters import OrderingFilter

2、代码用法

视图类代码

from rest_framework.viewsets import ModelViewSet
from .models import Book
from .serializer import BookSerializer
from django_filters.rest_framework import DjangoFilterBackend
from .filters import CommonFilter
from rest_framework.filters import OrderingFilter


class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    # 第三方过滤插件(OrderingFilter放在其他过滤参数前)
    filter_backends = [OrderingFilter, DjangoFilterBackend, CommonFilter]
    # 查询的字段
    filterset_fields = ['id', 'name', 'price']
    # 指定排序的字段(-是降序,默认升序)
    ordering_fields = ['price']

搜索用法

# 默认升序
    http://127.0.0.1:8000/api/books/?price_gt=60&ordering=price
    
# 降序
	http://127.0.0.1:8000/api/books/?price_gt=60&ordering=-price

六、分页

1、用法简介

  • 只有查询所有接口才能到用到分页
  • drf内置了三个分页器,分别应对三种分页方式
  • 内置的分页类不能直接使用,需要继承,定制一些参数后才能使用

2、三种分页器的用法

模块地址:

​ 三种分页器在同一个父类中

from rest_framework.pagination import PageNumberPagination, CursorPagination, LimitOffsetPagination

视图类代码:

class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # 指定分页器
    pagination_class = ‘指定使用的分分页器’(需要导入分页器类)

2、1.自定义分页器

from rest_framework.pagination import PageNumberPagination, CursorPagination, LimitOffsetPagination


# 第一种:通常用于web端(常规分页器)
class CommonPageNumberPagination(PageNumberPagination):
    # 每页显示2条
    page_size = 2
    # page=10  查询第10页的数据,每页显示2条
    page_query_param = 'page'
    # page=10&size=5    查询第10页,每页显示5条
    page_size_query_param = 'size'
    # 每页最大显示10条
    max_page_size = 5


# 第二种:可以控制每页显示的数量(偏移分页,用的较少)
class CommonLimitOffsetPagination(CursorPagination):
    # 每页显示2条
    default_limit = 3
    # limit=3   取3条
    limit_query_param = 'limit'
    # offset=1  从第一个位置开始,取limit条
    offset_query_param = 'offset'
    # 最大显示数
    max_limit = 5


# 第三种:游标分页器(app常用,拉到哪里显示多少数据)
class CommonCursorPagination(CursorPagination):
    # 查询参数(可以随便写,需要在前端路由对上)
    cursor_query_param = 'p'
    # 每页多少条
    page_size = 2
    # 排序的字段
    ordering = 'id'

前端对应搜索方式:

#基本分页方式(基本是这种,网页端):
	http://127.0.0.1:8000/api/v1/books/?page=2&size=3
    

# 偏移分页 :从第一条开始,取4条
	http://127.0.0.1:8000/api/v1/books/?limit=4&offset=1

# 游标分页:
	http://127.0.0.1:8000/api/books/?p=cD0x