一个Django snippet : 文件流方式的下载

有时候为了只让有权限的用户下载,不能直接把文件放在硬盘上以静态文件的方式直接提供下载,下面这段代码实现通过文件流的方式下载:


  def download_android(request):
     
      your_file_path = '/xxx/xxx/'
      original_filename = 'xxx.xx'
      file_path = your_file_path + original_filename
     
      fp = open(file_path, 'rb')
      response = HttpResponse(fp.read())
      fp.close()
      type, encoding = mimetypes.guess_type(original_filename)
      if type is None:
          type = 'application/octet-stream'
      response['Content-Type'] = type
      response['Content-Length'] = str(os.stat(file_path).st_size)
      if encoding is not None:
          response['Content-Encoding'] = encoding

      # To inspect details for the below code, see http://greenbytes.de/tech/tc2231/
      if u'WebKit' in request.META['HTTP_USER_AGENT']:
          # Safari 3.0 and Chrome 2.0 accepts UTF-8 encoded string directly.
          filename_header = 'filename=%s' % original_filename.encode('utf-8')
      elif u'MSIE' in request.META['HTTP_USER_AGENT']:
          # IE does not support internationalized filename at all.
          # It can only recognize internationalized URL, so we do the trick via routing rules.
          filename_header = 'filename=%s' % original_filename.encode('utf-8')
      else:
          # For others like Firefox, we follow RFC2231 (encoding extension in HTTP headers).
          filename_header = 'filename*=UTF-8\'\'%s' % urllib.quote(original_filename.encode('utf-8'))
      response['Content-Disposition'] = 'attachment; ' + filename_header
      return response

Django snippet 下载 文件流
Views (5504) Comments (5) 2013-01-09
阿尼玛卿 :
你好啊,按照你的方法在centos下下载大文件时是可以的,但是在windown下下载文件只有17k。请教linux和windown方法不能同用吗?
老楠 Reply to 阿尼玛卿 :
在windows下还真没试过,一般来说python在linux下的表现比在windows下肯定要优秀得多。试试别的方法,比如ftplib之类的,看在windows下表现会不会好些。
老楠 Reply to 阿尼玛卿 :
另外,补充下,如果用了Django1.5,现在推荐StreamingHttpResponse, https://docs.djangoproject.com/en/dev/topics/http/middleware/#response-middleware
Dig :
如果用户是固定的,直接在nginx或者apache里面用HTTP认证就可以了啊
老楠 Reply to Dig :
嗯,不过一般都是业务系统的动态用户来着。
For example, "name@something.com". If someone replies to you it will be via email.
For example, "http://someaddress.com"