如何在Django REST Framework中测试FileField

时间:2016-10-05 07:17:02

标签: python django serialization django-rest-framework

我正在测试这个序列化器:

class AttachmentSerializer(CustomModelSerializer):
    order = serializers.PrimaryKeyRelatedField()
    file = FileField()

    class Meta:
        model = Attachment
        fields = (
            'id',
            'order',
            'name',
            'file_type',
            'file',
            'created_at',
        )

我的测试只是检查它是否有效:

    def test_serializer_create(self):
        self.data = {
            'order': self.order.pk,
            'name': 'sample_name',
            'file_type': 'image',
            'created_at': datetime.now(),
            'file': open(self.image_path, 'rb').read()
        }

        serializer = AttachmentSerializer(data=self.data)

        self.assertTrue(serializer.is_valid())

我经常遇到这个错误:

{'file': ['No file was submitted. Check the encoding type on the form.']}

我试图以多种不同的方式创建文件,例如使用StringIO / BytesIO,File等无济于事。

可能出现什么问题?

3 个答案:

答案 0 :(得分:0)

问题是您将打开的文件传递给APIClient / APIRequestFactory,而不是传递给视图本身。 Django请求会将文件包装到UploadedFile,这是你应该使用的。

答案 1 :(得分:0)

from django.core.files.uploadedfile import SimpleUploadedFile
content = SimpleUploadedFile("file.txt", "filecontentstring")
data = {'content': content}

尝试这样的smth,因为如果你检查FileField序列化程序的代码 - 它需要具有名称和大小的UploadedFile:

    def to_internal_value(self, data):
    try:
        # `UploadedFile` objects should have name and size attributes.
        file_name = data.name
        file_size = data.size
    except AttributeError:
        self.fail('invalid')

和StringIO或打开的文件对象没有size属性。

答案 2 :(得分:0)

我遇到了类似的问题。事实证明Django REST Framework FileField不能与JSON API解析器一起使用。 DRF documentation states表示“大多数解析器(例如JSON)不支持文件上传。”

您的问题并未显示您配置的解析器,但鉴于JSON的普遍性,可能是罪魁祸首。您可以按照here的说明,为整体或特定的API视图设置不同的解析器。

一旦解析器问题解决,我就可以使用Django File进行测试,但是也许其他方法也可以工作:

from django.core.files import File

def test_create(self):
    ...
    data = {
        'file': File(open(path_to_test_file, 'rb')),
    }
    ...