【django2.0之Rest_Framework框架三】rest_framework认证,权限,限流,过滤,排序,分页,异常处理,生成文档介绍

本文主要是介绍【django2.0之Rest_Framework框架三】rest_framework认证,权限,限流,过滤,排序,分页,异常处理,生成文档介绍,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 认证Authentication

  1. 全局配置
    可以在配置文件中配置全局默认的认证方案。
from rest_framework import settings# 在settings配置文件中,我们可以进行下面的配置来覆盖默认配置
REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': (#哪个写在前面,优先使用哪个认证'rest_framework.authentication.SessionAuthentication',  # session认证,admin后台其实就使用的session认证,其实接口开发很少用到session认证,所以我们通过配置可以改为其他认证,比如后面项目里面我们用到jwt,JSON WEB TOKEN认证,或者一些配合redis的认证'rest_framework.authentication.BasicAuthentication',   # 基本认证,工作当中可能一些测试人员会参与的话,他们会将一些认证数据保存在内存当中,然后验证的,我们基本上用不上)
}
  1. 局部使用
    也可以在每个视图中通过设置authentication_classess属性来设置,比如说我们很多接口的数据都是可以让别人获取数据的,但是有可能有些接口是调用给别人网站的,有可能到时候我们就需要一些单独的认证了
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.views import APIViewclass ExampleView(APIView):# 类属性authentication_classes = [SessionAuthentication, BasicAuthentication] #也可以写成元祖形式的,到时候我们使用我们自己开发的认证组件的时候,就需要自己写一个认证组件类,然后写在列表中来使用...

认证失败会有两种可能的返回值:

  • 401 Unauthorized 未认证
  • 403 Permission Denied 权限被禁止

自定义认证组件

## 写一个认证类 students/utils/app_auth.py
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from students.models import UserToken
class MyAuthentication(BaseAuthentication):def authenticate(self, request):# 认证逻辑,如果认证通过,返回两个值#如果认证失败,抛出AuthenticationFailed异常token=request.GET.get('token')if  token:user_token=UserToken.objects.filter(token=token).first()# 认证通过if user_token:return user_token.user,tokenelse:raise AuthenticationFailed('认证失败')else:raise AuthenticationFailed('请求地址中需要携带token')# 可以有多个认证,从左到右依次执行
# 全局使用,在setting.py中配置
REST_FRAMEWORK={"DEFAULT_AUTHENTICATION_CLASSES":["students.utils.app_auth.MyAuthentication",]
}
# 局部使用,在视图类上写
## views.py
from students.utils.app_auth import MyAuthentication
class StudentView(APIView):authentication_classes = [MyAuthentication, ]def get(self,request):print(request.user)  # 用户名print(request.auth)  # tokenreturn Response({'msg':'ok'})
# 局部禁用
authentication_classes=[]

2. 权限Permissions

权限控制可以限制用户对于视图的访问和对于具体数据对象的访问。

  • 在执行视图的dispatch()方法前,会先进行视图访问权限的判断
  • 在通过get_object()获取具体对象时,会进行模型对象访问权限的判断
  1. 全局使用
    可以在配置文件中全局设置默认的权限管理类,如
REST_FRAMEWORK = {....'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAuthenticated', #登录状态下才能访问我们的接口,可以通过退出admin后台之后,你看一下还能不能访问我们正常的接口就看到效果了)
}

如果未指明,则采用如下默认配置

from rest_framework import permissions
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.AllowAny', #表示任何人都可以进行任何的操作,没做限制
)
  1. 局部使用
    也可以在具体的视图中通过permission_classes属性来设置,如
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIViewclass ExampleView(APIView):permission_classes = (IsAuthenticated,)...

内置提供的权限

  • AllowAny 允许所有用户
  • IsAuthenticated 仅通过认证的用户

自定义权限的使用

如需自定义权限,需继承rest_framework.permissions.BasePermission父类,并重写has_permission(self, request, view) 方法表示是否可以访问视图, view表示当前视图对象。如果权限通过,就返回True,不通过就返回False

