I am using DjangoRestFramework to make an API. Currently I have OAuth2 authentication working which means I can generate a valid access token to use the API.
How do I upload a user file? I need to upload a file and relate it to the user who uploaded it.
I am currently trying to do it this way
api/views.py:
class FileUploadView(APIView):
parser_classes = (FileUploadParser,)
def put(self, request, filename, format=None):
file_obj = request.FILES['file']
# do stuff
return Response(status=204)
api/urls.py contains this line:
url(r'^files/', 'api.views.FileUploadView'),
but when I try to upload a file I get an error stating that:
'CSRF verification failed. Request aborted'
'Reason given for failure: CSRF cookie not set'
when I try this curl command:
curl -XPUT http://localhost:8000/files/ -H 'Authorization: Bearer some_access_token' -F [email protected]
Here are my REST_FRAMEWORK defaults:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAdminUser',),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.OAuth2Authentication',
)
}
1) In my original code I was expecting a filename parameter to come into my view but I was not parsing it out of the url in urls.py. It should have looked something like this:
url(r'^uploads/(?P<filename>[\w.]{0,256})/$', views.UploadsView.as_view()),
2) I was also not providing the APIView as a view. If you notice above I am specifically calling the .as_view() method.
With the above fixed and implementing POST instead of PUT my code works as expected. Here is my current APIView:
class UploadsView(APIView):
parser_classes = (FileUploadParser,)
permission_classes = (permissions.IsAuthenticated,)
def post(self, request, format=None):
file_obj = request.FILES['file']
print("FILE OBJ: ", file_obj)
return Response(status=201)
Per the Django REST Framework Documentation, "If you're using SessionAuthentication you'll need to include valid CSRF tokens for any POST, PUT, PATCH or DELETE operations.
In order to make AJAX requests, you need to include CSRF token in the HTTP header, as described in the Django documentation."
Alternatively, you can attempt to make this view CSRF Exempt:
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
class FileUploadView(APIView):
parser_classes = (FileUploadParser,)
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
return super(FileUploadView, self).dispatch(request, *args, **kwargs)
def put(self, request, filename, format=None):
file_obj = request.FILES['file']
# do stuff
return Response(status=204)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With