在DRF中支持JSON和文件分段上传的测试

Pro*_*eus 8 python django python-3.x django-rest-framework

我想为我的DRF应用程序编写测试,该应用程序使用multipart发布json和文件.

这是我到目前为止所尝试的但是collection_items(在create方法中) 是空白的.我是否需要修改我的视图以使其正常工作,或者我在下面的测试用例中做错了什么?

我的测试:

    image = Image.new('RGB', (100, 100))
    tmp_file = tempfile.NamedTemporaryFile(suffix='.jpg')
    image.save(tmp_file)

    files = {"collection_items": [{"image": tmp_file}]}
    payload = json.dumps({
        "title": "Test Collection",
    })

    self.api_factory.credentials(Authorization='Bearer ' + self.token)
    response = self.api_factory.post(url, data=payload, files=files, format='multipart')
Run Code Online (Sandbox Code Playgroud)

这是模型:

class Collection(models.Model):

    title = models.CharField(max_length=60)
    collection_items = models.ManyToManyField('collection.Item')


class Item(models.Model):
    image = models.ImageField(upload_to="/",null=True, blank=True)
Run Code Online (Sandbox Code Playgroud)

串行器:

class ItemCollectionDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = Item
        fields = ('id', 'image')
        read_only_fields = ('image',)


class CollectionListSerializer(serializers.ModelSerializer):

    url = serializers.HyperlinkedIdentityField(view_name='col_detail')
    collection_items = ItemCollectionDetailSerializer(many=True, required=True)

    class Meta:
        model = Collection
        fields = ('url', 'id', 'collection_items')

    def create(self, validated_data):

        item_data = validated_data.pop('collection_items')

        print(item_data)  # <----- **EMPTY HERE???**

        etc ....edited for brevity
Run Code Online (Sandbox Code Playgroud)

那么print(item_data)空[],为什么?我该如何解决这个问题?

这是我的全部观点:下面,我需要在这里做些什么吗?

class CollectionListView(generics.ListCreateAPIView):

    queryset = Collection.objects.all()
    serializer_class = CollectionListSerializer
Run Code Online (Sandbox Code Playgroud)

我正在使用Django Rest Framework 3.x,Django 1.8.x和Python 3.4.x.

更新

我试过下面但仍然没有快乐!collection_items在我的身上是空的create.这或者与它是一个嵌套对象或者在我的视图中必须发生的事实有关.

    stream = BytesIO()
    image = Image.new('RGB', (100, 100))
    image.save(stream, format='jpeg')
    uploaded_file = SimpleUploadedFile("temp.jpeg", stream.getvalue())

    payload = {
        "title": "Test Collection",
        "collection_items": [{"image": uploaded_file}],
    }

    self.api_factory.credentials(Authorization='Bearer ' + self.test_access.token)
    response = self.api_factory.post(url, data=payload, format='multipart')
Run Code Online (Sandbox Code Playgroud)

更新2

如果我改变我的有效负载使用json.dumps它似乎现在看到文件,但当然这不起作用!

payload = json.dumps({
            "title": "Test Collection",
            "collection_items": [{"image": uploaded_file}],
        })
Run Code Online (Sandbox Code Playgroud)

错误

<SimpleUploadedFile: temp.jpeg (text/plain)> is not JSON serializable
Run Code Online (Sandbox Code Playgroud)

PS

我知道文件正在上传,因为如果我在序列化程序中执行以下操作...

print(self.context.get("request").data['collection_items'])
Run Code Online (Sandbox Code Playgroud)

我明白了

{'image': <SimpleUploadedFile: temp.jpeg (text/plain)>}
Run Code Online (Sandbox Code Playgroud)

duk*_*ody 9

使用多部分解析器,您只需在post参数中传递文件处理程序(请参阅此内容).在您的代码中,您提交了一个json编码的部分作为数据有效负载和files参数中的文件部分,我不认为它可以这样工作.

试试这段代码:

from PIL import Image
from io import BytesIO
from django.core.files.uploadedfile import SimpleUploadedFile

stream = BytesIO()
image = Image.new('RGB', (100, 100))
image.save(stream, format='jpeg')

uploaded_file = SimpleUploadedFile("file.jpg", stream.getvalue(), content_type="image/jpg")
payload = {
    "title": "Test collection",
    "collection_items": [{"image": uf}],
}
self.api_factory.credentials(Authorization='Bearer ' + self.token)
self.api_factory.post(url, data=payload, format='multipart')
...
Run Code Online (Sandbox Code Playgroud)

我不完全确定嵌套序列化是否有效,但至少文件上传应该有效.