zoukankan      html  css  js  c++  java
  • drf路由组件

    一. 基本使用#

    Copy
    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()实例化的路由格式

    Copy
    # 项目中打印
    # 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()类实例化的路由格式

    Copy
    # 项目中打印
    '''
    [
        <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

    总结#

    Copy
    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装饰器#

    Copy
    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

    总结#

    Copy
    # 为什么使用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/$')
    

    三. 补充: 路由生成的二种方法#

    Copy
    urlpatterns = [
        # 1. 生成的路由第一种添加方法
        url(r'', include(router.urls))
    ]
    # 2. 生成的路由第二种添加方法
    urlpatterns += router.urls
    

    四. 补充: 关于路由组件的使用#

    Copy
    路由组自动生成的原理: 自动生成路由, 自动配置actions参数.
    也就是说只要是继承了ViewSetMixin的视图类, 都可以配置路由组件.
    
     
  • 相关阅读:
    程序、进程、线程区别与联系
    SQL常用知识与必须掌握的面试常问SQL语句
    快速搭建一个基于react的项目
    原生js判断设备类型
    在vue项目中设置BASE_URL
    纯前端实现数据导出excel文件
    原生js实现拖拽功能
    使用Echarts实现折线图的一点总结
    在vue项目中显示实时时间(年月日时分秒)
    在vue项目中使用MD5.js
  • 原文地址:https://www.cnblogs.com/Tornadoes-Destroy-Parking-Lots/p/13386337.html
Copyright © 2011-2022 走看看