You need to enable JavaScript to run this app. DRF 如何从自动生成的API路由列表中隐藏部分指定路由
优惠活动
大模型
产品
解决方案
定价
更多

DRF 如何从自动生成的API路由列表中隐藏部分指定路由

实现方案

完全可以在不改动DRF核心逻辑、不影响路由正常访问的前提下实现指定条目的隐藏展示能力,核心是利用DRF Router的可扩展入口自定义带隐藏标记能力的路由类即可。

核心实现思路

DRF的路由生成逻辑分为两个完全独立的运行模块:

  • 实际URL映射:在调用router.register()方法时就会完成路由和视图集的绑定,负责处理正常的请求匹配、视图响应流程
  • API根视图展示内容:由Router的get_api_root_view()方法动态生成,负责在浏览API根路径时给用户展示所有已注册的路由列表

我们只需要在生成根视图展示内容的阶段过滤掉带隐藏标记的路由条目即可,完全不碰实际URL映射的逻辑,自然不会影响对应路由的正常访问。

具体代码实现

  1. 先定义带隐藏能力的路由Mixin,扩展原有Router类的register方法和根视图生成逻辑:
    from rest_framework.routers import DefaultRouter, SimpleRouter
    from rest_framework.response import Response
    
    class HideableRouterMixin:
        def register(self, prefix, viewset, basename=None, hide_from_view=False):
            # 调用父类register方法完成所有正常路由注册流程,不改动核心逻辑
            super().register(prefix, viewset, basename)
            # 记录需要隐藏的路由前缀
            if not hasattr(self, '_hidden_routes'):
                self._hidden_routes = set()
            if hide_from_view:
                self._hidden_routes.add(prefix.rstrip('/'))
    
        def get_api_root_view(self, api_urls=None):
            # 复用原有根视图的生成逻辑,仅对返回的响应数据做过滤
            original_root_view = super().get_api_root_view(api_urls)
    
            def wrapped_root_view(request, *args, **kwargs):
                response = original_root_view(request, *args, **kwargs)
                # 仅在响应返回前过滤隐藏的路由条目
                if isinstance(response, Response) and hasattr(self, '_hidden_routes'):
                    for hidden_prefix in self._hidden_routes:
                        hidden_key = next(
                            (key for key in response.data.keys()
                             if key.rstrip('/').endswith(hidden_prefix)),
                            None
                        )
                        if hidden_key:
                            del response.data[hidden_key]
                return response
            return wrapped_root_view
    
    # 定义适配DEBUG/非DEBUG模式的自定义Router类
    class CustomDefaultRouter(HideableRouterMixin, DefaultRouter):
        pass
    
    class CustomSimpleRouter(HideableRouterMixin, SimpleRouter):
        pass
    
  2. 替换原有路由初始化逻辑,只需要把原来的DefaultRouter、SimpleRouter换成自定义的类即可,分支判断逻辑完全不需要调整:
    if settings.DEBUG:
        router = CustomDefaultRouter()
    else:
        router = CustomSimpleRouter()
    
  3. 路由注册逻辑就可以完全按照期望的写法实现:
    # Domains REST Routes:
    router.register(r'domains', DomainViewSet)
    
    # Domains Pin REST Routes:
    router.register(r'domains/pin', DomainPinViewSet, hide_from_view=True)
    

效果说明

  • 标记了hide_from_view=True的路由会从API根视图的展示列表中完全移除,不管是JSON格式响应还是Browsable API的HTML展示都不会出现该条目
  • 所有路由的实际访问能力不受任何影响,直接请求对应路径完全可以正常匹配视图、返回响应
  • 默认hide_from_view=False,原有未加该参数的路由注册逻辑和原生Router行为完全一致,不会产生兼容问题
  • 因为过滤逻辑完全在响应层实现,不会和DRF的其他路由扩展产生冲突

内容的提问来源于stack exchange,提问作者Micheal J. Roberts

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.02 08:45:09