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. 视图组件,路由组件,版本控制

    1,视图组件 django中写CBV的时候继承View,rest_framework继承的是APIView,,其实APIView是继承View urlpattEerns = [# url(r'^boo ...

  2. python drf_python drf各类组件的用法和作用

    DRF组件的用法和作用 认证 自定义认证的类 """ from rest_framework.authentication import BaseAuthenticati ...

  3. Django REST framework(十)路由集routers的使用

    Django REST framework(九)-视图集ViewSet.GenericViewSet.ModelViewSet.ReadOnlyModelViewSet_simpleyako的博客-C ...

  4. Rest-framework之drf认证组件,权限组件+不存数据库的token认证

    Rest-framework之drf认证组件,权限组件 django中一个请求时一个reques,如果在哪个位置改了request,那么到了后面就是修改过的request 昨日回顾: 认证: -写一个 ...

  5. Vue教程6【完结】【vue-router】路由,路由传参,编程式路由导航,缓存路由组件,路由守卫,路由模式,vue ui组件库

    vue-router 了解 vue插件库,用来实现SPA应用(单页面) 整个页面只有一个完整的页面 点击页面中导航链接,不会刷新页面,只做局部更新 数据通过ajax请求 路由的理解 一组映射关系(ke ...

  6. 【Android 组件化】路由组件 ( 页面跳转参数依赖注入 )

    文章目录 一.参数自动注入 二.自定义注解 三.使用 @Extra 自定义注解 四.注解处理器解析 @Extra 自定义注解 并生成相应 Activity 对应代码 五.博客资源 组件化系列博客 : ...

  7. 【Android 组件化】路由组件 ( 路由框架概述 )

    文章目录 一.路由框架概述 二.路由框架整体流程 三.博客资源 组件化系列博客 : [Android 组件化]从模块化到组件化 [Android 组件化]使用 Gradle 实现组件化 ( Gradl ...

  8. 【Android 组件化】路由组件 ( 生成 Root 类记录模块中的路由表 )

    文章目录 一.Root 表作用 二.生成 Root 表 三.完整注解处理器代码 及 生成的 Java 代码 ( 仅供参考 ) 1.注解处理器代码 2.app 模块中的注解类生成的 Java 源码 3. ...

  9. 【Android 组件化】路由组件 ( 组件间共享的服务 )

    文章目录 一.组件间共享的服务 二.注解处理器添加对上述 " 组件间共享的服务 " 的支持 三.注解处理器 生成代码规则 四.完整注解处理器代码 及 生成的 Java 代码 1.注 ...

最新文章

  1. strcpy_s与strcpy的比較
  2. IIS上.Net 扩展中进行恢复
  3. C#重写Equals方法步骤
  4. python下载谷歌地图瓦片_python获取bing地图发布自己的TMS服务(一)下载瓦片
  5. 软考信息系统项目管理师_历年真题_2020下半年错题集_上午综合知识题---软考高级之信息系统项目管理师036
  6. 如何用yolov5测试图片
  7. Supervisor 自动管理进程
  8. win10中安装step7 5.6
  9. GeoDa 空间自相关操作步骤
  10. Premiere视频剪辑软件的破解和安装
  11. 陈式新架一路八十三式口诀
  12. Temami防辐射服小贴士
  13. 求1加到n的发散思维方法
  14. nginx+flume网络流量日志实时数据分析实战
  15. ROG Phone 6什么时候发布 ROG Phone 6配置如何
  16. jquery水平导航栏动态菜单
  17. java 字体选择器_常见CSS3选择器和文本字体样式汇总
  18. java socket实现的简易的聊天工具demo
  19. DataTable属性详解
  20. vue 多页面应用搭建

热门文章

  1. 【MTK Front Camera Bringup】
  2. 在ubuntu18.04上安装vmware
  3. 01、pyqt入门使用--01布局、基本组件、第一个示例、qtdesigner大概使用
  4. 清北学堂2019.8.7
  5. 《在难搞的日子笑出声来》
  6. Mac恢复被修改的文档
  7. C#中定义装箱和拆箱详解
  8. react 中 ref 管理列表
  9. 融合软泥怪 (优先队列)
  10. 单的axis java教程