如何在Django REST Framework的Router中限制URL参数为int类型
这个需求完全可以实现,不需要停用DRF自带的Router,也不需要手动编写所有URL模式,有两种常用的实现方案可选:
方案1:自定义Router类全局指定int类型约束
你可以继承SimpleRouter重写路由规则,把原有默认的(?P<pk>[^/.]+)替换为Django的int路径转换器<int:pk>,之后所有用该Router注册的视图都会自动生成带int约束的单对象路由:
from rest_framework.routers import SimpleRouter, route, dynamic_route class IntPkSimpleRouter(SimpleRouter): routes = [ # 列表路由保持原有配置不变 route( url=r'^{prefix}{trailing_slash}$', mapping={ 'get': 'list', 'post': 'create' }, name='{basename}-list', detail=False, initkwargs={'suffix': 'List'} ), # 单对象路由把pk匹配规则改为int转换器 route( url=r'^{prefix}/<int:pk>{trailing_slash}$', mapping={ 'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy' }, name='{basename}-detail', detail=True, initkwargs={'suffix': 'Instance'} ), # 列表侧动态路由保持不变 dynamic_route( url=r'^{prefix}/{url_path}{trailing_slash}$', name='{basename}-{url_name}', detail=False, initkwargs={} ), # 单对象侧动态路由同步修改pk规则 dynamic_route( url=r'^{prefix}/<int:pk>/{url_path}{trailing_slash}$', name='{basename}-{url_name}', detail=True, initkwargs={} ), ]
修改后直接用自定义的IntPkSimpleRouter替换原有的SimpleRouter即可,原有注册逻辑不需要改动:
# urls.py router = IntPkSimpleRouter(trailing_slash=False) router.register("/?", MembersController, basename="member") urlpatterns = router.urls
方案2:单视图指定lookup匹配规则(轻量方案)
如果只需要给MembersController这一个视图加约束,不需要全局修改,直接在视图类中配置lookup_value_regex即可:
class MembersController(ModelViewSet): # 指定pk仅匹配数字,效果和int:转换器完全一致 lookup_value_regex = r'\d+' # 其余原有视图逻辑保持不变
修改后Router生成的单对象路由匹配规则会自动变为(?P<pk>\d+)$,非整数的pk请求会直接返回404,不会进入视图逻辑。
内容的提问来源于stack exchange,提问作者Kevin Renskers
相关产品推荐
相关产品推荐

