5 drf 路由组件

一. 基本使用

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']
'''

image-20200710070312742

使用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']
'''

image-20200710070250634

总结

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时的路由格式

image-20200710070055695

使用action添加了路由以后的detail=False时的路由格式

image-20200710070148919

总结

# 为什么使用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的视图类, 都可以配置路由组件.
posted @ 2020-11-15 13:17  为了等  阅读(114)  评论(0编辑  收藏  举报