python - 在 Django Rest Framework 中测试 PUT 方法
问题描述
我正在尝试在 django rest 框架中测试 PUT 方法。我得到 HttpResponsePermanentRedirect 而不是响应对象。我对 put 方法的视图设置为在成功更新后发送状态 200。错误:
self.assertEqual(response.data, serializer.data) AttributeError: 'HttpResponsePermanentRedirect' 对象没有属性 '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)
视图.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)
在视图中也有一个小错误:
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 通用视图。更少的代码,更多的完整性检查:https ://www.django-rest-framework.org/api-guide/generic-views/
推荐阅读
- ios - 生成 iOS Swift 测试报告的工具有哪些?
- html - 使用 Angular 设置 maxLength 属性 onInit
- javascript - TypeScript - 在使用别名解构对象时指定类型
- firebase - 将 FirebaseAuth 的当前会话/令牌从本机 Android 应用程序传递到 WebView 的 Firebase 应用程序
- c# - 如何将现有的 IQueryable 元素插入到 EF Core 中的 ThenInclude 方法
- python - 填充字符图像中的白洞的算法
- haxe - 石灰无法构建 html5 目标,编译导致各种类型和导入错误
- c++-cx - C++/CX 中的列表集合
- mysql - 需要对数据库模型的建议
- c# - Visual Studio 发布数据库项目