javascriptjquerypythondjangoajax-upload

Django ajaxuploader 400 badrequest error


Submitted.html The JS is also surrounded by a document.ready function

var uploader = new qq.FileUploader({
            action: "{% url 'QCOMLTE:imager' %}",
            element: $('#file-uploader')[0],
            multiple: true,
            onComplete: function(id, fileName, responseJSON) {
                if(responseJSON.success) {
                    alert("success!");
                } else {
                    alert("upload failed!");
                }
            },
            onAllComplete: function(uploads) {
                // uploads is an array of maps
                // the maps look like this: {file: FileObject, response: JSONServerResponse}
                alert("All complete!");
            },
            params: {
                'csrf_token': "{{  csrf_token }}",
                'csrf_name': 'csrfmiddlewaretoken',
                'csrf_xname': 'X-CSRFToken'
            }
        });

elsewhere in the html body

<div id="file-uploader">
    <noscript>
        <p>Please enable JavaScript to use file uploader.</p>
    </noscript>
</div>

urls.py

urlpatterns = patterns('',
                   url(r"^Submitted/$", views.HybridDetailView.as_view(), name='Submitted'),
                   url(r'^(?P<object_type>\w+)/process/$', views.process, name='process'),
                   url(r'^(?P<object_type>\w+)/$', views.generic_view, name='generic'),
                   url("$^", views.head, name='head'),
                   url("uploader", views.upload, name= 'imager'),
)

views.py

@AjaxFileUploader
def upload(request):
    response = {'files': []}
    script_dir = os.path.dirname(__file__)
    # Loop through our files in the files list uploaded
    print('request',request)
    print(request.FILES)
    for item in request.FILES.getlist('files[]'):
        file = UploadedFile(item)
        with open(script_dir + '/Excel/' + file.name) as destination:
            for chunk in file.chunks():
                destination.write(chunk)
        response['files'].append(file)
        print('appended')

return HttpResponse(json.dumps(response), content_type='application/json')

also contains 'ajaxuploader' in the installed apps list

When I try to submit a file through the button it sends the post call but receives a 400 (BAD REQUEST) Error. It's not even reaching the python from what I can tell, at least not the view code. It seems to form the request URL correctly

http://localhost:8000/QCOMLTE/uploader?qqfile=powered_by.png

And when you go to the URL it sends a message stating that post calls are only allowed. This is similar to Default django-ajax-uploader with s3 backend gives MalformedXML error Except that I'm not using any backends, just trying to grab the file/s and save them to a directory.

UPDATE 8/25/14: Removed the decorator from the view. This results in the error not being sent. After printing the request it becomes evident that the file is being sent to the GET path instead of the FILE path. I don't know how to change this.


Solution

  • After finding this Need a minimal Django file upload example

    I preceded to try and imitate it, to find that the FILE and POST requests were actually going through, unlike the ajax/jquery I was using. The JQuery was

           $('#uploadform').submit(function (e){
                console.log('submitting')
                var data = new FormData($('#uploadform').get(0));
    
                $.ajax({
                    type: 'POST',
                    url: "{% url 'QCOMLTE:imager' %}",
                    data: data,
                    success: function(data){console.log(data)},
                    error: function(data){console.log(data)},
                    cache: false,
                    processData: false,
                    contentType: false
                });
                e.preventDefault()
            });
    

    except the type was below URL. I tried changing it to a $.post request and it was trying to post to the wrong URL then... So I decided to change it back, and this time put type at the top of the ajax call. It then worked... and still does after much testing.