首页 > 解决方案 > 下载带有视图的 FileField

问题描述

我有一个显示订单信息的表格 - 每个订单都附有一个文件。此文件的文件路径已在表中显示为链接,但我无法通过单击它进行下载。我希望能够单击此链接并下载正确的 .docx。

我正在参考:如何在 django 视图中下载文件字段文件

但我真的不明白这个解决方案是如何工作的。不需要网址吗?视图如何知道要选择哪个文件?我打开了一个先前的问题并被标记为重复并指向此链接,但我真的不明白这里给出的解决方案。我需要以某种方式传递订单的 pk 吗?任何帮助将不胜感激。下面是我的代码。

模型.py

class Orders(models.Model):

...

order_file = models.FileField(upload_to='web_unit', null=True, blank=True)

...
    def __str__(self):

       return self.reference

索引.html

<div class="table-responsive">
<table id="main_table" class="table table-striped table-bordered" cellspacing="0" style="width="100%">
  <thead>
    <tr>
      ....
  </thead>

  <tbody>

    {% for order in orders %}

    <tr>

      <td>
        <!-- Update book buttons -->
      <button type="button" class="update-book btn btn-sm btn-primary" style="color: #FFCF8B; border-color: #FFCF8B; background-color: #FFF;" data-id="{% url 'order_update' order.pk %}">
        <span class="fa fa-pencil"></span>
      </button>
      </td>

   ....

      <td><a href="{{ order.order_file.url }}">Download</a></td> #this is the link

    </tr>
    {% endfor %}


  </tbody>
</table>

当点击表中的链接时——我想要下载文件——我需要有关如何定义 URL 和视图的帮助来实现这一点。

现在,当我单击链接时,我收到一个错误,显示所有已尝试的 url。

标签: pythondjango

解决方案


一开始这有点复杂,但让我为你分解一下。

首先,您通过Django上传的文件存储在文件系统中的某个位置(在默认设置的情况下)。这通常意味着您上传的文件将转到您的/media文件夹,该文件夹与您的其他 Django 文件位于同一目录中。可以使用参数在 Django 设置文件中定义媒体文件夹的路径。MEDIA_ROOT默认情况下,它可能在您的manage.py文件旁边。

为了能够下载您上传的文件,您需要使用网络服务器(Apache、nginx 等)来提供文件。这是来自经典nginx设置的配置片段:

# Media files
    location /media {
        alias /home/riverman/my-django-project/media;
    }

这意味着,可以使用以下虚构链接通过浏览器访问(和下载)您上传的文件:
http://my-django-project.test/media/images/cat.png

现在这是棘手的部分:Django 不会将完整的 url ( http://my-django-project.test/media/images/cat.png) 存储到数据库中的文件中,而是只存储它的静态部分 ( /images/cat.png)。媒体文件夹的名称(media在本例中)和网站的 URL ( my-django-project.test) 都可能在以后更改,因此将其全部存储在数据库中并不明智,相反,您可以即时生成完整的 URL。

当您访问所需文件 ( {{ order.order_file.url }}) 的路径时,您只会收到部分信息,如下所示:/media/images/cat.png.

您需要将此部分信息与您网站的 url 结合起来。这是我如何做的一个例子。将此添加到您的views.py

from django.contrib.sites.models import Site

current_site = Site.objects.get_current()
current_site.domain

并将您的更新index.html为:

<td><a href="{{ current_site.domain }}/{{ order.order_file.url }}">Download</a></td>

在您的开发机器上设置本地网络服务器超出了这个问题的范围,但您可以参考这个问题:Bestlightweight web server (only static content) for Windows

祝你好运!


推荐阅读