django ajax/jquery文件上传

django ajax/jquery文件上传,django,django-models,django-templates,django-forms,django-views,Django,Django Models,Django Templates,Django Forms,Django Views,我试图复制Alex Kuhl在其优秀帖子中给出的示例: 然而,我在复制这方面并不太成功 ####### upload_page.html {% extends "base.html" %} {% load i18n %} {% block title %}Blog Post: Upload Files.{% endblock %} {% block content %} <div id="maintext"> <p>To upload a file, clic

我试图复制Alex Kuhl在其优秀帖子中给出的示例:

然而,我在复制这方面并不太成功

####### upload_page.html  

{% extends "base.html" %}
{% load i18n %}
{% block title %}Blog Post: Upload Files.{% endblock %}

{% block content %} 
<div id="maintext"> 
<p>To upload a file, click on the button below.</p>
<div id="file-uploader">
<noscript>
<p>Please enable JavaScript to use file uploader.</p>
<!-- or put a simple form for upload here -->
</noscript>
</div>
<script>
    function createUploader(){
    var uploader = new qq.FileUploader( {
        action: "{% url ajax_upload %}",
        element: $('#file-uploader')[0],
        multiple: false,
        onComplete: function( id, fileName, responseJSON ) {
          if( responseJSON.success )
        alert( "success!" ) ;
          else
        alert( "Sorry, your upload has failed! Please contact us by telephone or email." ) ;
        },
        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',
        },
      } ) ;
    }

    // in your app create uploader as soon as the DOM is ready
    // don't wait for the window to load
    window.onload = createUploader;
</script>
</div>
{% endblock %}
URL.py如下所示:

############### views.py
def upload_page( request ):
    ctx = RequestContext( request, {
        'csrf_token': get_token( request ),
    })
    return render_to_response( 'success/upload_page.html', ctx )

def save_upload( uploaded, filename, raw_data ):
    filename = settings.UPLOAD_STORAGE_DIR
    '''
    raw_data: if True, uploaded is an HttpRequest object with the file being
        the raw post data
        if False, uploaded has been submitted via the basic form
        submission and is a regular Django UploadedFile in request.FILES
    '''
    try:
        from io import FileIO, BufferedWriter
        with BufferedWriter( FileIO( filename, "wb" ) ) as dest:
            # if the "advanced" upload, read directly from the HTTP request
            # with the Django 1.3 functionality
            if raw_data:
                foo = uploaded.read( 1024 )
                while foo:
                    dest.write( foo )
                    foo = uploaded.read( 1024 )
            # if not raw, it was a form upload so read in the normal Django chunks fashion
            else:
                for c in uploaded.chunks( ):
                    dest.write( c )
            # got through saving the upload, report success
            return True
    except IOError:
        # could not open the file most likely
        pass
        return False

def ajax_upload( request ):
    if request.method == "POST":   
        if request.is_ajax( ):
            # the file is stored raw in the request
            upload = request
            is_raw = True
            # AJAX Upload will pass the filename in the querystring if it is the "advanced" ajax upload
            try:
                filename = request.GET[ 'qqfile' ]
            except KeyError:
                return HttpResponseBadRequest( "AJAX request not valid" )
        # not an ajax upload, so it was the "basic" iframe version with submission via form
        else:
            is_raw = False
            if len( request.FILES ) == 1:
                upload = request.FILES.values( )[ 0 ]
            else:
                raise Http404( "Bad Upload" )
            filename = upload.name

        # save the file
        success = save_upload( upload, filename, is_raw )

        # let Ajax Upload know whether we saved it or not
        import json
        ret_json = { 'success': success, }
        return HttpResponse( json.dumps( ret_json ) )
