python - 在 Django Rest Framework 中测试 PUT 方法

标签 python django testing django-rest-framework

我正在尝试在 django Rest 框架中测试 PUT 方法。我得到 HttpResponsePermanentRedirect 而不是响应对象。我对 put 方法的看法设置为在成功更新后发送状态 200。错误:

self.assertEqual(response.data, serializer.data) AttributeError: 'HttpResponsePermanentRedirect' object has no attribute 'data'

测试.py

class PostTestGetAndPutMethod(APITestCase):
    def setup(self):
        Post.objects.create(title="POST CREATED", content="POST WAS CREATED")
        Post.objects.create(title="POST CREATED 2", content="POST WAS CREATED 2")
        Post.objects.create(title="POST CREATED 3", content="POST WAS CREATED 3")

    def test_get_posts(self):
        '''
        Ensure we can get list of posts
        '''
        # get API response 
        response = self.client.get(reverse('posts'))
        # get data from DB
        posts = Post.objects.all()
        # convert it to JSON
        serializer = PostSerializer(posts, many=True)
        # check the status 
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data, serializer.data)

    def test_update_put_post(self):
        '''
        Check if we can update post 
        '''
        data = {'title': 'POST MODIFIED', 'content': 'CONTENT MODIFIED'}
        response = self.client.put('/posts/1', data)
        serializer = PostSerializer(data)
        self.assertEqual(response.data, serializer.data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)

views.py

@api_view(['GET', 'PUT', 'DELETE'])
def post_detail(request, pk):
    """
    Retrieve, update or delete a code snippet.
    """
    try:
        post = Post.objects.get(pk=pk)
    except Post.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        serializer = PostSerializer(post)
        return Response(data=serializer.data, status=status.HTTP_200_OK)

    elif request.method == 'PUT':
        serializer = PostSerializer(post, data=data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        post.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

编辑 测试应该如下所示:

class PostTestPutMethod(APITestCase):
    def setUp(self):
        # Posts to be modified 
        self.first_post = Post.objects.create(title="POST CREATED", content="POST WAS CREATED")
        self.second_post = Post.objects.create(title="POST CREATED 2", content="POST WAS CREATED 2")

        self.valid_post = {
            "title" : "post is changed",
            "content": "post is changed"
        }
        self.invalid_post = {
            "title": "",
            "content": "post change"
        }
    def test_valid_update_post(self):
        '''
        Validated data case 
        '''
        response = self.client.put(
            reverse('post_detail', kwargs={'pk': self.first_post.pk}),
            data = json.dumps(self.valid_post),
            content_type = 'application/json'
        )
        self.assertEqual(response.status_code, status.HTTP_200_OK)

    def test_invalid_update_post(self):
        '''
        Invalid data case 
        '''
        response = self.client.put(
            reverse('post_detail', kwargs={'pk': self.second_post.pk}),
            data = json.dumps(self.invalid_post),
            content_type = 'application/json'
        )
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)


View 中还有一个小错误: serializer = PostSerializer(post, data=data) 并且应该替换为 serializer = PostSerializer(post, data=request.data)

最佳答案

在第一个测试中,您成功了:

response = self.client.get(reverse('posts'))

接下来,您对路径进行硬编码,缺少末尾的斜杠。

response = self.client.put('/posts/1', data)

Django 将尝试将 /posts/1 重定向到 /posts/1/。在测试中添加斜杠或找到reverse() 的正确名称,您应该就可以了。

此外,我真的建议使用 DRF 通用 View 。更少的代码,更多的健全性检查:https://www.django-rest-framework.org/api-guide/generic-views/

关于python - 在 Django Rest Framework 中测试 PUT 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60892321/

相关文章:

python - 确保两个 Pandas DatetimeIndex 相同?

python - 如何创建 TensorFlow 变量的 Python 列表

python - 使用多个分隔符在 python 中拆分字符串的最佳方法 - 同时保留分隔符

django - 如何使用 Apache 和 Daphne 部署 django channel ?

django - 使用 Django 用户管理员使电子邮件字段独一无二

测试 Outlook VSTO 插件

python - MySQLdb连接问题

python - 你如何管理你的 Django 应用程序?

android - Espresso 中多个 View 的断言

c++ - fgetwc EOF 循环测试失败,但 65535 OK