0

I'm trying to send some data and an image and put them into their own models.

I can see the data that comes to the view if I print it:

<QueryDict: {
  'id': ['2f44ab21-4e05-4e0a-ade1-05cdbdbf1cab'], 
  'name': ['NewFooBar'], 
  'image': ["{
     'image': <tempfile._TemporaryFileWrapper object at 0x7f766a229ac0>, 
     'tool': '2f44ab21-4e05-4e0a-ade1-05cdbdbf1cab', 
     'id': 'ae5d04ed-1e03-4111-b584-9db947068d38'
     }"]
  }
>

I can also print out the serializer before checking if is_valid. And there I see the data:

NestedToolSerializer(data=<QueryDict: {
  'id': ['2f44ab21-4e05-4e0a-ade1-05cdbdbf1cab'], 
  'name': ['NewFooBar'], 
  'image': ["{
     'image': <tempfile._TemporaryFileWrapper object>, 
     'tool': '2f44ab21-4e05-4e0a-ade1-05cdbdbf1cab', 
     'id': 'ae5d04ed-1e03-4111-b584-9db947068d38'}"
     ]}>):
    id = UUIDField(read_only=True)
    image = ImageToolSerializer():
        id = UUIDField(read_only=True)
        tool = PrimaryKeyRelatedField(queryset=Tool.objects.all())
        image = ImageField(allow_null=True, max_length=100, required=False)
    name = CharField(max_length=70)
    description = CharField(allow_blank=True, required=False, style={'base_template': 'textarea.html'})
    keeper = PrimaryKeyRelatedField(allow_null=True, queryset=CustomUser.objects.all(), required=False)

I never get serializer.is_valid() but I get the serializer.errors and it says:

{'image': [ErrorDetail(string='This field is required.', code='required')]}

This is my unittest:

def test_upload_image_when_creating_tool(self):
        """ Creating a tool and upload image at the same time """
        uuidTool = '2f44ab21-4e05-4e0a-ade1-05cdbdbf1cab'
        uuidImage = 'ae5d04ed-1e03-4111-b584-9db947068d38'
        
        with tempfile.NamedTemporaryFile(suffix='.jpg') as ntf:
            img = Image.new('RGB', (10, 10))
            img.save(ntf, format='JPEG')
            ntf.seek(0)
            payload = {'id': uuidTool, 'name': 'NewFooBar',
                       'image': [{'image': ntf, 'tool': uuidTool,
                                  'id': uuidImage, }, ], }
            response = self.client.post(NESTED_URL,
                                        payload, format='multipart',)

        print('    UNITTEST     ')
        print(response.data)
        tool = Tool.objects.get(id=uuidTool)
        image = ImageTool.objects.get(id=uuidImage)
        print(response.data)

        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertTrue(tool)
        self.assertTrue(image)
        self.assertTrue(os.path.exists(image.image.path))
        image.image.delete()

This is my View:

class ToolPostUpload(views.APIView):
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)
    parser_classes = (MultiPartParser, FormParser, JSONParser)

    def post(self, request, format=None):
        print('    VIEW     ')
        print(request.data)
        serializer = NestedToolSerializer(data=request.data)
        print('     serializer.data     ')
        print(serializer)

        if serializer.is_valid():
            serializer.save()
            return Response(
                serializer.data,
                status=status.HTTP_200_OK,
            )

        return Response(
            serializer.errors,
            status=status.HTTP_400_BAD_REQUEST,
        )

And my serializer:

class ImageToolSerializer(serializers.ModelSerializer):
    """Serialize image for tool"""

    class Meta:
        model = ImageTool
        fields = ['id', 'tool', 'image']
        read_only_fields = ('id',)


class NestedToolSerializer(WritableNestedModelSerializer):
    """ Serilizer for tool nested serializers """

    # Reverse FK relation
    image = ImageToolSerializer()

    class Meta:
        model = Tool
        fields = ('id', 'image', 'name', 'description',
                  'keeper')
        extra_kwargs = {'image': {'required': False}}
sumpen
  • 503
  • 6
  • 19
  • maybe `image = ImageToolSerializer(required=False)` ? – JPG May 09 '21 at 18:16
  • That just makes is not required to have an image to the Post. The problem is that the image I'm trying to Post does not end up into the image table. – sumpen May 09 '21 at 18:22
  • 1
    It seems you are sending the `image` within an array, but, Django expect it to be a `dict` – JPG May 09 '21 at 18:26
  • @JPG Yeah, when I use dict I get this: "AssertionError: Test data contained a dictionary value for key 'image', but multipart uploads do not support nested data. You may want to consider using format='json' in this test case" And when I use json as format i get this: "UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte" I'm really stuck – sumpen May 09 '21 at 18:52

0 Answers0