#######url.py
urlpatterns=patterns(“”,
(r'media/(?P.*)','django.views.static.service',{'document_root':settings.media_root}),
(r“^media/(?P.*)”、“django.views.static.service”、{“document\u root”:settings.media\u root}),
url(r'^$',索引,name='home'),
url(r“^ajax\u upload$”,ajax\u upload,name=“ajax\u upload”),
url(r“^upload/$”,upload\u page,name=“upload\u page”),
(r“^admin/”,包括(admin.site.url)),
(r“^accounts/”,包括('regfields.url'),
#示例:
#url(r'^$'、'mysite.views.home',name='home'),
#url(r“^mysite/”,包括('mysite.foo.url'),
#取消注释下面的admin/doc行以启用管理员文档:
#url(r“^admin/doc/”,包括('django.contrib.admindocs.url'),
#取消注释下一行以启用管理员:
#url(r“^admin/”,包括(admin.site.url)),
守则亦载于:

虽然看起来一切正常,但上传总是失败

我使用:filename=settings.UPLOAD\u STORAGE\u DIR,其中,UPLOAD\u STORAGE\u DIR在settings.py中定义为“/media/”


有人能指出我哪里出了问题吗(对不起,我是网络编程新手,实际上以前从未使用过JS,但可以合理地用python编程!)

您的Javascript中有一个输入错误。它应该是
{%csrf\u token%}
而不是
{csrf\u token}

编辑: 在你的评论之后,我仔细看了一下你链接的文章

您需要包括库
fileuploader.js
。它将用id
fileuploader
替换占位符div,并使用具有适当事件处理程序的表单。用纯HTML创建表单将不起作用


我建议您看看Github存储库中的示例:

您需要将
return True
添加到if语句中,以检查它是否为原始数据,否则即使上传成功,它也会返回False:

...
if raw_data:
    foo = uploaded.read(1024)
    while foo:
        dest.write(foo)
        foo = uploaded.read(1024) 
    return True
...

嗨,Daniel。谢谢你。我重新编辑了脚本(见上面的编辑),没有输入错误,但我仍然得到相同的404错误:(是AJAX请求吗?还是带有页面重新加载的普通表单请求?另外,你能修复python代码中的缩进以使其更具可读性吗?不,我认为没有发出AJAX请求(你能解释一下你在这里的意思吗?)。我现在已经把代码放在了dpaste上:dpaste.com/600371我想第40行可能有问题。我想知道“我应该在这里使用什么动作。应该是action=“ajax\u upload”吗?非常感谢您的帮助!Daniel,非常感谢您的回复。我现在修改了代码,看起来如下:我基本上使用了demo.html作为起点,然后根据[link](kuhlit.blogspot.com/2011/04/…)更改了代码的javascript部分Alex Kuhl。然而,我似乎在插入修改后的JS代码后丢失了上传按钮。因此,我将JS代码改为通过id获取文档为file-uploader-demo1。但是现在,当我上传文件时,它似乎总是失败。关于我正在做的事情,有什么想法吗?非常愚蠢(?)再次感谢您的时间{%csrf_token%}呈现一个HTML输入小部件(和一个隐藏的div),因此它不适用于javascript。我将删除它,因为将其视为一个可接受的答案会让人感到困惑。您是否收到了“错误上载”ajax_upload函数引发的404或不同的404?嗨,Alex,这就是问题:我没有收到错误的上传或403/404。当它上传时,似乎在OnComplete上失败并抛出else错误。它几乎立即抛出错误。另一个问题是:我需要更改fileuploader.js脚本中的任何内容吗?不,fileuploader.js应该在不做任何更改的情况下工作。您使用什么浏览器进行测试?如果它不能正确支持HTML5,则可能是iframe回退的问题。在其他情况下,如果您尝试打印responseJSON的值,您会得到什么(false、null等)?正如Daniel在下面所问的,你确定ajax请求会发出吗?你可以在开始上传后使用Firefox中的Firebug(不确定Chrome或Opera的开发工具)查看ajax流量。你也可以使用Wireshark或Fiddler(Fiddler更容易用于此目的)为了观察流量。Alex,再次感谢你的帮助。我在Ubuntu上使用Firebox 6。我已经查看了firebug输出,它似乎做了一个post请求。我将输出附加到:它似乎在ajax_上传时说了一些类似于NameError的话。这是否指向任何东西(Alex,我还发现使用Firebug时,在save_upload的第45行中,似乎是这样写的:Exception Location:/home/foo/path/mysite/。/mysite/views.py,第45行基本上是:“filename=settings.upload_STORAGE_DIR”,我的settings.py文件中有upload_STORAGE_DIR='/media/。)
...
if raw_data:
    foo = uploaded.read(1024)
    while foo:
        dest.write(foo)
        foo = uploaded.read(1024) 
    return True
...