【9.0】DRF之路由

【一】路由的写法

【1】原始写法

介绍

  • 是指手动编写路由规则的方式。
  • 使用path()函数或re_path()函数来定义路由规则,并将其与对应的视图函数或类关联起来。

例如

  • 假设有一个名为book的应用,它包含了一个处理图书列表的视图函数book_list,以及一个处理单个图书详情的视图函数book_detail
  • 我们可以通过以下方式手动编写路由规则:
from django.urls import path

from book.views import book_list, book_detail

urlpatterns = [
    path('books/', book_list, name='book_list'),
    path('books/<int:book_id>/', book_detail, name='book_detail'),
]
  • 在这个例子中
    • 第一条路由规则匹配到/books/路径,并将其与book_list视图函数关联起来。
    • 第二条路由规则匹配到/books/<int:book_id>/路径,其中<int:book_id>是一个路径参数,用于匹配一个整型的图书ID,并将其传递给book_detail视图函数。

【2】映射的写法

介绍

  • 是指使用DRF(Django REST Framework)提供的路由器来自动生成路由规则。
  • 路由器将HTTP方法与视图集中的相应操作方法进行映射。
  • 在使用路由器时,需要先定义一个视图集,然后将其与路由器关联起来。
  • 最后,在URL配置中使用路由器生成的路由规则。

示例

from rest_framework.routers import DefaultRouter
from book.views import BookViewSet

router = DefaultRouter()
router.register('books', BookViewSet, basename='book')

urlpatterns = router.urls
  • 在这个例子中
    • BookViewSet是一个继承了DRF提供的ModelViewSet的视图集,它定义了处理图书列表、创建图书等操作的方法。
    • 使用DefaultRouter()创建了一个默认的路由器实例,并将视图集BookViewSet注册到路由器中,设置了基准名称为book
    • 最后,使用router.urls获取路由器生成的路由规则,并将其用于URL配置。

【3】小结

  • 可以根据需求选择手动编写路由规则或使用路由器自动生成路由规则。
  • 手动编写路由规则更加灵活,可以对每个URL路径指定具体的视图函数或类。
  • 使用路由器可以简化代码,特别适用于处理一组相关操作的视图函数或类。

【二】自动生成路由

  • 必须要继承ViewSetMixin及其子类的视图类,才能用
  • 继承了 5个视图扩展类+ViewSetMixin的视图类,能自动生成路由
