2010-07-09 73 views
2

我试图在用户机器上下载上传文件的脚本。问题是,下载不起作用(它会下载我一个空文件,或给我一些错误)。Django的下载文件不能正常工作

的最后一个错误是: 胁迫为Unicode:需要字符串或缓冲区,FieldFile发现

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 

我怎么可以声明正确的文件名,这样它就会每次都下载了什么文件知道: 的文件名实际上是'course'如上所述

谢谢!

回答

5

编辑

我认为你需要提取的FileField path值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 

这是为什么:

比方说,我有(好吧,其实我有)型号:

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

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

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

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

[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

[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:\projekty\pracus\<ipython console> in <module>() 

C:\Python26\lib\genericpath.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 

我得到类型错误,像你这样的。所以,我需要的文件路径为字符串,它可以与path属性来获得:

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

或者,我可以得到name属性和os.path.join它MEDIA_ROOT设置:

[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是绝对路径,我需要提取的文件名来把它传递给内容处理标头:

[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' 
+0

nop,该课程的名称是 – dana 2010-07-09 14:43:46

+0

表中的'course'字段的对应关系。这太奇怪了,因为我的错误仍然强制为Unicode:需要字符串或缓冲区,找到FieldFile。我真的不明白为什么。 – dana 2010-07-09 15:17:47

+1

对不起,我的回答是错误的,我再次检查并编辑。现在上面的代码应该按预期工作,我试图解释它为什么这样工作。 – cji 2010-07-09 15:38:45

2

除非你让用户下载一个动态生成的文件,否则我不明白为什么你需要这么做。

您可以让此视图重定向到适当的路径,并且各个标头由服务于静态文件的服务器设置;通常Apache或nginx的

我愿意做你的这一观点如下:

from django.conf import settings 

def download_course(request,id): 
    course = get_object_or_404(Course,id=id) 
    filename = course.course 
    return redirect('%s/%s'%(settings.MEDIA_URL,filename)) 

享受:)

+0

现在它说:“FieldFile”对象有没有属性“_default_manager” – dana 2010-07-09 14:02:05