Test for supporting both JSON and multi-file files in DRF

I would like to write a test for my DRF application that hosts both json and file using multipart .

This is what I have tried so far, but collection_items (in the create method) is empty . Do I need to change my mind to make this work correctly, or am I doing something wrong in my test case below?

My test:

  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') 

This is the model:

 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) 

serializers:

 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 

So print(item_data) empty [], why? How to solve this?

This is my view: below, do I need to do something here?

 class CollectionListView(generics.ListCreateAPIView): queryset = Collection.objects.all() serializer_class = CollectionListSerializer 

I am using Django Rest Framework 3.x, Django 1.8.x and Python 3.4.x.

Refresh

I tried below, but still no joy! collection_items empty in my create . This is either due to the fact that this is a nested object, or something should happen in my view.

  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') 

Update 2

If I change my payload to use json.dumps , it looks like it will now see the file, but of course it won't work!

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

Mistake

 <SimpleUploadedFile: temp.jpeg (text/plain)> is not JSON serializable 

PS

I know the file is loading because if I do the following in my serializer ...

 print(self.context.get("request").data['collection_items']) 

I get

 {'image': <SimpleUploadedFile: temp.jpeg (text/plain)>} 
+8
python django django-rest-framework
source share
1 answer

Using a multi-parameter parser, you can simply pass the file handler in the post arguments (see this ). In your code, you are passing the json-encoded part as the data payload and part of the file in the files argument, and I don't think it can work that way.

Try this code:

 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') ... 

I'm not quite sure if nested serialization works, but at least file loading should work.

+5
source share

All Articles