【问题标题】:django.urls.exceptions.NoReverseMatch: Reverse for 'user-detail' with no arguments not founddjango.urls.exceptions.NoReverseMatch:“用户详细信息”的反向,没有找不到参数
【发布时间】:2018-01-01 21:14:13
【问题描述】:

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

def test_user_retrieve(self):
    factory = APIRequestFactory()
    User.objects.create_superuser(username='test', password='Welcome2', email='test@test.com')
    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='test@test.com')
    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】:

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

    userPK = 123  # User ID
    url = reverse('core:user-detail', args=[userPK])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-11
      • 2018-06-07
      • 1970-01-01
      • 2019-06-01
      • 2019-07-10
      • 2019-06-03
      相关资源
      最近更新 更多