Django下载文件不起作用 [英] Django download file not working

查看:41
本文介绍了Django下载文件不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作一个脚本,用于在用户的机器上下载上传的文件.问题是下载根本不起作用(它要么给我下载了一个空文件,要么给了我一些错误).

I'm trying to make a script for downloading the uploaded files, on the user's machine. The problem is that the download simply doesn't work (it either downloads me an empty file, or gives me some errors).

最后一个错误是:强制转换为 Unicode:需要字符串或缓冲区,找到 FieldFile

the last error is: coercing to Unicode: need string or buffer, FieldFile found

def download_course(request, id):
    course = Courses.objects.get(pk = id).course

    path_to_file = 'root/cFolder'
    filename = course # Select your file here.                                
    wrapper = FileWrapper(file(course))
    content_type = mimetypes.guess_type(filename)[0]
    response = HttpResponse(wrapper, content_type = content_type)
    response['Content-Length'] = os.path.getsize(filename)
    response['Content-Disposition'] = 'attachment; filename=%s/' % smart_str(course)

    return response

如何正确声明文件名,以便它每次都知道要下载的文件:文件名实际上是上面声明的课程"

how can I declare properly the filename so that it will know each time what file to be downloading: the filename is actually 'course' as declared above

谢谢!

推荐答案

已编辑

我认为您需要从 FileField 对象中提取 path 值:

I think that you need to extract path value from FileField object:

def download_course(request, id):
    course = Courses.objects.get(pk = id).course

    path = course.path # Get file path
    wrapper = FileWrapper( open( path, "r" ) )
    content_type = mimetypes.guess_type( path )[0]

    response = HttpResponse(wrapper, content_type = content_type)
    response['Content-Length'] = os.path.getsize( path ) # not FileField instance
    response['Content-Disposition'] = 'attachment; filename=%s/' %  
                                       smart_str( os.path.basename( path ) ) # same here

    return response

这是为什么:

假设我有(好吧,我实际上有)模型:

Let's say I have (well, I actually have) Model:

class DanePracodawcy( DaneAdresowe, DaneKontaktowe ):
    # other fields
    logo = ImageWithThumbnailsField( upload_to = 'upload/logos/',
                                  thumbnail = {'size': (180, 90)},
                                  blank = True )

ImageWithThumbnailsField 是 FileField 的子类,所以它的行为方式相同.现在,当我做 SELECT 时:

ImageWithThumbnailsField is subclass of FileField, so it behaves the same way. Now, when I do SELECT:

mysql> select logo from accounts_danepracodawcy;
+-----------------------------+
| logo                        |
+-----------------------------+
| upload/logos/Lighthouse.jpg |
+-----------------------------+
1 row in set (0.00 sec)

它显示(相对于 MEDIA_ROOT)存储文件的路径.但是当我访问 logo 模型属性时:

it shows (relative to MEDIA_ROOT) path of stored file. But when I access logo Model attribute:

[D:projekty/pracus]|1> from accounts.models import DanePracodawcy
[D:projekty/pracus]|4> DanePracodawcy.objects.get().logo
                   <4> <ImageWithThumbnailsFieldFile: upload/logos/Lighthouse.jpg>
[D:projekty/pracus]|5> type( _ )
                   <5> <class 'sorl.thumbnail.fields.ImageWithThumbnailsFieldFile'>

我得到了某个对象的实例.如果我尝试将该实例传递给 os.path.getsize:

I get instance of some object. If I try to pass that instance to os.path.getsize:

[D:projekty/pracus]|8> import os.path
[D:projekty/pracus]|9> os.path.getsize( DanePracodawcy.objects.get().logo )
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

D:projektypracus<ipython console> in <module>()

C:Python26libgenericpath.pyc in getsize(filename)
     47 def getsize(filename):
     48     """Return the size of a file, reported by os.stat()."""
---> 49     return os.stat(filename).st_size
     50
     51

TypeError: coercing to Unicode: need string or buffer, ImageWithThumbnailsFieldFile found

我和你一样遇到 TypeError.所以我需要文件路径作为字符串,可以通过 path 属性获取:

I get TypeError, like you. So I need file path as string, which can be obtained with path attribute:

[D:projekty/pracus]|13> os.path.getsize(  DanePracodawcy.objects.get().logo.path )
                   <13> 561276L

或者,我可以通过 MEDIA_ROOT 设置获取 name 属性和 os.path.join 它:

Alternatively, I could get name attribute and os.path.join it with MEDIA_ROOT setting:

[D:projekty/pracus]|11> from django.conf import settings
[D:projekty/pracus]|12> os.path.getsize(  os.path.join( settings.MEDIA_ROOT, DanePracodawcy.objects.get().logo.name ) )
                   <12> 561276L

但那是不必要的输入.

最后要注意:因为 path 是绝对路径,所以我需要提取文件名以将其传递给 Content-Disposition 标头:

Last thing to note: because path is absolute path, I need to extract filename to pass it to Content-Disposition header:

[D:projekty/pracus]|16> DanePracodawcy.objects.get().logo.path
                   <16> u'd:\projekty\pracus\site_media\upload\logos\lighthouse.jpg'
[D:projekty/pracus]|17> os.path.basename( DanePracodawcy.objects.get().logo.path )
                   <17> u'lighthouse.jpg'

这篇关于Django下载文件不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