Django REST Framework reverse()找不到路由器“{basename}-detail”的匹配项

Django REST Framework reverse() not finding match for router's "{basename}-detail"

这个问题非常类似于:How to fix this NoReverseMatch exception in Django rest frameworks routers?但那不是answered/resolved,经过大量调查后,我正在寻求帮助.

我正在尝试使用测试驱动开发构建一个 API。作为惯例,我通过使用 django.urls.reverse()

为 URLS 保存常量变量来开始我的测试

问题是 reverse('{app}:{basename}-list') 工作正常,但 reverse('{app}:{basename}-detail') 抛出异常:

django.urls.exceptions.NoReverseMatch: Reverse for 'designer-detail' with no arguments not found. 2 pattern(s) tried: ['api/design/designer/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$', 'api/design/designer/(?P<pk>[^/.]+)/$']

我的 test.py:(注意列表 url 首先运行并且没有抛出异常)

from rest_framework.test import APITestCase, APIClient
from django.contrib.auth import get_user_model
from rest_framework_simplejwt.tokens import RefreshToken
from django.urls import reverse
from rest_framework import status
from designs.models import Designer
from designs.serializers import DesignerSerializer


DESIGNER_LIST_URL = reverse('designs:designer-list')
DESIGNER_DETAIL_URL = reverse('designs:designer-detail')

我的app/urls.py:

from rest_framework.routers import DefaultRouter
from designs.views import DesignerViewset


app_name = 'designs'

router = DefaultRouter()
router.register(r'designer', DesignerViewset, 'designer')

urlpatterns = router.urls

我的project/urls.py:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/user/', include('user.urls')),
    path('api/design/', include('designs.urls'))
]

我的serializers.py:

from rest_framework import serializers
from designs.models import Designer


class DesignerSerializer(serializers.ModelSerializer):
    """
    Model serializer for Designer.
    """
    class Meta:
        model = Designer
        fields = "__all__"

还有我的 views.py:

from rest_framework.viewsets import ModelViewSet
from designs.models import Designer
from designs.serializers import DesignerSerializer


class DesignerViewset(ModelViewSet):
    """
    ModelViewSet for the Designer model.
    """
    queryset = Designer.objects.all()
    serializer_class = DesignerSerializer

我尝试修改基本名称、路由器、app_name、url模式,但似乎没有任何效果。我已经阅读了关于 vanilla django 和 DRF 的官方文档。 最令人困惑的 是为什么 "designs:designer-list" 按预期运行但 "designs:designer-detail" 失败? DefaultRouter 应该会处理这个问题。我在 Django shell.

中手动测试了最后一个比较

我错过了什么?

引发错误的原因是 URL 有一个 pk 参数,因此您需要为其提供一个值才能定义 URL 路径。

可以用kwarg=…参数传递命名参数的值,所以:

reverse('designs:designer-detail', <strong>kwargs={'pk': <em>42</em>}</strong>)

其中 42 是您要获取其详细信息的项目的主键。