五、drf路由组件
drf路由组件
一、基本使用
1. 步骤
-
导入routers模块
from rest_framework import routers
-
有两个类,实例化(二选一)得到该对象
# routers.DefaultRouter # routers.SimpleRouter router = routers.SimpleRouter()
-
注册
# router.register('前缀','继承自ModelViewSet试图类','别名') 不要加斜杠 router.register('book',view.BookViewSet) # 不要加斜杠
-
自动生成路由
# router.urls 就是自动生成的路由,直接添加到urlpatterns中 urlpatterns += router.urls
2. 代码实现
# 第一步
from rest_framework import routers
# 第二步
router = routers.SimpleRouter()
# 第三步
router.register('books',views.BooksView) # 不要加斜杠
urlpatterns = [
url(r'^admin/', admin.site.urls),
]
# 第四步
urlpatterns += router.urls
3. 总结
1.适用范围:只有继承了ViewSetMixin类的视图,才可以使用路由组件快速生成路由
2.快速生成的路由有2种路由类:SimpleRouter、DefaultRouter
3.2种路由类的区别
SimpleRouter生成的路由
^admin/
^books/$ [name='book-list']
^books/(?P<pk>[^/.]+)/$ [name='book-detail']
DefaultRouter生成的路由 华而不实
^admin/
^books/$ [name='book-list']
^books\.(?P<format>[a-z0-9]+)/?$ [name='book-list']
^books/(?P<pk>[^/.]+)/$ [name='book-detail']
^books/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='book-detail']
^books/(?P<pk>[^/.]+)/get_1/$ [name='book-get-1']
^\.(?P<format>[a-z0-9]+)/?$ [name='api-root']
二、视图中的action装饰器
from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response
from rest_framework.decorators import action
from app01.models import Book
from app01.serializer import BookModelSerializer
class BookModelViewSet(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
"""
提示: action是一个装饰器
导入方式: from rest_framework.decorators import action
作用: 给继承自ModelViewSet的视图类中定义的函数也添加路由
"""
@action(methods=['GET'], detail=True)
def get_two(self, request, pk):
print(pk)
book_queryset = self.get_queryset()[:2]
serializer = self.serializer_class(instance=book_queryset, many=True)
return Response(serializer.data)
@action(methods=['GET'], detail=False)
def get_all(self, request):
book_queryset = self.get_queryset()
serializer = self.serializer_class(instance=book_queryset, many=True)
return Response(serializer.data)
参数详解
def action(methods=None, detail=None, url_path=None, url_name=None, **kwargs):
methods: 第一个参数,传一个列表,列表中放请求方式
提示: 由下面的源码得知如果没有指定参数, 默认是get方法. 且方法可以大写, 可以小写. 大写的话就会将大写的字符串转换成小写
methods = ['get'] if (methods is None) else methods
methods = [method.lower() for method in methods]
detail: 指定布尔值. 控制路由匹配的形式. True可以匹配单条数据, False可以匹配多条数据
True时匹配规则: ^app02/ ^books/(?P<pk>[^/.]+)/get_two/$ [name='book-get-two']
False时匹配规则: ^app02/ ^books/get_two/$ [name='book-get-two']
总结
1.detail=True是在需要传入pk值时使用,detail=False相反
2.action装饰器的使用场景:对查询数据有限制时使用
3.为什么使用action装饰器?
因为快速生成路由组件无法手动添加路由 和 无法修改视图类中方法名, 通过action就可以快速实现.
4.使用流程
(1). 导入: from rest_framework.decorators import action
(2). 在视图中为视图中的方法添加装饰器
class BookView(ViewSet):
@action(method=["post", ], detail=True)
def login():
...
参数介绍:
method: 不指定, 默认就是get方法. 如果指定大写, 默认就会转成小写.
detail: 不指定, 会抛出异常. 指定True, False表示的路由不一样. 看3
(3). 路由中就会新增一个路由
detail=True时: url(r'^books/(?P<pk>)/login/$')
detail=False时: url(r'^books/login/$')
三、补充
1. 路由生成的两种方式
urlpatterns = [
# 1. 生成的路由第一种添加方法
url(r'', include(router.urls))
]
# 2. 生成的路由第二种添加方法
urlpatterns += router.urls
2. 关于路由组件的使用
路由组自动生成的原理: 自动生成路由, 自动配置actions参数.
也就是说只要是继承了ViewSetMixin的视图类, 都可以配置路由组件.