Я строю проект для изучения Django-rest-framework и React, и наткнулся на проблему. Когда я пытаюсь сделать POST-запрос с почтальоном, посылая и заголовок, и изображение, все работает правильно, я получаю ответ 200, дБ обновляется и изображение сохраняется в папку. При использовании API выборки на веб-странице я также получаю ответ 200, заголовок устанавливается в БД, но изображение не сохраняется в папке.
Я запускаю это локально, используя React, response-thunk, fetch и django-rest-framework. Я попытался вручную настроить парсеры на стороне API и получил те же результаты, и, учитывая, что он действительно работает с почтальоном, я не думаю, что проблема заключается в API.
Я попытался проверить заголовки и тело из запроса Почтальон и выборки, но они выглядят в основном одинаково:
Почтальон:
POST http://127.0.0.1:8000/products/ HTTP/1.1
Authorization: JWT *<key>*
Content-Type: multipart/form-data; boundary=--------------------------137332308863963697302646
cache-control: no-cache
Postman-Token: 7205a938-e8ac-4377-87ef-62c1c9bdbae4
User-Agent: PostmanRuntime/7.4.0
Accept: */*
Host: 127.0.0.1:8000
accept-encoding: gzip, deflate
content-length: 1428354
Connection: keep-alive
----------------------------137332308863963697302646
Content-Disposition: form-data; name="title"
test app
----------------------------137332308863963697302646
Content-Disposition: form-data; name="image1"; filename="20180801_09550558.jpg"
Content-Type: image/jpeg
*weird characters*
----------------------------137332308863963697302646
Реагировать / выборки:
POST http://127.0.0.1:8000/products/ HTTP/1.1
Host: 127.0.0.1:8000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0
Accept: */*
Accept-Language: pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost:3000/addproduct
authorization: JWT *<key>*
content-type: multipart/form-data; boundary=---------------------------312531002128989
origin: http://localhost:3000
Content-Length: 1428331
Connection: keep-alive
-----------------------------312531002128989
Content-Disposition: form-data; name="title"
test app
-----------------------------312531002128989
Content-Disposition: form-data; name="image01"; filename="20180801_09550558.jpg"
Content-Type: image/jpeg
*weird characters*
-----------------------------312531002128989
settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
models.py
class Products(models.Model):
owner = models.CharField(max_length=250)
title = models.CharField(max_length=250)
image1 = models.ImageField(upload_to='uploaded_media', null=True)
views.py
class ProductsViewSet(viewsets.ModelViewSet):
permission_classes = [permissions.IsAuthenticated, ]
serializer_class = ProductsSerializer
pagination_class = StandardResultsSetPagination
def get_queryset(self):
user = self.request.user
return Products.objects.filter(owner=user)
def create(self, request, *args, **kwargs):
user = self.request.user
serializer = ProductsSerializer(data=request.data)
if not serializer.is_valid(raise_exception=False):
return Response({"status":"failure","status_message":serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
serializer.save(owner=user)
return Response({"status":"success","status_message":"Product listed succesfully"}, status=status.HTTP_200_OK)
serializer.py
class ProductsSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='user')
class Meta:
model = Products
fields = ('id', 'owner', 'title', 'image01')
действия \ listImage.js
export const newProduct = (title, image01) => {
return (dispatch, getState) => {
const token = getState().auth.token;
let headers = {};
let body = new FormData();
body.append("title", `${title}`);
body.append("image01", image01);
if (token) {
headers["Authorization"] = `JWT ${token}`;
}
return fetch("http://127.0.0.1:8000/products/", {
headers,
body,
method: "POST"})
.then(res => {
if (res.status === 200 || res.status === 201) {
dispatch({type: 'LISTED_SUCCESSFULLY', data: res.data })
throw res;
} else {
dispatch({type: 'LISTED_ERROR', data: res.data })
throw res;
}
})
}
}