使用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
相关产品推荐
相关产品推荐

