一. 基本使用
from django.conf.urls import url
# 第一步:从rest_framework包中导入routers模块
from rest_framework import routers
from .views import BookModelViewSet
# 第二步:有两个类,实例化得到对象
"""
routers.SimpleRouter() 生成2条路由
routers.DefaultRouter() 生成6条路由
"""
# router = routers.SimpleRouter()
router = routers.DefaultRouter()
# 第三步:注册
'''
def register(self, prefix, viewset, basename=None, base_name=None):
"""
prefix: 前缀.
viewset: 继承自ModelViewSet视图类
basename: 别名
"""
'''
router.register('books', BookModelViewSet) # 提示: 不需要加斜杠
urlpatterns = []
# 第四步: 通过router.urls会自动生成的路由列表, 只需要加入到原路由中即可
urlpatterns += router.urls
使用SimpleRouter()实例化的路由格式
# 项目中打印
# print(router.urls)
'''
[
<RegexURLPattern book-list ^books/$>,
<RegexURLPattern book-detail ^books/(?P<pk>[^/.]+)/$>
]
'''
# 浏览器中打印
'''
# 解析: [^/.]+
[^/.]+ 中^表示取反 意思就是匹配任意其它内容, /就不匹配.
+号表示且匹配1个或者多个
^app01/ ^books/$ [name='book-list']
^app01/ ^books/(?P<pk>[^/.]+)/$ [name='book-detail']
'''
使用DefaultRouter()类实例化的路由格式
# 项目中打印
'''
[
<RegexURLPattern book-list ^books/$>,
<RegexURLPattern book-list ^books\.(?P<format>[a-z0-9]+)/?$>,
<RegexURLPattern book-detail ^books/(?P<pk>[^/.]+)/$>,
<RegexURLPattern book-detail ^books/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$>, <RegexURLPattern api-root ^$>,
<RegexURLPattern api-root ^\.(?P<format>[a-z0-9]+)/?$>
]
'''
# 浏览器中打印
'''
^app01/ ^books/$ [name='book-list']
^app01/ ^books\.(?P<format>[a-z0-9]+)/?$ [name='book-list']
^app01/ ^books/(?P<pk>[^/.]+)/$ [name='book-detail']
^app01/ ^books/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='book-detail']
^app01/ ^$ [name='api-root']
^app01/ ^\.(?P<format>[a-z0-9]+)/?$ [name='api-root']
'''
总结
1. 使用范围: 只有继承了 ViewSetMixin 类的视图, 才可以使用路由组件快速生成路由
2. 快速生成路由的2种路由类: SimpleRouter, DefaultRouter
3. 路由中使用:
from django.conf.urls import include
from rest_framework.routes import SimpleRouter
router = SimpleRouter()
router.register('路由前缀', 继承了ViewSetMixin类的视图, 用于反向解析的别名)
urlpatterns = [
url('', include(router.urls)), # 添加路由的第二种方式
]
urlpatterns += router # 添加路由的第一种方式
二. 视图中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的视图类中定义的函数也添加路由
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']
"""
'''
# detail=False时浏览器输入 http://127.0.0.1:8011/app02/books/get_two/
# detail=True时浏览器输入: http://127.0.0.1:8011/app02/books/1/get_two/
@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)
使用action添加了路由以后的detail=True时的路由格式
使用action添加了路由以后的detail=False时的路由格式
总结
# 为什么使用action装饰器?
因为快速生成路由组件无法手动添加路由 和 无法修改视图类中方法名, 通过action就可以快速实现.
# 使用流程
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/$')
三. 补充: 路由生成的二种方法
urlpatterns = [
# 1. 生成的路由第一种添加方法
url(r'', include(router.urls))
]
# 2. 生成的路由第二种添加方法
urlpatterns += router.urls
四. 补充: 关于路由组件的使用
路由组自动生成的原理: 自动生成路由, 自动配置actions参数.
也就是说只要是继承了ViewSetMixin的视图类, 都可以配置路由组件.