【问题标题】:FileUpload with Django使用 Django 上传文件
【发布时间】:2011-06-12 14:51:05
【问题描述】:

我正在使用ajax-upload 代码进行简单的 AJAX 文件上传。我遇到的问题是提交后文件没有显示在后端。

前端代码非常基本:

<div id="image_uploader">Upload More Images</div>
<script type="text/javascript" charset="utf-8">
    function createUploader(){            
        var uploader = new qq.FileUploader({
            element: document.getElementById('image_uploader'),
            action: '/add/image/1',
            debug: true,
            onSubmit : function () {
                progress.show();
            },
            onComplete : function () {
                progress.hide();
            },
            onCancel : function () {
                progress.hide();
            },
        });           
    };

    createUploader();
</script>

后端代码(目前正在进行中)也很基本:

def add_image(request, id):
    print request
    if request.FILES:
        return HttpResponse("{success:true}")
    else:
        return HttpResponse("{success:false, message:'Unable to find FILES}")

【问题讨论】:

    标签: ajax django file file-upload


    【解决方案1】:

    对我来说,使用来自Alex Kuhl 的代码,request.GET['qqfile'] 具有文件名,request.read()(在 Django 1.3 中)返回数据。

    request.FILES 仅用于我尚未发生的情况。我正在使用 ajax-upload 直接与 Photologue 对话,我的代码如下所示:

    def save_upload( uploaded, filename, raw_data ):
        """
        raw_data: if True, upfile is a HttpRequest object with raw post data
        as the file, rather than a Django UploadedFile from request.FILES
        """
        try:
            filename = os.path.normpath(os.path.join(IMAGE_UPLOAD_PATH, filename))
            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:
                    (dirName, fileName) = os.path.split(filename)
                    (fileBaseName, fileExtension)=os.path.splitext(fileName)
                    #
                    # right here, if fileBaseName is less than n characters, might want to slap on a date just for fun
                    #
                    try:
                        i_can_has_p = Photo.objects.get(title=fileBaseName)
                        title = fileBaseName + "_" + str(datetime.datetime.now().strftime("%Y%m%dT%H%M%S"))
                    except Photo.DoesNotExist:
                        title = fileBaseName
                    title_slug = slugify(title)
                    p = Photo(title=title, title_slug=title_slug)
                    p.image.save(filename,ContentFile(uploaded.read()))
                # if not raw, it was a form upload so read in the normal Django chunks fashion
                else:
                    # TODO: figure out when this gets called, make it work to save into a Photo like above
                    for c in uploaded.chunks( ):
                        dest.write( c )
        except IOError:
            # could not open the file most likely
            return False
        return True
    
    def ajax_upload( request ):
      if request.method == "POST":
          # AJAX Upload will pass the filename in the querystring if it is the "advanced" ajax upload
          if request.is_ajax( ):
              # the file is stored raw in the request
              upload = request
              is_raw = True
              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:
                  # FILES is a dictionary in Django but Ajax Upload gives the uploaded file an
                  # ID based on a random number, so it cannot be guessed here in the code.
                  # Rather than editing Ajax Upload to pass the ID in the querystring, note that
                  # each upload is a separate request so FILES should only have one entry.
                  # Thus, we can just grab the first (and only) value in the dict.
                  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
      ret_json = { 'success': success, }
      return HttpResponse( json.dumps( ret_json ) )
    

    在我的例子中,ajax_upload 是 ajax 的 action: 参数调用的函数

    【讨论】:

    • 我在哪里可以定义IMAGE_UPLOAD_PATH
    • 这个常量不是必须的,迅雷只是利用它来构建一个绝对路径。您可以对要保存上传的目录使用硬编码值,而不是常量。但是,如果您确实想使用它,则可以将其放置在 settings.py 中,然后将其导入要使用的视图中。也感谢雷霆的点头,很高兴其他人发现我的帖子有用。
    • @alex:好的,我正在使用request.META['PWD'] + "/appName/static/images/" + filename
    • @alex:谢谢(感谢您的原始代码!)@Josh:我在 settings.py 中定义了
    • 和@Alex:感谢代码,我做了一些调整,现在效果很好。
    【解决方案2】:

    Andrew Valums 现在在 git hub 上获得了 django app

    【讨论】:

      猜你喜欢
      • 2011-03-18
      • 2017-02-14
      • 2010-09-23
      • 1970-01-01
      • 1970-01-01
      • 2021-05-21
      相关资源
      最近更新 更多