## utils/permissions.py
from rest_framework.permissions import BasePermissionclass UserPermission(BasePermission):def  has_permission(self, request, view):# 不是超级用户,不能访问# 由于认证已经过了,request内就有user对象了,当前登录用户user=request.user  # 当前登录用户# 如果该字段用了choice,通过get_字段名_display()就能取出choice后面的中文print(user.get_user_type_display())if user.user_type==1:return Trueelse:return False# 局部使用
## views.py
class TestView(APIView):permission_classes = [permissions.UserPermission]def get(self,request):return Response({'msg':'ok'})
# 全局使用
REST_FRAMEWORK={"DEFAULT_AUTHENTICATION_CLASSES":["app01.app_auth.MyAuthentication",],'DEFAULT_PERMISSION_CLASSES': ['app01.app_auth.UserPermission',],
}
# 局部禁用
class TestView(APIView):permission_classes = []

3. 限流Throttling

可以对接口访问的频次进行限制,以减轻服务器压力。
一般用于付费购买次数,投票等场景使用.

  1. 全局使用
    可以在配置文件中,使用DEFAULT_THROTTLE_CLASSESDEFAULT_THROTTLE_RATES进行全局配置
REST_FRAMEWORK = {'DEFAULT_THROTTLE_CLASSES': ('rest_framework.throttling.AnonRateThrottle', # 匿名用户,未登录的'rest_framework.throttling.UserRateThrottle'  # 经过登录之后的用户),'DEFAULT_THROTTLE_RATES': {'anon': '100/day','user': '1000/day'}
}

DEFAULT_THROTTLE_RATES 可以使用 second, minute, hourday来指明周期。

源码:
{'s': 1, 'm': 60, 'h': 3600, 'd': 86400} m表示分钟,可以写m,也可以写minute
  1. 局部使用
    也可以在具体视图中通过throttle_classess属性来配置
from rest_framework.throttling import UserRateThrottle
from rest_framework.views import APIViewclass ExampleView(APIView):throttle_classes = (UserRateThrottle,)...

内置频率组件源码

from rest_framework.throttling import BaseThrottle,SimpleRateThrottle
import time
from rest_framework import exceptions
visit_record = {}
class VisitThrottle(BaseThrottle):# 限制访问时间VISIT_TIME = 10VISIT_COUNT = 3# 定义方法 方法名和参数不能变def allow_request(self, request, view):# 获取登录主机的idid = request.META.get('REMOTE_ADDR')self.now = time.time()if id not in visit_record:visit_record[id] = []self.history = visit_record[id]# 限制访问时间while self.history and self.now - self.history[-1] > self.VISIT_TIME:self.history.pop()# 此时 history中只保存了最近10秒钟的访问记录if len(self.history) >= self.VISIT_COUNT:return Falseelse:self.history.insert(0, self.now)return Truedef wait(self):return self.history[-1] + self.VISIT_TIME - self.now

可选限流类

1) AnonRateThrottle
限制所有匿名未认证用户,使用IP区分用户。
使用DEFAULT_THROTTLE_RATES['anon'] 来设置频次

2)UserRateThrottle
限制认证用户,使用User id 来区分。
使用DEFAULT_THROTTLE_RATES['user'] 来设置频次

示例

全局配置中设置访问频率

	'DEFAULT_THROTTLE_CLASSES': ('rest_framework.throttling.AnonRateThrottle','rest_framework.throttling.UserRateThrottle'),'DEFAULT_THROTTLE_RATES': {'anon': '3/m','user': '10/m'}

4. 过滤Filtering

对于列表数据可能需要根据字段进行过滤,我们可以通过添加django-fitlter扩展来增强支持。

pip install django-filter

在配置文件中增加过滤后端的设置:

