drf路由组件Routers
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 UserTokenclass 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, tokenelse: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 APIViewclass ExampleView(APIView):# 类属性authentication_classes = [SessionAuthentication, BasicAuthentication]...
五、drf权限功能Permissions
1、自定义权限类
权限控制可以限制用户对于视图的访问和对于具体数据对象的访问。
- 在执行视图的dispatch()方法前,会先进行视图访问权限的判断
- 在通过get_object()获取具体对象时,会进行模型对象访问权限的判断
编写权限类
# 继承BasePermission,重写has_permission,如果有权限,就返回True,没有权限就返回False
from rest_framework.permissions import BasePermissionclass PermissionUser(BasePermission):def has_permission(self, request, view):# 如果有权限,返回Trueif 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 APIViewclass 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 MyThrottlingclass 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 SearchFilterclass 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 OrderingFilterclass 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,OrderingFilterclass 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 DjangoFilterBackendclass 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 BaseFilterBackendclass MyFilterBackend(BaseFilterBackend):# url: http://127.0.0.1:8000/book/?price__gt=56def 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 MyFilterBackendclass BookGenericViewSet(ListCreateAPIView):queryset = Book.objects.all()serializer_class = Bookserializersfilter_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=2page_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=3offset_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' #按谁排序
drf路由组件Routers相关推荐
- 视图组件,路由组件,版本控制
1,视图组件 django中写CBV的时候继承View,rest_framework继承的是APIView,,其实APIView是继承View urlpattEerns = [# url(r'^boo ...
- python drf_python drf各类组件的用法和作用
DRF组件的用法和作用 认证 自定义认证的类 """ from rest_framework.authentication import BaseAuthenticati ...
- Django REST framework(十)路由集routers的使用
Django REST framework(九)-视图集ViewSet.GenericViewSet.ModelViewSet.ReadOnlyModelViewSet_simpleyako的博客-C ...
- Rest-framework之drf认证组件,权限组件+不存数据库的token认证
Rest-framework之drf认证组件,权限组件 django中一个请求时一个reques,如果在哪个位置改了request,那么到了后面就是修改过的request 昨日回顾: 认证: -写一个 ...
- Vue教程6【完结】【vue-router】路由,路由传参,编程式路由导航,缓存路由组件,路由守卫,路由模式,vue ui组件库
vue-router 了解 vue插件库,用来实现SPA应用(单页面) 整个页面只有一个完整的页面 点击页面中导航链接,不会刷新页面,只做局部更新 数据通过ajax请求 路由的理解 一组映射关系(ke ...
- 【Android 组件化】路由组件 ( 页面跳转参数依赖注入 )
文章目录 一.参数自动注入 二.自定义注解 三.使用 @Extra 自定义注解 四.注解处理器解析 @Extra 自定义注解 并生成相应 Activity 对应代码 五.博客资源 组件化系列博客 : ...
- 【Android 组件化】路由组件 ( 路由框架概述 )
文章目录 一.路由框架概述 二.路由框架整体流程 三.博客资源 组件化系列博客 : [Android 组件化]从模块化到组件化 [Android 组件化]使用 Gradle 实现组件化 ( Gradl ...
- 【Android 组件化】路由组件 ( 生成 Root 类记录模块中的路由表 )
文章目录 一.Root 表作用 二.生成 Root 表 三.完整注解处理器代码 及 生成的 Java 代码 ( 仅供参考 ) 1.注解处理器代码 2.app 模块中的注解类生成的 Java 源码 3. ...
- 【Android 组件化】路由组件 ( 组件间共享的服务 )
文章目录 一.组件间共享的服务 二.注解处理器添加对上述 " 组件间共享的服务 " 的支持 三.注解处理器 生成代码规则 四.完整注解处理器代码 及 生成的 Java 代码 1.注 ...
最新文章
- strcpy_s与strcpy的比較
- IIS上.Net 扩展中进行恢复
- C#重写Equals方法步骤
- python下载谷歌地图瓦片_python获取bing地图发布自己的TMS服务(一)下载瓦片
- 软考信息系统项目管理师_历年真题_2020下半年错题集_上午综合知识题---软考高级之信息系统项目管理师036
- 如何用yolov5测试图片
- Supervisor 自动管理进程
- win10中安装step7 5.6
- GeoDa 空间自相关操作步骤
- Premiere视频剪辑软件的破解和安装
- 陈式新架一路八十三式口诀
- Temami防辐射服小贴士
- 求1加到n的发散思维方法
- nginx+flume网络流量日志实时数据分析实战
- ROG Phone 6什么时候发布 ROG Phone 6配置如何
- jquery水平导航栏动态菜单
- java 字体选择器_常见CSS3选择器和文本字体样式汇总
- java socket实现的简易的聊天工具demo
- DataTable属性详解
- vue 多页面应用搭建