【问题标题】:MultiValueDictKeyError when upload an Image using Django Test使用 Django 测试上传图像时出现 MultiValueDictKeyError
【发布时间】:2019-07-27 05:07:55
【问题描述】:

您好,我正在尝试制作一个测试用例来测试我的上传图片 API。但我认为当我传递 request.FILES 的文件时我没有返回任何东西

#models.py
class Image(models.Model):
    name = models.CharField(max_length=200)
    imagefile = models.ImageField(
        null=True,
        blank=True,
        max_length=500,
        upload_to='temp/images/')
    def __str__(self):
        return self.name

#views.py
class ImagesView(APIView):
    def post(self, request):
        print("DATA!!!", request.data)
        print("FILE!!!", request.FILES)
        params = Image(
            imagefile=request.FILES['image'])
        params.save()
        print(params)

        return Response({"status": "ok"})

#test.py
class CanalImagesApiTests(TestCase):
    fixtures = []
    def test_post_image(self):
        c = Client()
        response = c.post('/admin/login/', {'username': 'admin', 'password': 'passwrd'})
        filename = 'data/sample_image.jpg'
        name = 'sample_image.jpg'
        data = {"data": "passthis"}
        print(to_upload)
        with open(filename, 'rb') as f:
            c.post('/images/', data=data, files={"name": name, "image": f}, format='multipart')
        response = c.get('/images/')
        results = response.json()

我的request.FILES 是空的:<MultiValueDict: {}> 我的测试出错:django.utils.datastructures.MultiValueDictKeyError: 'image'

【问题讨论】:

    标签: python django post django-rest-framework django-testing


    【解决方案1】:
    • 您可以在数据字典中传递文件对象。
    • 不需要files 参数。 format 参数表示输出格式,不是输入格式。
    • 如果您正在测试 Django REST Framework API,您可以使用 APITestCase 而不是 TestCase。这使您可以测试一些方法,例如PUT
    from rest_framework import status
    from rest_framework.test import APITestCase
    
    
    class CanalImagesApiTests(APITestCase):
        def test_post_image(self):
            with open('data/sample_image.png', 'rb') as f:
                data = {
                    "data": "passthis",
                    "image": f,
                }
    
                response = self.client.post('/images/', data=data)
                self.assertEqual(response.status_code, status.HTTP_200_OK)
                self.assertEqual(response.json(), {"status": "ok"})
    

    测试结果(通过):

    DATA!!! <QueryDict: {'data': ['passthis'], 'image': [<InMemoryUploadedFile: sample_image.png (image/png)>]}>
    FILE!!! <MultiValueDict: {'image': [<InMemoryUploadedFile: sample_image.png (image/png)>]}>
    

    【讨论】:

    • 我收到错误:AssertionError: Test data contained a dictionary value for key 'data', but multipart uploads do not support nested data. You may want to consider using format='json' in this test case.
    • 我的“数据”有另一本字典,这就是原因。
    • 您不能使用Content-Type: multipart/form-data 发送嵌套字典。您可以使用Content-Type: application/json 发送嵌套字典,但文件必须以base64 编码传输,开销约为33%。我的建议是将上传文件的API和上传数据的API分开。
    猜你喜欢
    • 2018-04-01
    • 1970-01-01
    • 2016-07-16
    • 2011-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-15
    相关资源
    最近更新 更多