INSTALLED_APPS = [...'django_filters',  # 需要注册应用,
]
# 全局配置
REST_FRAMEWORK = {...'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}

在视图中添加filter_fields属性,指定可以过滤的字段

class StudentListView(ListAPIView):queryset = Student.objects.all()serializer_class = StudentSerializerfilter_fields = ('age', 'sex') # 配置可以按照哪个字段来过滤# 127.0.0.1:8000/stu/students/?sex=1

5. 排序Ordering

对于列表数据,REST framework提供了OrderingFilter过滤器来帮助我们快速指明数据按照指定字段进行排序。

使用方法:

在类视图中设置filter_backends,使用rest_framework.filters.OrderingFilter过滤器,REST framework会在请求的查询字符串参数中检查是否包含了ordering参数,如果包含了ordering参数,则按照ordering参数指明的排序字段对数据集进行排序。

前端可以传递的ordering参数的可选字段值需要在ordering_fields中指明。

示例:

from rest_framework.filters import OrderingFilter
class Students7View(ModelViewSet):queryset = models.Student.objects.all()  # 必须写这个参数 ,方法中使用的self.get_queryset()方法自动获取到queryset属性数据serializer_class = StudentModelSerializer  # 非必填属性,self.get_serializer获取到serializer_class制定的序列化器类filter_backends = (OrderingFilter,)ordering_fields = ('id', 'age')# students/?ordering=-id# 127.0.0.1:8000/books/?ordering=-age 
# 必须是ordering=某个值
# -id 表示针对id字段进行倒序排序
# id  表示针对id字段进行升序排序

如果需要在过滤以后再次进行排序,则需要两者结合!

from rest_framework.generics import ListAPIView
from students.models import Student
from .serializers import StudentModelSerializer
from django_filters.rest_framework import DjangoFilterBackend #需要使用一下它才能结合使用
class Student3ListView(ListAPIView):queryset = Student.objects.all()serializer_class = StudentModelSerializerfilter_fields = ('age', 'sex')# 因为filter_backends是局部过滤配置,局部配置会覆盖全局配置,所以需要重新把过滤组件核心类再次声明,# 否则过滤功能会失效filter_backends = [OrderingFilter,DjangoFilterBackend]ordering_fields = ('id', 'age')# 127.0.0.1:8000/books/?sex=1&ordering=-age 

6. 分页Pagination

REST framework提供了分页的支持。
我们可以在配置文件中设置全局的分页方式,如:

REST_FRAMEWORK = {# 全局分页,一旦设置了全局分页,那么我们drf中的视图扩展类里面的list方法提供的列表页都会产生分页的效果。所以一般不用全局分页'DEFAULT_PAGINATION_CLASS':  'rest_framework.pagination.PageNumberPagination','PAGE_SIZE': 100  # 每页最大数据量
}

也可通过自定义Pagination类,来为视图添加不同分页行为。在视图中通过pagination_class属性来指明。

class LargeResultsSetPagination(PageNumberPagination):page_size = 1000#127.0.0.1:8001/students/?page=5&page_size=10page_size_query_param = 'page_size'max_page_size = 10000
class BookDetailView(RetrieveAPIView):queryset = BookInfo.objects.all()serializer_class = BookInfoSerializerpagination_class = LargeResultsSetPagination# pagination_class = None

注意:如果在视图内关闭分页功能,只需在视图内设置

pagination_class = None

可选分页器

1) PageNumberPagination
前端访问地址形式:

GET  http://127.0.0.1:8000/students/?page=4

可以在子类中定义的属性:

  • page_size 每页数目
  • page_query_param 前端发送的页数关键字名,默认为"page"
  • page_size_query_param 前端发送的每页数目关键字名,默认为None
  • max_page_size 前端最多能设置的每页数量
# 声明分页的配置类
from rest_framework.pagination import PageNumberPagination
class StandardPageNumberPagination(PageNumberPagination):# 默认每一页显示的数据量page_size = 2# 允许客户端通过get参数来控制每一页的数据量page_size_query_param = "size"max_page_size = 10# 自定义页码的参数名page_query_param = "p"class StudentAPIView(ListAPIView):queryset = Student.objects.all()serializer_class = StudentModelSerializerpagination_class = StandardPageNumberPagination# 127.0.0.1/four/students/?p=1&size=5

2)LimitOffsetPagination(了解)

前端访问网址形式:其实就是通过偏移量来取数据

GET http://127.0.0.1/four/students/?limit=100&offset=400  #从下标为400的记录开始,取100条记录

可以在子类中定义的属性:

  • default_limit 默认限制,每页数据量大小,默认值与PAGE_SIZE设置一致
  • limit_query_param limit参数名,默认'limit' , 可以通过这个参数来改名字
  • offset_query_param offset参数名,默认'offset' ,可以通过这个参数来改名字
  • max_limit 最大limit限制,默认None, 无限制
from rest_framework.pagination import LimitOffsetPagination
class StandardLimitOffsetPagination(LimitOffsetPagination):# 默认每一页查询的数据量,类似上面的page_sizedefault_limit = 2limit_query_param = "size"offset_query_param = "start"class StudentAPIView(ListAPIView):queryset = Student.objects.all()serializer_class = StudentModelSerializer# 调用页码分页类# pagination_class = StandardPageNumberPagination# 调用查询偏移分页类pagination_class = StandardLimitOffsetPagination

