当前位置:网站首页>drf路由组件Routers
drf路由组件Routers
2022-08-02 14:01:00 【意大利面拌42号混凝土】
drf路由组件Routers
对于视图集ViewSet,我们除了可以自己手动指明请求方式与动作action之间的对应关系外,还可以使用Routers来帮助我们快速实现路由信息。
REST framework提供了两个router
- SimpleRouter
- DefaultRouter
一、使用方法
创建Router对象,并注册视图集
# 导入SimpleRouter与DafaultRouter包
from rest_farmework.routers import SimpleRouter,DafaultRouter
# 实例化对象
simplerouter = SimpleRouter()
defaultrouter = DafaultRouter()
# 路由注册
simplerouter.register('login/',StudentModelViewSet,basename='login')
register(prefix, viewset, base_name)
- prefix 该视图集的路由前缀
- viewset 视图集
- base_name 路由别名的前缀
如上述代码会形成的路由如下:
^books/$ name: book-list
^books/{
pk}/$ name: book-detail
二、添加路由的两种方式
有两种添加方式
第一种
urlpatterns = [
……
]
urlpatterns+=simplerouter.urls
第二种
urlpatterns = [
path('',include(simplerouter.urls))
]
代码演示
# 必须是继承ModelViewSet的视图类才能自动生成路由
from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet
class StudentModelViewSet(ModelViewSet):
queryset = Student.objects.all()
serializer_class = StudentModelSerializer
# 这种方法不会自动生成,需要用action配置
def login(self,request):
"""学生登录功能"""
print(self.action)
return Response({
"message":"登录成功"})
路由代码
from django.urls import path, re_path
from . import views
urlpatterns = [
...
]
"""使用drf提供路由类router给视图集生成路由列表"""
# 实例化路由类
# drf提供一共提供了两个路由类给我们使用,他们用法一致,功能几乎一样
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
# 注册视图集
# router.register("路由前缀",视图集类)
router.register("router_stu",views.StudentModelViewSet)
# 把生成的路由列表追加到urlpatterns
print( router.urls )
urlpatterns += router.urls
上面的代码就成功生成了路由地址[增/删/改/查一条/查多条的功能],但是不会自动我们在视图集自定义方法的路由。
所以我们如果也要给自定义方法生成路由,则需要进行action动作的声明。
1、自动生成路由的视图类
-需要继承ViewSetMixin+9个视图子类
-需要继承ViewSetMixin+视图类+五个视图扩展类
三、视图集中附加action的声明
在视图集中,如果想要让Router自动帮助我们为自定义的动作生成路由信息,需要使用rest_framework.decorators.action
装饰器。
以action装饰器装饰的方法名会作为action动作名,与list、retrieve等同。
action装饰器可以接收两个参数:
methods: 声明该action对应的请求方式,列表传递
detail: 声明该action的路径是否与单一资源对应,及是否是
访问的路径,可以不写,如果不写,以方法名作为路径 通过get请求访问这个路径test/login就能触发login的执行
url_path:访问的路径可以不写,,如果不写就会以方法名作为路径,通过get请求访问这个路径test/login就能触发函数login的执行
url_name:别名
# @action(methods=['GET'],detail=False,url_path='login',url_name='login')
@action(methods=['GET'],detail=True)
def login(self, request,pk):
print(self.action)
print(pk)
# self.get_serializer()
return Response('登录成功')
四、drf认证功能Authentication
1、自定义认证类
需要单独新建一个py文件,编写认证类
#自定义认证类,要继承BaseAuthentication,重写authenticate,如果认证通过,返回两个值,如果认证失败,抛认证失败的异常
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from .models import UserToken
class LoginAuth(BaseAuthentication):
def authenticate(self, request):
# 校验用户是否登录:看它有没有带token来,以及token是不是合法的(是不是我给的)
token = request.GET.get('token')
# 校验token是否合法(根据token去库中查询是否存在,如果存在,就是登陆了,放行)
user_token = UserToken.objects.filter(token=token).first()
if user_token:
# 带的token是有效的
# user_token.user当前登录用户
return user_token.user, token
else:
raise AuthenticationFailed('token不合法或没有迭代token')
认证类的使用
#局部配置
from app01.auth import LoginAuth
class PublishView(ModelViewSet):
authentication_classes = [LoginAuth,]
# 全局配置
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.auth.LoginAuth",]
}
认证失败会有两种可能的返回值:
- 401 Unauthorized 未认证
- 403 Permission Denied 权限被禁止
2、内置认证类(需要配合权限使用)
可以在配置文件中配置全局默认的认证方案
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication', # session认证
'rest_framework.authentication.BasicAuthentication', # 基本认证
)
}
也可以在每个视图中通过局部设置authentication_classess属性来设置
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.views import APIView
class ExampleView(APIView):
# 类属性
authentication_classes = [SessionAuthentication, BasicAuthentication]
...
五、drf权限功能Permissions
1、自定义权限类
权限控制可以限制用户对于视图的访问和对于具体数据对象的访问。
- 在执行视图的dispatch()方法前,会先进行视图访问权限的判断
- 在通过get_object()获取具体对象时,会进行模型对象访问权限的判断
编写权限类
# 继承BasePermission,重写has_permission,如果有权限,就返回True,没有权限就返回False
from rest_framework.permissions import BasePermission
class PermissionUser(BasePermission):
def has_permission(self, request, view):
# 如果有权限,返回True
if request.user.user_type == 1:
return True # 超级用户允许访问
else:
return False
权限类使用
#认证类的局部配置
from app01.auth import LoginAuth
class PublishView(ModelViewSet):
# 权限类:publish的5个接口,必须超级用户才能访问
permission_classes = [PermissionUser]
#全局使用
REST_FRAMEWORK={
"DEFAULT_PERMISSION_CLASSES":["app01.auth.PermissionUser",]
}
如需自定义权限,需继承rest_framework.permissions.BasePermission父类,并实现以下两个任何一个方法或全部
- `.has_permission(self, request, view)`
是否可以访问视图, view表示当前视图对象
- `.has_object_permission(self, request, view, obj)`
是否可以访问数据对象, view表示当前视图, obj为数据对象
2、内置权限类
from rest_framework.permissions import AllowAny,IsAuthenticated,IsAdminUser,IsAuthenticatedOrReadOnly
- AllowAny 允许所有用户
- IsAuthenticated 仅通过认证的用户
- IsAdminUser 仅管理员用户
- IsAuthenticatedOrReadOnly 已经登陆认证的用户可以对数据进行增删改操作,没有登陆认证的只能查看数据。
全局使用
REST_FRAMEWORK = {
....
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
}
- 如未指名,则采用如下配置
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.AllowAny',
)
局部使用在具体的视图中通过permission_classes属性来设置
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
class ExampleView(APIView):
permission_classes = [IsAuthenticated,]
...
六、drf频率功能Throttling
1、自定义频率类
2、内置频率类
新建一个名为throttlings.py的文件,名字可以随便取,在里面写限流类
# 使用内置限流类SimpleRateThrottle
from rest_framework.throttling import SimpleRateThrottle
class MyThrottling(SimpleRateThrottle):
# 类中书写一个属性
scope = 'frequency'
# 重写get_cache_key()方法
def get_cache_key(self, request, view):
#返回什么就以什么做限制,此处返回其父类中的get_ident()方法,get_ident()方法为其内置ip限流方法
return self.get_ident(request)
使用方法
# 局部配置
from .serializers import Bookserializers
from .models import Book
from rest_framework.generics import ListCreateAPIView
# 导入自定义编写的限流py文件
from .throttlings import MyThrottling
class BookGenericViewSet(ListCreateAPIView):
queryset = Book.objects.all()
serializer_class = Bookserializers
# 使用throttle_classes类属性
""" throttle_classes类属性在类APIView中 """
throttle_classes = [MyThrottling,]
# 全局配置
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES': {
# key值是频率类中scop字段对应的值,value是访问次数限制
'frequency': '3/m',
}
}
七、drf过滤排序功能
首先要明确一点,过滤条件应是在请求地址中
过滤功能有三种,内置过滤功能,第三方的过滤功能和自定义过滤功能
1、内置过滤功能
rest-framework的filters模块有三个类BaseFilterBackend(基类),SearchFilter(过滤查询类),OrderingFilter(排序类)
# 直接导入内置过滤模块,并配置过滤类即可使用
from .serializers import Bookserializers
from .models import Book
from rest_framework.generics import ListCreateAPIView
from rest_framework.filters import SearchFilter
class BookGenericViewSet(ListCreateAPIView):
queryset = Book.objects.all()
serializer_class = Bookserializers
# 配置过滤类
filter_backends = [SearchFilter,]
# 配置过滤字段
search_fields=['name'] # url:http://127.0.0.1:8000/book/?search=记
# 也可以配置多重字段,多种条件一起过滤
search_fields=['name','price'] # url:http://127.0.0.1:8000/book/?search=记&search=56
2、内置排序功能
# 直接导入内置过滤模块,并配置排序类类即可使用
from .serializers import Bookserializers
from .models import Book
from rest_framework.generics import ListCreateAPIView
from rest_framework.filters import OrderingFilter
class BookGenericViewSet(ListCreateAPIView):
queryset = Book.objects.all()
serializer_class = Bookserializers
# 配置排序类
filter_backends = [OrderingFilter,]
# 配置排序字段
# search_fields=['name']
ordering_fields=['price'] # http://127.0.0.1:8000/book/?ordering=price (按价格的正序排列)
ordering_fields = ['price','id'] # http://127.0.0.1:8000/book/?ordering=price,-id (价格一样,按照id的倒叙排列)
3、过滤排序组合使用
# 过滤排序组合使用
from .serializers import Bookserializers
from .models import Book
from rest_framework.generics import ListCreateAPIView
from rest_framework.filters import SearchFilter,OrderingFilter
class BookGenericViewSet(ListCreateAPIView):
queryset = Book.objects.all()
serializer_class = Bookserializers
# 配置过滤与排序类
filter_backends = [SearchFilter,OrderingFilter]
# 配置过滤字段
search_fields = ['name']
# 配置排序字段
ordering_fields = ['price'] # url:http://127.0.0.1:8000/book/?search=记&ordering=-price
4、第三方过滤类的使用
现在我们有这么个需求,我想要价格为56且名字等于西游记的具体数据,怎么办?
http://127.0.0.1:8000/book/?search=西游记&price=56,就现有学习的内容无法实现此功能,这就需要借助于第三方的模块
pip install django-filter
from django_filters.rest_framework import DjangoFilterBackend
# 第三方过滤类的使用
from .serializers import Bookserializers
from .models import Book
from rest_framework.generics import ListCreateAPIView
from django_filters.rest_framework import DjangoFilterBackend
class BookGenericViewSet(ListCreateAPIView):
queryset = Book.objects.all()
serializer_class = Bookserializers
# 配置过滤字段
filter_backends = [DjangoFilterBackend]
filter_fields = ['name','price'] # url: http://127.0.0.1:8000/book/?name=西游记&price=56
1、自定义过滤类
新建一个过滤FilterBackend.py文件
# 自定义过滤类
from rest_framework.filters import BaseFilterBackend
class MyFilterBackend(BaseFilterBackend):
# url: http://127.0.0.1:8000/book/?price__gt=56
def filter_queryset(self, request, queryset, view):
# queryset就是要过滤的数据
price= request.query_params.get('price__gt')
if price:
queryset = queryset.filter(price__gt=price)
return queryset
view.py
# 自定义过滤类的使用
from .serializers import Bookserializers
from .models import Book
from rest_framework.generics import ListCreateAPIView
from .FilterBackend import MyFilterBackend
class BookGenericViewSet(ListCreateAPIView):
queryset = Book.objects.all()
serializer_class = Bookserializers
filter_backends = [MyFilterBackend]
八、drf分页功能
############## 自定义分页类
##基本分页
from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination
##基本分页
class MyPageNumberPagination(PageNumberPagination):
# 重写4个类属性即可
page_size = 2 # 每页显示两条
page_query_param = 'page' # 查询条件 http://127.0.0.1:8000/books/?page=2
page_size_query_param = 'size' # http://127.0.0.1:8000/books/?page=2&size=4 获取第二页数据,返回4条
max_page_size = 5 # http://127.0.0.1:8000/books/?page=2&size=400 获取第二页数据,最多返回5条
# 偏移分页
class MyLimitOffsetPagination(LimitOffsetPagination):
# 4个类属性
default_limit = 2 #每页默认显示多少条
limit_query_param = 'limit' # http://127.0.0.1:8000/books/?limit=3
offset_query_param = 'offset'# http://127.0.0.1:8000/books/?limit=3&offset=1 # 从2位置取3条数据
max_limit = 5 # 限制limit最大条数
# 游标分页
class MyCursorPagination(CursorPagination):
cursor_query_param = 'cursor' # 查询条件,无用
page_size = 2 # 每页显示多少条
ordering = 'id' #按谁排序
边栏推荐
- php开源的客服系统_在线客服源码php
- 【Tensorflow】AttributeError: module ‘keras.backend‘ has no attribute ‘tf‘
- 基于深度学习的图像检索方法!
- 网络安全第三次作业
- shell脚本“画画”
- logback源码阅读(二)日志打印,自定义appender,encoder,pattern,converter
- 如何选择正规的期货交易平台开户?
- els 长条碰撞变形判断
- els long block deformation conditions, boundary collision judgment
- 微信小程序如何实现支付功能?看官方文档头疼(使用云函数的方式操作)「建议收藏」
猜你喜欢
鲲鹏devkit & boostkit
乐心湖‘s Blog——MySQL入门到精通 —— 囊括 MySQL 入门 以及 SQL 语句优化 —— 索引原理 —— 性能分析 —— 存储引擎特点以及选择 —— 面试题
【ONE·Data || 排序入门】
Break the limit of file locks and use storage power to help enterprises grow new momentum
Some impressions of the 519 plummet 2021-05-21
如何解决mysql服务无法启动1069
The most complete ever!A collection of 47 common terms of "digital transformation", read it in seconds~
Image retrieval method based on deep learning!
Awesome!Alibaba interview reference guide (Songshan version) open source sharing, programmer interview must brush
mysql的case when如何用
随机推荐
Swagger 的使用
机器学习——交叉验证法
好用的php空间,推荐国内三个优质的免费PHP空间[通俗易懂]
期货具体是如何开户的?
网络安全第五次作业
【Tensorflow】AttributeError: '_TfDeviceCaptureOp' object has no attribute '_set_device_from_string'
【ONE·Data || 排序入门】
CVE-2020-27986(Sonarqube敏感信息泄漏) 漏洞修复
The bad policy has no long-term impact on the market, and the bull market will continue 2021-05-19
Sentinel源码(一)SentinelResourceAspect
你接受不了60%的暴跌,就没有资格获得6000%的涨幅 2021-05-27
HALCON: 内存管理(Memory Management)
Sentinel源码(四)(滑动窗口流量统计)
Differences and concepts between software testing and hardware testing
如何解决1045无法登录mysql服务器
Some impressions of the 519 plummet 2021-05-21
栈 && 队列
LayoutParams的详解
You can't accept 60% slump, there is no eligible for gain of 6000% in 2021-05-27
How to solve mysql service cannot start 1069