从Django 1.4.3的media文件夹下载已上传的文件

12 投票
5 回答
16275 浏览
提问于 2025-04-17 18:07

我正在使用Django来设计基本的网页,这些网页可以处理文件的上传下载,文件会存放在media文件夹里。

实际上,文件成功上传到了media文件夹,也能成功下载,但文件名的最后会多出一个下划线,比如file_one.pdf_file_two.pdf_file_three.txt_等等。

以下是我的代码:

urls.py

urlpatterns = patterns('',
             url(r'^upload$', 'learn_django.views.upload'),
             url(r'^files_list$', 'learn_django.views.files_list'),
             url(r'^download/(?P<file_name>.+)$', 'learn_django.views.download'),
)
if settings.DEBUG:
    urlpatterns = patterns('',
    url(r'^media/(?P<path>.*)$', 'django.views.static.serve',{'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
) + urlpatterns

views.py

def upload(request):
    ......
    ....
    return render_to_response('uploads_form.html', {'form': form},context_instance=RequestContext(request))


def files_list(request):
    return render_to_response('files_list.html',{'total_files':os.listdir(settings.MEDIA_ROOT),'path':settings.MEDIA_ROOT},context_instance=RequestContext(request))

def download(request,file_name):
    file_path = settings.MEDIA_ROOT +'/'+ file_name
    file_wrapper = FileWrapper(file(file_path,'rb'))
    file_mimetype = mimetypes.guess_type(file_path)
    response = HttpResponse(file_wrapper, content_type=file_mimetype )
    response['X-Sendfile'] = file_path
    response['Content-Length'] = os.stat(file_path).st_size
    response['Content-Disposition'] = 'attachment; filename=%s/' % smart_str(file_name) 
    return response

files_list.html

<table border="1" colspan="2" width="100%">
   <tr>
     <th width="60%">File</td>
     <th width="40%">Download</td> 
   </tr>
 {% for file in total_files %}
   <tr>
     <td width="60%">{{file}}</td>
     <td width="40%" align="center"><a href="/download/{{file}}" style="text-decoration:None">Download here</a></td>
   </tr>
 {% endfor %}  
</table>

在上面的代码中,当文件成功上传到media文件夹后,会通过files_list视图函数重定向到files_list.html,这个页面会以表格的形式显示文件总数,并在每个文件名旁边提供下载链接。

当我们点击下载链接时,会执行download函数来下载相应的文件。

文件能够成功下载,但文件名的最后会多出一个下划线,比如file_one.pdf_file_two.pdf_file_three.txt_等等。

所以,有谁能告诉我,我的下载函数代码哪里出错了,为什么文件名后面会多出这个下划线,以及如何去掉这个下划线呢……

5 个回答

2

这些都不是必须的。在HTML中,你可以通过使用 <a download="{video.URL}"> 来下载媒体文件。

举个例子:

<button class="btn btn-outline-info">
<a href="{{result.products.full_video.url}}" download="{{result.products.full_video.url}}" style="text-decoration:None" class="footer_link">Download<i class="fa fa-download"></i></a>
</button>
6

你的代码是对的,但在download里有一个多余的字符:

def download(request,file_name):
    file_path = settings.MEDIA_ROOT +'/'+ file_name
    file_wrapper = FileWrapper(file(file_path,'rb'))
    file_mimetype = mimetypes.guess_type(file_path)
    response = HttpResponse(file_wrapper, content_type=file_mimetype )
    response['X-Sendfile'] = file_path
    response['Content-Length'] = os.stat(file_path).st_size
    response['Content-Disposition'] = 'attachment; filename=%s/' % smart_str(file_name) 
    return response

在最后一行,文件名的属性后面多了一个斜杠(/):filename=%s/

这个斜杠导致了问题。把这个斜杠去掉就可以正常工作了。

6

只需要把文件名后面的 / 去掉就可以了。

把这个:

response['Content-Disposition'] = 'attachment; filename=%s/' % smart_str(file_name) 

改成这个:

response['Content-Disposition'] = 'attachment; filename=%s' % smart_str(file_name) 

撰写回答