HyperlinkedModelSerializer生成URL缺失api/前缀的问题及解决
Django REST Framework Hyperlinked URL 缺失前缀问题的解决办法
这问题我之前踩过坑,核心原因是你的路由配置出现了重复冲突,导致DRF生成链接时选到了不带前缀的路由。
问题原因分析
你当前的路由配置做了两件冲突的事:
- 把
router.urls通过re_path(r'api/', include(router.urls))挂载到了api/前缀下 - 又直接通过
urlpatterns += router.urls把router的原始路由(不带前缀)也添加到了全局路由里
这就导致同一个视图集对应了两组路由:一组带api/前缀,另一组不带。而HyperlinkedModelSerializer生成URL时,会通过视图对应的路由名称反向解析路径,这时候因为不带前缀的路由也存在,DRF就默认匹配了那组,所以返回的链接里没有api/前缀。同时这也是为什么localhost:8000/api/comments/1/和localhost:8000/comments/1/都能访问的原因——两组路由都生效了。
解决方法
只需要保留带api/前缀的路由配置,删掉直接追加router.urls的那一行即可。修改后的api.urls代码如下:
from django.urls import re_path, include from rest_framework import routers from . import viewsets router = routers.DefaultRouter() router.register('posts', PostViewSet) router.register('comments', CommentViewSet) urlpatterns = [ # 建议加上^锚定开头,避免匹配到类似apitest/这类无关路径 re_path(r'^api/', include(router.urls)), ] # 移除下面这行重复的路由配置 # urlpatterns += router.urls
如果你的Django版本在2.0及以上,用path会更简洁规范:
from django.urls import path, include # ...其他导入代码 urlpatterns = [ path('api/', include(router.urls)), ]
修改后重启服务,再访问localhost:8000/api/comments/,返回的单个Comment数据里的url和post字段就会带上api/前缀了,而且不带前缀的路由也会失效,完全符合你的预期。
内容的提问来源于stack exchange,提问作者ImportError
相关产品推荐
相关产品推荐

