Django的下载文件不能正常工作
我试图在用户机器上下载上传文件的脚本。问题是,下载不起作用(它会下载我一个空文件,或给我一些错误)。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'如上所述
谢谢!
编辑
我认为你需要提取的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'
除非你让用户下载一个动态生成的文件,否则我不明白为什么你需要这么做。
您可以让此视图重定向到适当的路径,并且各个标头由服务于静态文件的服务器设置;通常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))
享受:)
现在它说:“FieldFile”对象有没有属性“_default_manager” – dana 2010-07-09 14:02:05
nop,该课程的名称是 – dana 2010-07-09 14:43:46
表中的'course'字段的对应关系。这太奇怪了,因为我的错误仍然强制为Unicode:需要字符串或缓冲区,找到FieldFile。我真的不明白为什么。 – dana 2010-07-09 15:17:47
对不起,我的回答是错误的,我再次检查并编辑。现在上面的代码应该按预期工作,我试图解释它为什么这样工作。 – cji 2010-07-09 15:38:45