Django下载文件

Car*_*ine 31 python django

我是使用Django的新手,我正在尝试开发一个用户可以上传大量excel文件的网站,然后将这些文件存储在媒体文件夹Webproject/project/media中.

def upload(request):
    if request.POST:
        form = FileForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return render_to_response('project/upload_successful.html')
    else:
        form = FileForm()
    args = {}
    args.update(csrf(request))
    args['form'] = form

    return render_to_response('project/create.html', args)
Run Code Online (Sandbox Code Playgroud)

然后,文档将与列表中的任何其他文档一起显示在列表中,您可以单击该文档,它将显示有关它们的基本信息以及它们已上载的文件的名称.从这里我希望能够使用以下链接再次下载相同的excel文件:

 <a  href="/project/download"> Download Document </a>
Run Code Online (Sandbox Code Playgroud)

我的网址是

 urlpatterns = [

              url(r'^$', ListView.as_view(queryset=Post.objects.all().order_by("-date")[:25],
                                          template_name="project/project.html")),
              url(r'^(?P<pk>\d+)$', DetailView.as_view(model=Post, template_name="project/post.html")),
              url(r'^upload/$', upload),
              url(r'^download/(?P<path>.*)$', serve, {'document root': settings.MEDIA_ROOT}),

          ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Run Code Online (Sandbox Code Playgroud)

但是我得到了错误,serve()得到了一个意外的关键字参数'document root'.谁能解释如何解决这个问题?

要么

说明如何使用上传的文件进行选择和提供

def download(request):
    file_name = #get the filename of desired excel file
    path_to_file = #get the path of desired excel file
    response = HttpResponse(mimetype='application/force-download')
    response['Content-Disposition'] = 'attachment; filename=%s' % smart_str(file_name)
    response['X-Sendfile'] = smart_str(path_to_file)
    return response
Run Code Online (Sandbox Code Playgroud)

Ser*_*aev 65

您在参数文档_root中错过了下划线.但是serve在生产中使用它是个坏主意.使用这样的东西代替:

import os
from django.conf import settings
from django.http import HttpResponse, Http404

def download(request, path):
    file_path = os.path.join(settings.MEDIA_ROOT, path)
    if os.path.exists(file_path):
        with open(file_path, 'rb') as fh:
            response = HttpResponse(fh.read(), content_type="application/vnd.ms-excel")
            response['Content-Disposition'] = 'inline; filename=' + os.path.basename(file_path)
            return response
    raise Http404
Run Code Online (Sandbox Code Playgroud)

  • 这不是让用户通过使用像`../../some/other/path/secrets.txt`这样的`path`来下载服务器上的任何文件吗? (2认同)
  • 是否可以调整此方法以便用户下载 .exe 文件? (2认同)
  • 我参加聚会迟到了,但是:路径论证的目的是什么?我可以用它来下载 powerpoint 文件吗? (2认同)

小智 41

您可以在标签中添加“下载”属性来下载文件。

<a  href="/project/download" download> Download Document </a>
Run Code Online (Sandbox Code Playgroud)

https://www.w3schools.com/tags/att_a_download.asp

  • 因为它不适用于 Django。Django 将“/project/download”作为 URL 进行处理...因此,如果 `/project/myfile.pdf` 未解析为 URL...则 GET 请求将在 Django 中给出 404 - 即使 html 已标记作为下载。 (4认同)
  • 该死的,这太容易实现了,我想知道为什么支持票这么少! (3认同)
  • 它在 djago &lt;a href="{{ obj.file_field_name.url }}" download&gt;Download&lt;/a&gt; 中为我工作 (3认同)

小智 19

参考

在 view.py 中实现类似的功能,

def download(request, id):
    obj = your_model_name.objects.get(id=id)
    filename = obj.model_attribute_name.path
    response = FileResponse(open(filename, 'rb'))
    return response
Run Code Online (Sandbox Code Playgroud)

  • 这似乎比接受的答案更好,谢谢!这也适用于 nginx 吗? (2认同)

sik*_*i99 8

当您使用 上传文件时FileField,该文件将有一个 URL,您可以使用该 URL 指向该文件并使用 HTMLdownload属性下载该文件,您只需执行此操作即可。

models.py

model.py 看起来像这样

class CsvFile(models.Model):
    csv_file = models.FileField(upload_to='documents')
Run Code Online (Sandbox Code Playgroud)

views.py

#csv上传

class CsvUploadView(generic.CreateView):

   model = CsvFile
   fields = ['csv_file']
   template_name = 'upload.html'
Run Code Online (Sandbox Code Playgroud)

#csv下载

class CsvDownloadView(generic.ListView):

    model = CsvFile
    fields = ['csv_file']
    template_name = 'download.html'
Run Code Online (Sandbox Code Playgroud)

然后在你的模板中。

#上传模板

upload.html

<div class="container">
<form action="#" method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.media }}
    {{ form.as_p }}
    <button class="btn btn-primary btn-sm" type="submit">Upload</button>
</form>
Run Code Online (Sandbox Code Playgroud)

#下载模板

download.html

  {% for document in object_list %}

     <a href="{{ document.csv_file.url }}" download  class="btn btn-dark float-right">Download</a>

  {% endfor %}
Run Code Online (Sandbox Code Playgroud)

我没有使用表单,只是渲染模型,但无论哪种方式,FileField都在那里并且它的工作方式相同。