3
votes

I’ve been working on a Django project that requires a file upload. I use API approach in my app designs using django-rest-framework. I created my model, APIView, and serializer but unfortunately every time the request goes through the serializer the upload.data returns {'file': None}. If I just use request.FILES['file'] it returns the file no problem but I want to use the serialized data. I'm using dropzone js on the front end to upload the file. Here is my code below.

HTML

{% extends 'base_profile.html' %}
{% load static %}
{% block title %}File Import{% endblock %}
{% block pagetitle %}File Import{% endblock %}
{% block content %}
<div class="widget">
    <div class="widget-heading clearfix">
      <h3 class="widget-title pull-left list-inline">CSV </h3>
      <button type="button" class="btn btn-primary pull-right"><i class="ti-upload mr-5"></i> Upload</button>
    </div>
    <div class="widget-body">
      <form id="type-dz" class="dropzone">{% csrf_token %}</form>
    </div>
</div>

{% endblock %}
{% block js %}
<script type="text/javascript">
    $("#type-dz").dropzone({
        url: "{% url 'api_import:file' %}",
        paramName: "file",
        acceptedFiles: ".csv",
        maxFilesize: 2,
        maxThumbnailFilesize: .5,
        dictDefaultMessage: "<i class='icon-dz fa fa-file-text-o'></i>Drop files here to upload"
});
</script>
{% endblock %}

urls.py

urlpatterns = [
    url(r'^api/import/', include('api.import_api.urls', namespace="api_import")),
]

api/urls.py

urlpatterns = [
    url(r'^file/', FileImport.as_view(), name='file'),
]

views.py

class FileImport(APIView):
    parser_classes = (MultiPartParser, FormParser,)
    serializer = ImportSerializer

    def post(self, request, format=None):
        upload = self.serializer(data=request.FILES)

        if upload.is_valid():
            file = FileUpload(file=upload.data['file'], uploaded_by=request.user.profile)
            file.save()
            return Response({'success': 'Imported successfully'})
        else:
            return Response(upload.errors, status=400)

serializers.py

class ImportSerializer(serializers.Serializer):
    file = serializers.FileField()

models.py

class FileUpload(models.Model):
    file = models.FileField(upload_to='files/%Y/%m/%d')
    date_uploaded = models.DateTimeField(auto_now=True)
    uploaded_by = models.ForeignKey('UserProfile', blank=True, null=True)
1
You need to use FileUploadParser.Burhan Khalid

1 Answers

4
votes

It would be helpful to see how you are uploading the file. If you are using a multipart/form-data request and providing the json for "file" properly, the most likely thing is that the file is failing validation for some reason.

If you can, it might also be helpful to test from the browsable api (as that guarantees nothing is wrong with your request).

Edit:
The issue was that the validated_data field should be used instead of the data field after calling is_valid().