Django REST Framework (DRF) Router 注册流程详解

在使用 Django REST Framework (DRF) 开发 API 的时候,我们常常会看到这样的代码:

python 复制代码
from rest_framework.routers import DefaultRouter
from .views import UserViewSet, GroupViewSet

router = DefaultRouter()
router.register(r'users', UserViewSet)
router.register(r'groups', GroupViewSet)

urlpatterns = router.urls

只需要几行代码,就能自动生成 users/groups/ 的路由。

那么问题来了:

  • Router.register() 做了什么?

  • 为什么只需要写 ViewSet 就能生成一堆路由?

  • router.urls 是怎么来的?

本文将深入解析 DRF Router 的注册流程。


1. Router 的作用

在 Django 原生路由中,我们需要手动写 URL:

python 复制代码
urlpatterns = [
    path('users/', UserList.as_view()),
    path('users/<int:pk>/', UserDetail.as_view()),
]

但是在 DRF 中,一个 ViewSet 通常包含了 list/create/retrieve/update/destroy 等多个动作。

如果手写 URL 映射会非常繁琐。

于是,Router 的职责就是:根据 ViewSet 自动生成标准化的 URLConf


2. Router.register() 做了什么?

DefaultRouter 为例,调用 register() 时:

python 复制代码
router.register(r'users', UserViewSet)

主要做了三件事:

  1. 保存注册信息

    prefix='users'viewset=UserViewSet 存入 self.registry 列表中。

    python 复制代码
    self.registry.append((prefix, viewset, basename))
  2. 确定 basename

    • 如果没指定,会自动从 UserViewSet.queryset.model 推断模型名称(如 user)。

    • 这个 basename 决定了路由命名空间,例如:user-listuser-detail

  3. 延迟生成 URL
    register() 并不会立刻生成 URL,而是等待访问 router.urls 时再统一构建。


3. router.urls 是怎么生成的?

当我们访问 router.urls 时,Router 会执行以下流程:

  1. 遍历 self.registry 中的所有注册项

    每个项包含:prefixviewsetbasename

  2. 调用 get_urls()

    根据 ViewSet 的动作方法(listcreateretrieveupdatepartial_updatedestroy)生成对应的路由规则。

    例如 UserViewSet 默认生成:

    URL HTTP方法 动作
    /users/ GET list
    /users/ POST create
    /users/{pk}/ GET retrieve
    /users/{pk}/ PUT update
    /users/{pk}/ PATCH partial_update
    /users/{pk}/ DELETE destroy
  3. 拼接为最终的 urlpatterns

    这就是 router.urls 的来源,最终交给 Django 的 URLConf 系统使用。


4. DefaultRouter 和 SimpleRouter 的区别

  • SimpleRouter

    只生成 CRUD 的基础路由。

  • DefaultRouter

    除了 CRUD 路由,还会额外生成一个 根 API 页面api-root/),列出所有注册的资源入口。

示例:

访问 /api/,会看到:

python 复制代码
{
  "users": "http://127.0.0.1:8000/api/users/",
  "groups": "http://127.0.0.1:8000/api/groups/"
}

5. 自定义 Router

如果你需要定制路由规则,可以继承 SimpleRouter 并重写 routes 属性:

python 复制代码
from rest_framework.routers import SimpleRouter, Route

class CustomRouter(SimpleRouter):
    routes = [
        Route(
            url=r'^{prefix}/custom/{lookup}{trailing_slash}$',
            mapping={'get': 'custom_action'},
            name='{basename}-custom',
            detail=True,
            initkwargs={'suffix': 'Custom'}
        ),
    ]

这样就可以为所有 ViewSet 自动添加一个自定义路由。


6. 总结

  • register() 负责登记 prefixviewsetbasename,并保存到 self.registry

  • router.urls 在第一次访问时动态生成 URLConf,映射到 ViewSet 的标准动作。

  • DefaultRouterSimpleRouter 多了一个根 API 入口。

  • Router 本质上就是一个 URL 自动生成器,大大简化了手写路由的工作。

相关推荐
luoluoal8 小时前
基于python的医疗问句中的实体识别算法的研究(源码+文档)
python·mysql·django·毕业设计·源码
jianghua0019 小时前
Django视图与URLs路由详解
数据库·django·sqlite
MZ_ZXD00121 小时前
springboot旅游信息管理系统-计算机毕业设计源码21675
java·c++·vue.js·spring boot·python·django·php
wqq63108551 天前
Python基于Vue的实验室管理系统 django flask pycharm
vue.js·python·django
Q_Q19632884751 天前
python大学生爱心校园互助代购网站_nyvlx_django Flask vue pycharm项目
python·django·flask
wxin_VXbishe1 天前
C#(asp.net)学员竞赛信息管理系统-计算机毕业设计源码28790
java·vue.js·spring boot·spring·django·c#·php
码界筑梦坊1 天前
330-基于Python的社交媒体舆情监控系统
python·mysql·信息可视化·数据分析·django·毕业设计·echarts
码界筑梦坊1 天前
325-基于Python的校园卡消费行为数据可视化分析系统
开发语言·python·信息可视化·django·毕业设计
码界筑梦坊1 天前
327-基于Django的兰州空气质量大数据可视化分析系统
python·信息可视化·数据分析·django·毕业设计·数据可视化
WangYaolove13142 天前
基于python的在线水果销售系统(源码+文档)
python·mysql·django·毕业设计·源码