django.urls.exceptions.NoReverseMatch:反向找不到参数的'user-detail'

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

我有一个相当简单的检索测试:

def test_user_retrieve(self):
    factory = APIRequestFactory()
    User.objects.create_superuser(username='test', password='Welcome2', email='[email protected]')
    user = User.objects.get(username='test')
    view = UserViewSet.as_view({'get': 'retrieve'})
    url = reverse('core:user-detail')
    request = factory.get(url)
    force_authenticate(request, user=user)
    response = view(request, pk=1)
    self.assertEqual(response.status_code, status.HTTP_200_OK)

它给出了以下回溯:

Traceback (most recent call last):
  File "D:\Projects\enterpass\api\core\tests.py", line 54, in test_user_retrieve
    url = reverse('core:user-detail')
  File "D:\Python36\lib\site-packages\django\urls\base.py", line 88, in reverse
    return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
  File "D:\Python36\lib\site-packages\django\urls\resolvers.py", line 632, in _reverse_with_prefix
    raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'user-detail' with no arguments not found. 2 pattern(s) tried: ['api/v1/core/users/(?P<pk>[^/.]+)\\.(?P<format>[a-z0-9]+)/?$', 'api/v1/core/users/(?P<pk>[^/.]+)/$']

如果我使用邮递员点击URL,则没有问题:

http://localhost:8000/api/v1/core/users/1/

该视图正在通过路由器进行注册,如下所示:

app_name = 'core'
router.register(r'users', views.UserViewSet, base_name='user')

这是相关视图的一部分:

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes_by_action = {'list': [CanListUser],
                                    'create': [CanCreateUser],
                                    'retrieve': [CanRetrieveUser],
                                    'update': [CanUpdateUser],
                                    'destroy': [CanDestroyUser]}

    def retrieve(self, request, pk=None, **kwargs):
        try:
            instance = self.get_object()
            self.check_object_permissions(self.request, instance)
            serializer = UserSerializer(instance, context={'request': request})
            return Response(serializer.data, status=status.HTTP_200_OK)
        except User.DoesNotExist:
            return Response(status=status.HTTP_204_NO_CONTENT)

找到解决方案,但我希望有人根据这个工作视图为我解释:

def test_user_retrieve(self):
    factory = APIRequestFactory()
    User.objects.create_superuser(username='test', password='Welcome2', email='[email protected]')
    user = User.objects.get(username='test')
    view = UserViewSet.as_view({'get': 'retrieve'})
    url = reverse('core:user-detail', args=(User.pk,))
    request = factory.get(url)
    force_authenticate(request, user=user)
    response = view(request, pk=1)
    self.assertEqual(response.status_code, status.HTTP_200_OK)

出于某种原因,我必须在URL中指定位置参数,然后在响应中我需要指定id。解决方案从这里拉出来:

Django Rest Framework - How to test ViewSet?

python django unit-testing
1个回答
1
投票

我想你忘了用reverse传递必需的参数。用下面的反向添加用户的pk。

userPK = 123 // User ID
url = reverse('core:user-detail', args=[userPK])
© www.soinside.com 2019 - 2024. All rights reserved.