1

I've been looking at this for a while now, I'm sending out a post request with multipart/form-data, but get back the error ["This field is required."] for each field that I'm supposed to populate with the request.

Here's the Serializer:

class InvoiceUploadSerializer(serializers.Serializer):
    serial=serializers.CharField(max_length=256, required=True)
    amount=serializers.CharField(max_length=256, required=True)
    debtor=serializers.CharField(max_length=256, required=True)
    dateout=serializers.CharField(max_length=256, required=True)
    expiration=serializers.CharField(max_length=256, required=True)
    invoicefile=serializers.FileField()

    class Meta:
        fields=('serial', 'amount', 'debtor', 'dateout', 'expiration', 'invoicefile',)

And the View:

class InvoiceViewSet(viewsets.ModelViewSet):
    queryset=Invoices.objects.all()
    serializer_class=InvoiceSerializer
    parser_classes=(MultiPartParser, FormParser)

    def get_permissions(self):
        if self.request.method in permissions.SAFE_METHODS:
            return (permissions.AllowAny(),)

        if self.request.method == 'POST':
            return (permissions.IsAuthenticated(),)

        return (permissions.IsAuthenticated(), IsAccountOwner(),)

    def create(self, request):
        serializer=InvoiceUploadSerializer(data=request.data)
        if serializer.is_valid():
            ... handle serializer

            return Response(serializer.validated_data, status=status.HTTP_201_CREATED)
        else:
            emessage=serializer.errors
            return Response({
                'status': 'Bad request',
                'message': emessage,
            }, status=status.HTTP_400_BAD_REQUEST

Here is a picture showing the browser console with the outgoing request: enter image description here

And lastly the error message from the browser console: enter image description here

I don't understand why it tells me all fields are missing, the header is set correctly and it looks fine to me.

Switched up the view-code and urls still the same error, New with the same problem:

class InvoiceUploadView(APIView):
    parser_classes=(MultiPartParser, FormParser)
    def get_permissions(self):
        return (permissions.AllowAny(),)

    def post(self, request):
        serializer=InvoiceUploadSerializer(data=request.POST)
        if serializer.is_valid():
            return Response(serializer.validated_data, status=status.HTTP_201_CREATED)
        else:
            emessage=serializer.errors
            return Response({
                'status': 'Bad request',
                'message': emessage,
            }, status=status.HTTP_400_BAD_REQUEST)
Marcus Grass
  • 1,043
  • 2
  • 17
  • 38
  • My guess is that validation is run by `InvoiceSerializer` before `create` method is executed.. you can add `print request.data` as first line inside this method just to make sure. – mariodev May 29 '18 at 07:58
  • @mariodev I tried to print, it outputs an empty querydict. If i set up a `for key in request.data: print(key)` Nothing is output. I edited the code in my post with the change in views. Suspicious that request.data in empty. – Marcus Grass May 29 '18 at 08:39

1 Answers1

1

Your POST request is missing the multipart boundary in it's Content-Type header. Without that it is possible that the application won't be able to parse the request payload - and validation would fail because data would be missing.

The browser would normally set the Content-Type header and boundary for you. Perhaps you are overriding that and setting the Content-Type header yourself somewhere? If you are, unset it and try making another request.

Will Keeling
  • 22,055
  • 4
  • 51
  • 61
  • Forgot to come back and respond to this, but you're completely right. When sending FormData, the browser sets the correct header with the correct boundary automatically, my setting the header manually was what messed it up for my back-end! – Marcus Grass May 31 '18 at 17:54