在 DRF 中支持 JSON 和文件分段上传的测试
Posted
技术标签:
【中文标题】在 DRF 中支持 JSON 和文件分段上传的测试【英文标题】:A Test to Support Both JSON and File Multipart Uploads in DRF 【发布时间】:2015-11-29 13:16:19 【问题描述】:我想为我的 DRF 应用程序编写一个测试,该应用程序使用 multipart 发布 json 和文件。
这是我迄今为止尝试过的,但collection_items
(在创建方法中)是空白。我是否需要修改我的视图以使其正常工作,或者我在下面的测试用例中做错了什么?
我的测试:
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')
这是模型:
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)
序列化器:
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
所以print(item_data)
是空的[],为什么?我该如何解决这个问题?
这是我的全部观点:下面,我需要在这里做点什么吗?
class CollectionListView(generics.ListCreateAPIView):
queryset = Collection.objects.all()
serializer_class = CollectionListSerializer
我正在使用 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')
更新 2
如果我将有效负载更改为使用json.dumps
,它现在似乎可以看到该文件,但当然这不起作用!
payload = json.dumps(
"title": "Test Collection",
"collection_items": ["image": uploaded_file],
)
错误
<SimpleUploadedFile: temp.jpeg (text/plain)> is not JSON serializable
PS
我知道文件正在上传,因为如果我在序列化程序中执行以下操作...
print(self.context.get("request").data['collection_items'])
我明白了
'image': <SimpleUploadedFile: temp.jpeg (text/plain)>
【问题讨论】:
【参考方案1】:使用多部分解析器,您只需在后置参数中传递文件处理程序(参见this)。在您的代码中,您提交了一个 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')
...
我不完全确定嵌套序列化是否有效,但至少文件上传应该有效。
【讨论】:
嗨,我已经根据这个答案用我厌倦的内容更新了我的 OP,但它仍然是空的! :( 请注意,字段图像在 ItemCollectionDetailSerializer 中设置为只读。无论如何,我建议您使用 pdb 跳过序列化程序验证方法以找出问题所在。以上是关于在 DRF 中支持 JSON 和文件分段上传的测试的主要内容,如果未能解决你的问题,请参考以下文章
Django REST framework编写图片上传接口并测试