1

I would like to send a photo from android app to django. I use django rest framework as backend.

When i post through postman everything works and I get 201. But when i try through android, I get 400. Where is the problem? Thanks for help in advance

My model:

class Photo(models.Model):
    file = models.FileField(blank=False, null=False)

My django view:

    def post(self, request, *args, **kwargs):
        parser_classes = (FileUploadParser,)
        file_serializer = PhotoSerializer(data=request.data)
        if file_serializer.is_valid():
            file_serializer.save()
            return Response(file_serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Retrofit request:

    @Headers("content-type: multipart/form-data;")
    @POST("upload")
    fun checkItem(@Body image: MultipartBody.Part): Observable<CheckDto>

That's how i send my photo from android app:

        val requestFile: RequestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file)
        val body: MultipartBody.Part = MultipartBody.Part.createFormData("file", file.toString(), requestFile)

        val requestInterface = ApiClient.getClient().create(ApiInterface::class.java)
        myCompositeDisposable?.add(requestInterface.checkItem(body)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io())
            .subscribe({ result ->
                Log.d("Request", result.toString())
            }, { error ->
                error.printStackTrace()
            })
        )

1 Answer 1

1

You're receiving 400 Bad Request because of the data you're trying to send. Your server accepts multipart/form-data whereas you're sending serialized object from Android.

You might ask now that how it's even possible?

Well, when you use Retrofit's @Body annotation, the object will be serialized using the Retrofit instance Converter and the result will be set directly as the request body.

So, what's the solution?

Just replace your code from

@Headers("content-type: multipart/form-data;")
@POST("upload")
fun checkItem(@Body image: MultipartBody.Part): Observable<CheckDto>

to

@Multipart
@POST("upload")
fun checkItem(@Part image: MultipartBody.Part): Observable<CheckDto>
  1. Remove @Headers() annotation and use @Multipart as we're sending multipart/form-data.
  2. Replace @Body with @Part

That's it!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.