path('books/', BookView.as_view({'get': 'list', 'post': 'create'})),
path('books/<int:pk>/', BookView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
  • 在Django REST Framework(DRF)中,可以使用视图集(ViewSet)来处理与模型相关的多个操作。

  • 为了方便地生成与视图集相关的路由规则,DRF提供了扩展类和Mixin类。

    • ViewSetMixin是一个基础Mixin类

      • 它包含了处理CRUD(Create、Retrieve、Update、Delete)操作的方法。

      • 当一个视图类继承了ViewSetMixin时,它就拥有了处理这些操作的方法,从而能够生成对应的路由规则。

    • DRF还提供了五个扩展类(ListModelMixinCreateModelMixinRetrieveModelMixinUpdateModelMixinDestroyModelMixin

      • 这些扩展类分别对应着列表查询、创建、单个对象查询、更新、删除等操作。
  • 继承了这五个扩展类和ViewSetMixin的视图类,能够自动生成符合RESTful设计风格的路由规则。

  • 例如,在一个书籍(Book)应用中,可以定义一个继承了五个扩展类和ViewSetMixin的视图类BookViewSet

from rest_framework import viewsets
from rest_framework.mixins import (
    ListModelMixin,
    CreateModelMixin,
    RetrieveModelMixin,
    UpdateModelMixin,
    DestroyModelMixin
)
from book.models import Book
from book.serializers import BookSerializer

class BookViewSet(
    ListModelMixin,
    CreateModelMixin,
    RetrieveModelMixin,
    UpdateModelMixin,
    DestroyModelMixin,
    viewsets.GenericViewSet
):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
  • 在这个例子中,BookViewSet继承了五个扩展类和ViewSetMixin,并且作为GenericViewSet的子类。
  • 通过设置queryset属性指定模型查询集,serializer_class属性指定序列化器类。
  • 通过使用DefaultRouter生成的路由器,可以自动生成符合RESTful设计风格的路由规则:
from rest_framework.routers import DefaultRouter
from book.views import BookViewSet

router = DefaultRouter()
router.register('books', BookViewSet, basename='book')

urlpatterns = router.urls
  • 在这个例子中
    • 使用DefaultRouter()创建了一个路由器实例router
    • 然后调用router.register()方法将视图集BookViewSet注册到路由器中,并设置了基准名称为'book'
    • 最后使用router.urls获取到生成的路由规则,并将其用于URL配置。
  • 使用上述方式
    • 自动生成的路由规则与手动编写的路由规则是等效的。
    • 例如
      • 自动生成的列表查询和创建操作对应的路由规则就等同于手动编写的path('books/', BookView.as_view({'get': 'list', 'post': 'create'}))
      • 自动生成的单个对象查询、更新和删除操作对应的路由规则就等同于手动编写的path('books/<int:pk>/', BookView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'}))

【三】自动注册路由的两种方式

第一步:导入一个路由类

from rest_framework.routers import SimpleRouter
  • 两个路由类
    • SimpleRouter
    • DefaultRouter

第二步:实例化得到对象

router = SimpleRouter()

第三步:注册路由(视图类)

router.register("books", BookView, "books")

# router.register("自定义前缀", 需要注册视图类, "别名")
  • "books":

    • 这是路由的前缀,用于指定URL配置中该视图集合的基本路径。

    • 在这个例子中,"books" 将作为 URL 配置的一部分,用来注册与图书相关的视图。

      • 配置了path('books/', include(router.urls))

      • 则所有与图书相关的URL都将以 "/books/" 开头。

  • BookView:

    • 这是要注册的视图类。
    • 在Django REST Framework中,视图类指的是实现了处理HTTP请求和响应的类。
    • BookView 是自定义的一个视图类,并继承自DRF提供的视图类(如 generics.ListAPIViewviewsets.ModelViewSet)。
    • 注册后,这个视图类将与指定的前缀相对应,并处理发送到相应URL的请求。
  • "books":

    • 这是路由的别名(可选参数)。
    • 这个别名用于为路由创建名称,以方便在其他地方引用该路由。
    • 当您需要在代码中引用注册的路由时可以使用该别名。
  • 总结起来

    • router.register("books", BookView, "books") 的意思是将名为 BookView 的视图类注册到路由器中,并为它们添加一个基本路径为 "/books/" 的前缀。
    • 在URL配置中引用这个路由时,您可以使用别名 "books"。
    • 这样,当有请求发送到 "/books/" 或类似于 "/books/{pk}/" 的URL时,相应的视图类将被调用来处理这些请求。

第四步:加入到路由中

  • 方式一
    • 将路由对象的URL配置添加到现有的urlpatterns中。
    • 使用urlpatterns += router.urls将路由对象的URL配置列表添加到现有的URL配置中。
from django.urls import path

urlpatterns = [
    ...
]
urlpatterns += router.urls
print("urlpatterns:>>>", urlpatterns)
# urlpatterns:>>> [<URLResolver <URLPattern list> (admin:admin) 'admin/'>, <URLPattern 'book/'>]
print("router:>>>", router)
# router:>>> <rest_framework.routers.SimpleRouter object at 0x000001EB24D63130>
  • 方式二
    • 使用include()函数创建URL配置
    • 并将路由对象作为参数传递给include()函数。
    • 例如,使用path("api/v1/", include(router.urls))将路由对象的URL配置嵌套在前缀为"api/v1/"的URL路径下。
from django.urls import path, include

urlpatterns = [
    path("api/v1/", include(router.urls))
]

【SimpleRouter】

介绍

  • SimpleRouter是一个简单的路由类,它提供了基本的路由功能。
  • 使用SimpleRouter可以轻松地将视图类与URL路径进行映射和注册。
  • 它内部使用了SimpleRouter()类创建了一个路由对象。

操作步骤

  • 首先,导入SimpleRouter:
    • from rest_framework.routers import SimpleRouter
  • 然后,实例化一个SimpleRouter对象:
    • router = SimpleRouter()
  • 接下来,使用router.register()方法将需要注册的视图类进行注册。
    • 该方法接受三个参数:自定义前缀、需要注册的视图类和别名。
    • 例如,router.register("books", BookView, "books")
  • 最后,将路由对象添加到URL配置中
    • 可以通过两种方式实现:
      • 一种是将 urlpatterns += router.urls 添加到现有的URL配置中
      • 另一种是使用 include() 函数创建URL配置,并将路由对象作为参数传递给 include() 函数。

【DefaultRouter】

介绍

  • DefaultRouter是SimpleRouter的子类,它提供了与SimpleRouter相同的基本路由功能,并且额外提供了一个默认根路径。
  • 这个根路径可以用于自动创建包括API根视图和可浏览API的URL配置。

操作步骤

  • 首先,导入DefaultRouter:
    • from rest_framework.routers import DefaultRouter
  • 然后,实例化一个DefaultRouter对象:
    • router = DefaultRouter()
  • 接下来,使用router.register()方法注册视图类,同样可以传递自定义前缀和别名。
  • 最后,将路由对象添加到URL配置中,可以通过方式一或方式二将其加入现有的URL配置。

【四】路由的映射

手动

  • 根据指定的动作触发指定的函数
path("books/",BookView.as_view({"get":"my_model"})),
  • 使用path("books/", BookView.as_view({"get":"my_model"}))来进行手动映射。
    • 这里是使用Django的path函数将URL路径 "/books/" 与 my_model 方法关联起来。
  • BookView 是一个视图类,并且通过as_view()方法将其转换为可调用的视图函数。
  • 利用字典 {"get": "my_model"} 将HTTP GET请求映射到名为 my_model 的方法上。
  • 这样当有GET请求发送到 "/books/" 路径时,my_model 方法将被调用来处理请求。

自动

  • 必须要继承ViewSetMixin及其子类的视图类,才能用
# 使用装饰器做映射
from rest_framework.decorators import action


# 自定义视图类 --- 必须继承ViewSetMixin及其子类的视图类
class MyView(ViewSet):
    # 在想要触发的函数上面加装饰器
    @action(methods=["GET"],detail=False,url_path="my_router",url_name="my_router")
    def my_view(self, request):
        return Response("OK")
  • 首先需要继承DRF提供的 ViewSetMixin 或其子类的自定义视图类,
    • 例如 class MyView(ViewSet)
  • 使用装饰器 @action 来声明要触发的函数
    • 比如 @action(methods=["GET"],detail=False,url_path="my_router",url_name="my_router")
  • 在该装饰器内部,可以指定HTTP方法、是否针对单个对象(详情视图)以及自定义的URL路径和URL名称。
  • 上述代码中的 my_view 方法是被装饰的函数,用于处理相应的请求。在这个例子中,当有GET请求发送到路径 "/my_router/" 时,my_view 方法将被调用来处理请求,并返回 "OK"。

【五】总结

【1】自动注册路由

  • 继承了 5个视图扩展类+ViewSetMixin的视图类,能自动生成路由(get:list,get:retrieve..)

  • 我们自己命名的: 方法名:login send_sms,需要使用装饰器来做

# 视图类:
class SMSView(ViewSet):
    @action(methods=['GET'], detail=False, url_path='my_router', url_name='my_router')
    def lqz(self, request):
# 路由
router.register('my_router',SMSView,'my_router')
# 路径是:http://127.0.0.1:8000/api/v1/my_router/my_router/
  • action装饰器的参数

    • methods:请求方式

    • detail:

      • 一个True
        • 用True,表示生成详情的路径 <int:pk>
        • True,books/1/方法名/
      • 一个False
        • False,books/方法名/
    • url_path:

      • 路径名字,需要加上前面的路径一起
      • 如果不加,默认以函数名作为路径名
    • url_name:

      • 反向解析使用的名字(用的不多)

【2】路由类

  • 路由类,有两个,用法完全一致,区别是DefaultRouter生成的路径多

  • SimpleRouter :用的最多

  • DefaultRouter

  • DefaultRouter与SimpleRouter的区别是

    • DefaultRouter会多附带一个默认的API根视图
    • 返回一个包含所有列表视图的超链接响应数据。

【六】路由转换器

  • 在Django框架中,路由转换器(Route Converters)是用于从URL中提取参数并将其传递给视图函数的一种机制。
  • 它允许开发者定义灵活的URL模式,并从URL中提取有意义的数据作为视图函数的参数。

【1】功能:

  • 提取URL参数:
    • 路由转换器可以从URL路径中提取出特定的参数,并将其传递给相关的视图函数。
  • 数据验证:
    • 路由转换器还可以对提取的参数进行验证,确保其符合开发者的要求。
  • 实现动态URL:
    • 通过使用不同类型的路由转换器,可以创建具有动态参数的URL,更加灵活和可扩展。

【2】路由转换器类型:

  • str:
    • 匹配除了路径分隔符(/)以外的任何字符。
    • 例如,<str:name>可以匹配名字为字符串类型的参数。
  • int:
    • 匹配一个正整数。
    • 例如,<int:pk>可以匹配一个名为pk的整型参数。
  • slug:
    • 匹配一个Slug(短标签),只允许字母、数字、下划线或连字符。
    • 例如,<slug:slug>可以匹配一个名为slug的Slug参数。
  • uuid:
    • 匹配一个UUID格式的字符串。
    • 例如,<uuid:uuid>可以匹配一个名为uuid的UUID参数。
  • path:
    • 匹配包括路径分隔符(/)的任何非空字符串。
    • 例如,<path:path>可以匹配一个名为path的任意路径。

【3】使用路由转换器:

  • 在Django中,路由转换器通过在URL模式中使用尖括号进行定义。例如:
from django.urls import path
from . import views

urlpatterns = [
    path('users/<int:user_id>/', views.user_detail),
]
  • 上述代码中,<int:user_id>使用了int路由转换器来提取一个名为user_id的整型参数,并将其传递给views.user_detail函数。

【4】高级用法:

  • 自定义转换器:
    • 除了内置的路由转换器类型外,您还可以自定义自己的转换器类型,以便满足特定的需求。
  • 组合转换器:
    • 您可以将多个转换器组合在一起,以实现更复杂的参数提取和验证逻辑。
posted @ 2023-07-31 12:22  Chimengmeng  阅读(160)  评论(0编辑  收藏  举报