Reputation: 69
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
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>
@Headers()
annotation and use @Multipart
as we're sending multipart/form-data
.@Body
with @Part
That's it!
Upvotes: 1