7. 异常处理 Exceptions

看一个简单的示例

class APIError(Exception):passclass Student2APIView(APIView):def get(self,request,pk):try:instance = Student.objects.get(pk=pk)except Student.DoesNotExist:raise APIError('自定义API错误')return Response({"message":"访问的商品已经下架~"})serializer = StudentModelSerializer(instance=instance)return Response(serializer.data)

REST framework提供了异常处理,我们可以自定义异常处理函数。

可以创建一个utils文件夹,里面放一个exceptions.py文件,名字随便写,然后写下面的内容

from rest_framework.views import exception_handlerdef custom_exception_handler(exc, context): #自定义的错误处理函数"""exc错误对象context 异常发生时的一些上下文信息"""# 先调用REST framework默认的异常处理方法获得标准错误响应对象response = exception_handler(exc, context) #这个函数是drf提供的,它处理了一些错误,但是如果它处理不了的,它会返回None,所以,如果是None的话,我们需要自己来处理错误# 在此处补充自定义的异常处理if response is None:if isinstance(exc,APIError)#这里就可以记录错误信息了,一般记录到文件中,可以使用日志系统来进行记录# return Respose({'msg':'自定义API错误了'})response.data['status_code'] = response.status_codereturn response

在配置文件中还要声明自定义的异常处理

REST_FRAMEWORK = {'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'
}

如果未声明,会采用默认的方式,如下

## rest_frame/settings.py
REST_FRAMEWORK = {'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler'
}

例如:补充上处理关于数据库的异常

from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework import status
from django.db import DatabaseErrordef exception_handler(exc, context):response = drf_exception_handler(exc, context)if response is None:view = context['view'] #出错的方法或者函数名称if isinstance(exc, DatabaseError):print('[%s]: %s' % (view, exc))response = Response({'detail': '服务器内部错误'}, status=status.HTTP_507_INSUFFICIENT_STORAGE)return response

REST framework定义的异常

  • APIException 所有异常的父类
  • ParseError 解析错误
  • AuthenticationFailed 认证失败
  • NotAuthenticated 尚未认证
  • PermissionDenied 权限决绝
  • NotFound 未找到
  • MethodNotAllowed 请求方式不支持
  • NotAcceptable 要获取的数据格式不支持
  • Throttled 超过限流次数
  • ValidationError 校验失败

也就是说,上面列出来的异常不需要我们自行处理了,很多的没有在上面列出来的异常,就需要我们在自定义异常中自己处理了。

8. 自动生成接口文档

REST framework可以自动帮助我们生成接口文档。
接口文档以网页的方式呈现。
自动接口文档能生成的是继承自APIView及其子类的视图。
文档:https://www.kernel.org/doc/html/v4.12/core-api/index.html

8.1. 安装依赖

REST framewrok生成接口文档需要coreapi库的支持。

pip install coreapi

8.2. 设置接口文档访问路径

在总路由中添加接口文档路径。
文档路由对应的视图配置为rest_framework.documentation.include_docs_urls
参数title为接口文档网站的标题。

from rest_framework.documentation import include_docs_urlsurlpatterns = [...path('docs/', include_docs_urls(title='站点页面标题'))
]

如果报错了下面的错误,说明我们缺少一个依赖,配置一下就行了
'AutoSchema' object has no attribute 'get_link'
配置:

REST_FRAMEWORK = {...'DEFAULT_SCHEMA_CLASS': "rest_framework.schemas.AutoSchema",}

8.3. 文档描述说明的定义位置

1) 单一方法的视图,可直接使用类视图的文档字符串,如

class BookListView(generics.ListAPIView):"""get: 返回所有图书信息.post: 添加记录"""#注意,这是在类中声明的注释,如果在方法中你声明了其他注释,会覆盖这个注释的

2)包含多个方法的视图,在类视图的文档字符串中,分开方法定义,如

class BookListCreateView(generics.ListCreateAPIView):"""get:返回所有图书信息.post:新建图书."""

3)对于视图集ViewSet,仍在类视图的文档字符串中封开定义,但是应使用action名称区分,如

class BookInfoViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):"""list:返回图书列表数据retrieve:返回图书详情数据latest:返回最新的图书数据read:修改图书的阅读量"""

