今天来总结一下学习的drf生成接口,支持哪些功能了?
总结一下:认证、限流、过滤查询、排序、分页
第一个就是认证了,就是没有登录的用户是无法访问该接口的,话不多说,上代码
认证
1:创建一个超级用户
python manage.py createsuperuser
2:登陆后台 http://127.0.0.1:8888/admin/,这里我用admin/123456做演示
3:再增加一个用户dong做演示
4:勾选管理员
5:开始写接口测试了
这里写2个接口进行测试
创建一个opt的app进行测试
python manage.py startapp opt
注册
引入配置和相关的类
修改rest_framework的默认配置
REST_FRAMEWORK ={
#配置认证方式
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication'
],
}
新建一个路由
from django.urls import path
from . import views
urlpatterns = [
]
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
#
router.register('test',views.ExampleAPIView,basename='auth')
urlpatterns += router.urls
提供的权限
- AllowAny 允许所有用户
- IsAuthenticated 仅通过登录认证的用户
- IsAdminUser 仅管理员用户
- IsAuthenticatedOrReadOnly 已经登陆认证的用户可以对数据进行增删改操作,没有登陆认证的只能查看数据。
默认/admin中的职员状态为true的时候会认为是管理员
建立对应的视图
from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from rest_framework.response import Response
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated, IsAdminUser, IsAuthenticatedOrReadOnly, AllowAny
# Create your views here.
'''
##### 提供的权限
- AllowAny 允许所有用户
- IsAuthenticated 仅通过登录认证的用户
- IsAdminUser 仅管理员用户
- IsAuthenticatedOrReadOnly 已经登陆认证的用户可以对数据进行增删改操作,没有登陆认证的只能查看数据。
默认/admin中的职员状态为true的时候会认为是管理员
'''
class ExampleAPIView(ViewSet):
# permission_classes = [IsAuthenticated,IsAdminUser]
permission_classes = [AllowAny]
# 认证组件的时候使用
# http://127.0.0.1:8888/opt/test/mall/
@action(methods=['get', 'post'], detail=False, url_path='mall')
def auth(self, request):
return Response('auth....')
# http://127.0.0.1:8888/opt/test/login/
@action(methods=['get', 'post'], detail=False, url_path='login')
def login(self, request):
return Response('login....')
看下效果
这里是AllowAny,所以所有用户都可以访问,当删除用户sessionId,然后更改权限试试
其他的就不演示了,反正同理。。。
如果想全局配置,那么就加上下面的代码就可以了,看自己的选择咯
#全局配置
#'DEFAULT_PERMISSION_CLASSES':(
#'rest_framework.permissions.IsAuthenticated', #仅通过登录认证的用户
#'rest_framework.permissions.IsAuthenticatedOrReadOnly', #已经登陆认证的用户可以对数据进行增删改操作,没有登陆认证的只能查看数据。
#'rest_framework.permissions.AllowAny',
#)
如果想自定义权限怎么办了?比如只允许dong这个用户访问这个接口,其他用户admin等都不能访问,如何实现了?
那么就该我们的自定义权限上场啦
1:先导入相应的包和权限BasePermission基类
from rest_framework.permissions import BasePermission
# 自定义权限 继承父类权限
class ConstumerPermission(BasePermission):
def has_permission(self, request, view):
if request.user and request.user.username == 'dong':
return True
# 自定义权限哦
class Example2APIView(ViewSet):
permission_classes = [ConstumerPermission]
# 认证组件的时候使用
# http://127.0.0.1:8888/opt/test2/auth/
@action(methods=['get', 'post'], detail=False, url_path="auth")
def auth(self, request):
return Response('ConstumerPermission....')
2:这里我们重写has_permission方法,然后在这里根据用户进行判断就可以了
如果返回True,表示真,只有这个用户才可以访问此接口
3:最后测试下
登陆后
限流
如何让一个接口,在一分钟或者一小时内控制访问的频率了,那么该使用限流就可以啦
建立一个单独的路由进行测试
router.register('test3',views.Example3APIView,basename='water')
视图类
# 限流
class Example3APIView(ViewSet):
@action(methods=['get'], detail=False, url_path="water")
def auth(self, request):
return Response('测试限流....')
启用限制类的配置
'DEFAULT_THROTTLE_CLASSES': ( # 启用的限制类
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
),
'DEFAULT_THROTTLE_RATES': { # 限制频率
'anon': '5/minute',
'user': '10/minute',
'python30':'30/minute'
},
这里的时间根据自己的需要进行配置
当我们不断f5刷新访问第10次的时候,就会出现这个效果
当初我们也可以自定义配置时间
用到了局部限流
# 局部限流
from rest_framework.throttling import UserRateThrottle, AnonRateThrottle, ScopedRateThrottle
class Example4APIView(ViewSet):
# throttle_classes = [UserRateThrottle,AnonRateThrottle]
throttle_classes = [UserRateThrottle, AnonRateThrottle]
throttle_scope = 'python30' # 自定义配置限制时间
@action(methods=['get'], detail=False, url_path="hot")
def auth(self, request):
return Response('测试局部限流....')
单独加个路由进行测试
router.register('test4',views.Example4APIView,basename='hot')
当我们刷新第30次的时候
过滤
如果我们想根据age进行查询该怎么实现了,别担心,马上见分晓,上代码
先写个路由单独测试
urlpatterns = [
path('test5/', views.Example5APIView.as_view({'get':'list'})),
]
导入相关的类
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import ListModelMixin
from students.models import Student
from students.sersizes import StudentModelSerializers
class Example5APIView(GenericViewSet,ListModelMixin):
# 重写内置queryset
queryset = Student.objects.all()
serializer_class = StudentModelSerializers
filter_fields = ('sex','age')
修改setting配置
# 全局配置,也可以使用局部配置 必须加上才能生效
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
然后就可以开心访问测试了 http://127.0.0.1:8888/opt/test5/?age=55
看到没,通过age我们就可以查询出对应的数据,这就是他为我们封装好的,我们只需要调用就可以实现了,是不是特别方便,有木有?
排序
接下来就是我们想根据id或者age进行排序
'''
过滤和排序组件是重叠的,
http://127.0.0.1:8888/opt/test6/?age=55&ordering=-id
'''
from rest_framework.filters import OrderingFilter #排序
from django_filters.rest_framework import DjangoFilterBackend #过滤类
class Example6APIView(GenericViewSet,ListModelMixin):
# 重写内置queryset
queryset = Student.objects.all()
serializer_class = StudentModelSerializers
#排序类 过滤类 重叠的 必须都加上才可以同时支持过滤和查询
filter_backends = [OrderingFilter,DjangoFilterBackend]
#进行ID倒序排序
# http://127.0.0.1:8888/opt/test6/?ordering=-id
#ordering=-id 负数为倒序 正数为正序
ordering_fields=['id','age'] #排序字段
filter_fields = ('sex', 'age') #过滤字段
PS:因为排序和过滤有冲突,所以如果想在一个接口同时支持过滤和排序,那么必须都加上
filter_backends = [OrderingFilter,DjangoFilterBackend]
如果只做排序,可以只加一个OrderingFilter
ID倒序排列(-为倒序,+为正序)
http://127.0.0.1:8888/opt/test6/?ordering=-id
同时支持过滤和排序 http://127.0.0.1:8888/opt/test6/?ordering=id&age=26
分页
修改配置
#全局分页配置
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 4 # 每页数目
看效果
PS:
如果在配置settings.py文件中, 设置了全局分页,那么在drf中凡是调用了ListModelMixin的list(),都会自动分页。如果项目中出现大量需要分页的数据,只有少数部分的分页,则可以在少部分的视图类中关闭分页功能。
局部分页测试
导入路由
router.register('page',views.pageAPIView,basename='page')
添加配置
from rest_framework.pagination import LimitOffsetPagination
class MyPage(LimitOffsetPagination):
default_limit = 3 #默认每页条数
limit_query_param = 'limit' #支持url的查询分页为5条
max_limit = 5
offset_query_param = 'offset'
class pageAPIView(GenericViewSet,ListModelMixin):
# 重写内置queryset
queryset = Student.objects.all()
serializer_class = StudentModelSerializers
pagination_class = MyPage
可以看到也支持query查询分页
就算写最大http://127.0.0.1:8888/opt/page/?limit=15也只会显示5条数据的哦
当然也可以修改其他配置参数了
可选分页器
1) PageNumberPagination
class MyPage(LimitOffsetPagination):
# default_limit = 3 #默认每页条数
# limit_query_param = 'limit' #支持url的查询分页为5条
# max_limit = 5
# offset_query_param = 'offset'
# 默认每一页显示的数据量
page_size = 2
# 允许客户端通过get参数来控制每一页的数据量
page_size_query_param = "size"
max_page_size = 10
# 自定义页码的参数名
page_query_param = "p"
另外一种
2)LimitOffsetPagination
前端访问网址形式:
GET http://127.0.0.1/four/students/?limit=100&offset=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_size
default_limit = 2
limit_query_param = "size"
offset_query_param = "start"
class StudentAPIView(ListAPIView):
queryset = Student.objects.all()
serializer_class = StudentModelSerializer
# 调用页码分页类
# pagination_class = StandardPageNumberPagination
# 调用查询偏移分页类
pagination_class = StandardLimitOffsetPagination
最后上一张总的配置截图
大功告成,加油~~~~