Search code examples
djangodjango-rest-frameworkdjango-file-upload

Django Rest Framework Excel File Upload


Note: Please read the whole question before marking it as duplicate.

Django has changed ALOT Since a couple of years.

I have already tried all the solutions and read Django Rest Framework Documentation on:

None of the ways work. I also tried uploading using simple Django but that didnt seem to work Either.

The Error I am getting is that request.FILES['file'] is always an empty {}.

Write now my code looks like this

    parser_classes = [MultiPartParser]

    def put(self, request, format=None):
        file_obj1 = request.data['file']
        data = json.loads(request.POST['form'])
        print(file_obj1)

        return Response(status=status.HTTP_201_CREATED)

Like i said I always tried Using FileUploadParser. Same code just replaced MultiPartParser with FileUploadParser. I am using Postman to send an excel file and then reading it. Anyone who has recently upload an excel file in Django Rest Framework can guide me but make sure your code works becuase I have already spent a day and still can't find the solution so far.

Edit: Curl Request from Postman would be: curl --location 'http://localhost:8000/amm-api/upload/upload_workbook/' \ --form '=@"/Users/razan/Projects/HTS/ags-carmax/Robbie_Lisa-Branch.xlsx"'

This is how it looks in Postman enter image description here


Solution

  • After spending 2 days over it I have finally found a way by hit and try. Please try it and let me know. As of today it works on Django 3.8.2

    views.py

    from rest_framework.parsers import FileUploadParser
    import pandas as pd
    from rest_framework import viewsets, permissions
    from rest_framework.views import APIView
    from rest_framework.response import Response
    
    
    class FileUploadView(APIView):
    parser_classes = [FileUploadParser]
    permission_classes = [permissions.AllowAny]
    
    def put(self, request, filename, format=None):
        try:
            file_obj = request.data['file']
            file_content = file_obj.read()
            df = pd.read_excel(file_content, engine='openpyxl')
            return Response({'status': 'success', 'message': 'File uploaded.'})
        except Exception as e:
            error_message = str(e)
            return Response({'status': 'error', 'message': error_message})
    

    urls.py

    from django.urls import path, include, re_path
    from . import views
    from amm_core.views import FileUploadView
    
    urlpatterns = [
        re_path(r'^upload/(?P<filename>[^/]+)$', FileUploadView.as_view())
    ]
    

    settings.py (Make sure to include the certain permissions.)

    'DEFAULT_PERMISSION_CLASSES': [
            'rest_framework.permissions.AllowAny',
            'rest_framework.parsers.JSONParser',
            'rest_framework.parsers.MultiPartParser',
            'rest_framework.parsers.FormParser',
        ],
     'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema'
    

    Then from Postman hit the API with and excel selected. http://localhost:8000/<app-name><optional-sub-appname>/upload/<filename>.xlsx Postman image