You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用HyperlinkedModelSerializer与ModelViewSet时无法解析URL的问题

HyperlinkedModelSerializer 无法解析 test-detail 视图名错误

使用Django REST Framework的HyperlinkedModelSerializer时出现配置错误,无法解析test-detail视图名,已关联模型且未修改lookup_field,手动设置也无效。

代码实现

models.py

from django.db import models

class Test(models.Model):
    name = models.CharField(default="yolo", max_length=100)

serializers.py

from rest_framework import serializers
from .models import Test

class TestSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Test 
        fields = '__all__'

views.py

from rest_framework import viewsets
from .models import Test
from .serializers import TestSerializer

class TestViewSet(viewsets.ModelViewSet):
    queryset = Test.objects.all()
    serializer_class = TestSerializer

urls_v1.py

from rest_framework.routers import DefaultRouter
from django.urls import path, include
from .views import TestViewSet

router = DefaultRouter()
router.register(r'test', TestViewSet)
test_patterns = [
    path('', include(router.urls)),
]

urls.py

from django.urls import path, include
from core.urls_v1 import test_patterns

urlpatterns = [
    path('test', include((test_patterns, "test"))),
]

生成的路由

^test/$ [name='test-list']
^test\.(?P<format>[a-z0-9]+)/?$ [name='test-list']
^test/(?P<pk>[^/.]+)/$ [name='test-detail']
^test/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='test-detail']

错误信息

File "\rest_framework\serializers.py", line 522, in to_representation
    ret[field.field_name] = field.to_representation(attribute)
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "\rest_framework\relations.py", line 416, in to_representation
    raise ImproperlyConfigured(msg % self.view_name)

django.core.exceptions.ImproperlyConfigured: Could not resolve URL for hyperlinked relationship using view name "test-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.

问题原因与解决方法

问题出在路由命名空间的匹配上:你在urls.py中使用include((test_patterns, "test"))给路由设置了命名空间test,但HyperlinkedModelSerializer默认只会查找不带命名空间的test-detail视图名,导致无法匹配到实际带命名空间的test:test-detail。

有两种解决方式:

方式一:修改序列化器,指定带命名空间的view_name

在序列化器中显式设置url字段的view_name,加上命名空间前缀:

class TestSerializer(serializers.HyperlinkedModelSerializer):
    url = serializers.HyperlinkedIdentityField(
        view_name='test:test-detail'
    )
    
    class Meta:
        model = Test 
        fields = '__all__'

方式二:调整路由配置,避免命名空间冲突

如果不需要命名空间,可以修改urls.py中的include方式,去掉命名空间参数:

path('test/', include(test_patterns))

或者在注册路由时指定basename,确保视图名称正确匹配:
在urls_v1.py中注册路由时添加basename='test':

router.register(r'test', TestViewSet, basename='test')

内容的提问来源于stack exchange,提问作者Vegard

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 15:11:11