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 自动生成器,大大简化了手写路由的工作。

相关推荐
Muyuan199810 小时前
27.RAG 系统中的上下文充分性判断:从 Chunk 数量、FAISS 距离到 LLM Relevance Gate
python·django·pdf·fastapi·faiss
程序媛徐师姐15 小时前
Python基于Django的小区果蔬预定系统【附源码、文档说明】
python·django·小区果蔬预定系统·果蔬预定·python小区果蔬预定系统·小区果蔬预定·python果蔬预定系统
码界筑梦坊2 天前
111-基于Python的中国旅游用户数据可视化分析系统
python·信息可视化·django·毕业设计·旅游
YJlio2 天前
10.2.8 以其他账户运行服务(Running services in alternate accounts):为什么“把服务切到某个用户账号下运行”,本质上是在改变服务的整个安全上下文?
python·安全·ios·机器人·django·iphone·7-zip
小熊Coding2 天前
懂车帝汽车销售数据可视化分析系统
python·信息可视化·django·汽车·数据可视化分析·懂车帝·汽车销售数据分析
ma_de_hao_mei_le2 天前
ntquerysystemiunfomation 数据传递
django
Muyuan19982 天前
22.让 RAG Agent 更像真实产品:聊天页面优化、PDF 上传、知识库重建与检索片段展示
python·django·pdf·fastapi
Muyuan19983 天前
25.Paper RAG Agent 优化记录:上传反馈、计算器安全与 Chunk 参数调整
python·安全·django·sqlite·fastapi
Muyuan19983 天前
26.Paper RAG Agent 展示面收口:截图与项目表达更新记录
人工智能·python·django·fastapi
毕胜客源码4 天前
卷积神经网络的手势识别系统(有技术文档)深度学习 图像识别 卷积神经网络 Django python 人工智能
人工智能·python·深度学习·cnn·django