8.4. 访问接口文档网页

浏览器访问 127.0.0.1:8000/docs/,即可看到自动生成的接口文档。

两点说明:

1) 视图集ViewSet中的retrieve名称,在接口文档网站中叫做read
2)参数的Description需要在模型类或序列化器类的字段中以help_text选项定义,如:

class Student(models.Model):...age = models.IntegerField(default=0, verbose_name='年龄', help_text='年龄')...

或 注意,如果你多个应用使用同一个序列化器,可能会导致help_text的内容显示有些问题,小事情

class StudentSerializer(serializers.ModelSerializer):class Meta:model = Studentfields = "__all__"extra_kwargs = {'age': {'required': True,'help_text': '年龄'}}

这篇关于【django2.0之Rest_Framework框架三】rest_framework认证,权限,限流,过滤,排序,分页,异常处理,生成文档介绍的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/237024

相关文章

Python中win32包的安装及常见用途介绍

《Python中win32包的安装及常见用途介绍》在Windows环境下,PythonWin32模块通常随Python安装包一起安装,:本文主要介绍Python中win32包的安装及常见用途的相关... 目录前言主要组件安装方法常见用途1. 操作Windows注册表2. 操作Windows服务3. 窗口操作

Spring 框架之Springfox使用详解

《Spring框架之Springfox使用详解》Springfox是Spring框架的API文档工具,集成Swagger规范,自动生成文档并支持多语言/版本,模块化设计便于扩展,但存在版本兼容性、性... 目录核心功能工作原理模块化设计使用示例注意事项优缺点优点缺点总结适用场景建议总结Springfox 是

Golang如何用gorm实现分页的功能

《Golang如何用gorm实现分页的功能》:本文主要介绍Golang如何用gorm实现分页的功能方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录背景go库下载初始化数据【1】建表【2】插入数据【3】查看数据4、代码示例【1】gorm结构体定义【2】分页结构体

c++中的set容器介绍及操作大全

《c++中的set容器介绍及操作大全》:本文主要介绍c++中的set容器介绍及操作大全,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录​​一、核心特性​​️ ​​二、基本操作​​​​1. 初始化与赋值​​​​2. 增删查操作​​​​3. 遍历方

一文详解Java Stream的sorted自定义排序

《一文详解JavaStream的sorted自定义排序》Javastream中的sorted方法是用于对流中的元素进行排序的方法,它可以接受一个comparator参数,用于指定排序规则,sorte... 目录一、sorted 操作的基础原理二、自定义排序的实现方式1. Comparator 接口的 Lam

Python Pillow 库详解文档(最新推荐)

《PythonPillow库详解文档(最新推荐)》Pillow是Python中最流行的图像处理库,它是PythonImagingLibrary(PIL)的现代分支和继承者,本文给大家介绍Pytho... 目录python Pillow 库详解文档简介安装核心模块架构Image 模块 - 核心图像处理基本导入

HTML img标签和超链接标签详细介绍

《HTMLimg标签和超链接标签详细介绍》:本文主要介绍了HTML中img标签的使用,包括src属性(指定图片路径)、相对/绝对路径区别、alt替代文本、title提示、宽高控制及边框设置等,详细内容请阅读本文,希望能对你有所帮助... 目录img 标签src 属性alt 属性title 属性width/h

Python的端到端测试框架SeleniumBase使用解读

《Python的端到端测试框架SeleniumBase使用解读》:本文主要介绍Python的端到端测试框架SeleniumBase使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全... 目录SeleniumBase详细介绍及用法指南什么是 SeleniumBase?SeleniumBase

解决Entity Framework中自增主键的问题

《解决EntityFramework中自增主键的问题》:本文主要介绍解决EntityFramework中自增主键的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录Entity Framework中自增主键问题解决办法1解决办法2解决办法3总结Entity Fram

Spring Boot 实现 IP 限流的原理、实践与利弊解析

《SpringBoot实现IP限流的原理、实践与利弊解析》在SpringBoot中实现IP限流是一种简单而有效的方式来保障系统的稳定性和可用性,本文给大家介绍SpringBoot实现IP限... 目录一、引言二、IP 限流原理2.1 令牌桶算法2.2 漏桶算法三、使用场景3.1 防止恶意攻击3.2 控制资源