bwnuk
bwnuk

Reputation: 69

Problem with upload image from android(retrofit) to django

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()
            })
        )

Upvotes: 1

Views: 806

Answers (1)

Shashanth
Shashanth

Reputation: 5190

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!

Upvotes: 1

Related Questions