自动生成的 DRF 路线 *-使用 ViewSets 时未找到详细信息

问题描述 投票:0回答:1

我尝试将 Django Rest Framework (DRF) 与 HyperlinkedModelSerializers、ViewSets 和 Router 结合使用。

当我检查生成的路由时,Django 向我显示

vehicle-detail
,但 DRF 抱怨错误:

ImproperlyConfigured at /api/vehicles/
Could not resolve URL for hyperlinked relationship using view name "vehicle-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.

如果从字段中省略

url
,下面的代码效果很好。

有人知道缺少什么吗?

url.py

from rest_framework.routers import DefaultRouter
from vehicles import viewsets

# Create a router and register our ViewSets with it.
router = DefaultRouter()
router.register(r'vehicles',
                viewsets.VehicleViewSet,
                basename='vehicle')

# The API URLs are now determined automatically by the router.
urlpatterns = [
    path('', include(router.urls)),
]

车辆/viewsets.py

class VehicleViewSet(viewsets.ModelViewSet):
    queryset = Vehicle.objects.all()
    serializer_class = VehicleSerializer

车辆/序列化器.py

class VehicleSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Vehicle
        fields = ['url', 'name', 'description']
        # fields = ['name', 'description']  # Removed 'url'. Now the API works

生成的网址

api/ ^vehicles/$ [name='vehicle-list']
api/ ^vehicles\.(?P<format>[a-z0-9]+)/?$ [name='vehicle-list']
api/ ^vehicles/(?P<pk>[^/.]+)/$ [name='vehicle-detail']
api/ ^vehicles/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='vehicle-detail']
api/ [name='api-root']
api/ <drf_format_suffix:format> [name='api-root']

点冻结

Django                  5.1
djangorestframework     3.15.2
django django-rest-framework
1个回答
0
投票

问题是 url 命名空间

https://www.django-rest-framework.org/api-guide/routers/ 上指出:

如果将命名空间与超链接序列化器一起使用,您还需要确保序列化器上的任何 view_name 参数正确反映命名空间。在上面的示例中,您需要包含一个参数,例如 view_name='app_name:user-detail' 用于超链接到用户详细信息视图的序列化器字段。

Django 主 urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/auth/', include('rest_framework.urls', namespace='rest_framework')),
    path('api/', include(('api.urls', 'api'), namespace='api')),
]

解决方案

我在 path('api/', include(('api.urls', 'api'), namespace='api')) 中使用命名空间

api

我还需要在序列化器中提供命名空间:

class VehicleSerializer(serializers.HyperlinkedModelSerializer):
    url = serializers.HyperlinkedIdentityField(view_name='api:vehicle-detail')

    class Meta:
        model = Vehicle
        fields = ['url', 'name', 'description']
© www.soinside.com 2019 - 2024. All rights reserved.