Работает на React / Django и столкнулся с проблемой, которую не могу решить.
На внешнем интерфейсе есть следующий JS, отправляющий данные в Django API.В этом случае rejectedDocuemts()
отправляет массив filenames
на сервер, так что в конечном итоге электронное письмо может быть создано и отправлено администратору для просмотра.Файлы, которые не соответствуют утвержденному списку расширений, попадают в этот список.Вот где возникает ошибка.
submitDocuments
- это место, где отправляются файлы, которые соответствуют утвержденному списку расширений файлов.Весь объект files
отправляется на сервер для сохранения.Этот работает отлично.
export function rejectedDocuments(filenames, id) {
return function (dispatch) {
axios.post(
`${URL}/api/${(id)}/documents/upload/error`,
filenames,
{
headers: {
'content-type': 'text/plain',
'Authorization': 'JWT ' + sessionStorage.getItem('token')
}
}
)
}
}
// Creates the error state to be used in components
export function submitDocuments(files, id) {
return function (dispatch) {
const uploaders = _.map(files, f => {
const formData = new FormData();
formData.append('file', f);
return axios.post(
`${URL}/api/${(id)}/documents/upload/success`,
formData,
{
headers: {
'content-type': 'multipart/form-data',
'Authorization': 'JWT ' + sessionStorage.getItem('token')
}
}
)
});
axios.all(uploaders)
.then(response => {
dispatch({
type: SUBMIT,
payload: response[0].status
});
})
}
}
В классе rejectedDocuments
возникает ошибка (Forbidden (CSRF token missing or incorrect.): /api/84/documents/upload/error
).Осматривая заголовки сети, они оба включают Cookie: csrftoken=xyz
.У них обоих одинаковый токен CSRF.
Так что не уверен, что случилось или как обойти это.submitDocuments
отлично работает, и они ничем не отличаются друг от друга, кроме того, что один отправляет файловый объект (submitDocuments
), а другой отправляет массив строк (rejectedDocuments
).
В любомСкорость, вот серверная часть Django:
# documents/urls.py
from django.conf.urls import url
from .views import (
GetDocumentsAPIView,
RejectedDocumentsView,
SaveDocumentAPIView
)
app_name = 'Documents'
urlpatterns = [
url(r'^documents/upload/success', SaveDocumentAPIView.as_view(), name='upload'),
url(r'^documents/upload/error', RejectedDocumentsView.as_view(), name='rejected'),
url(r'^documents/', GetDocumentsAPIView.as_view(), name='documents')
]
# documents/views.py
import datetime
from django.contrib.auth import get_user_model
from django.db.models import Max
from django.views import View
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.status import HTTP_200_OK, HTTP_400_BAD_REQUEST
from rest_framework.views import APIView
from .serializers import GetDocumentsSerializer, SaveDocumentSerializer
from .models import Uploads
User = get_user_model()
# Create your views here.
class GetDocumentsAPIView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request, *args, **kwargs):
data = {'id': request.user.id}
if kwargs:
data['sur_id'] = kwargs.get('sur_id')
serializer = GetDocumentsSerializer(data=data)
if serializer.is_valid(raise_exception=True):
return Response(serializer.data, status=HTTP_200_OK)
return Response(serializer.errors, status=HTTP_400_BAD_REQUEST)
class RejectedDocumentsView(View):
def post(request):
print(request)
class SaveDocumentAPIView(APIView):
permission_classes = [IsAuthenticated]
def post(self, request, *args, **kwargs):
max_id = Uploads.objects.all().aggregate(Max('id'))
if max_id['id__max'] == None:
max_id = 1
else:
max_id = max_id['id__max'] + 1
data = {
'user_id': request.user.id,
'sur_id': kwargs.get('sur_id'),
'co': User.objects.get(id=request.user.id).co,
'date_uploaded': datetime.datetime.now(),
'size': request.FILES['file'].size
}
filename = str(data['co']) + '_' + str(data['sur_id']) + '_' + str(max_id) + '_' + request.FILES['file'].name
data['doc_path'] = filename
self.save_file(request.FILES['file'], filename)
serializer = SaveDocumentSerializer(data=data)
if serializer.is_valid(raise_exception=True):
serializer.save()
return Response(serializer.data, status=HTTP_200_OK)
return Response(serializer.errors, status=HTTP_400_BAD_REQUEST)
# Handling the document
def save_file(self, file, filename):
with open('flu/' + filename, 'wb+') as destination:
for chunk in file.chunks():
destination.write(chunk)
Не публикует сериализацию, потому что RejectedDocumentsView(View)
не нужен, и кажется, что ошибка происходит, прежде чем он делает этовид.