如何修复从Django App失败下载文件

时间:2019-08-18 19:27:01

标签: python django

在我的django应用程序中,该程序创建一个文档并将其保存到settings.py MEDIA_URL中定义的文件路径。如果存在文件,则用户应能够单击模板中的链接,并且文件应下载。这样做时,我会下载一个.docx,但它显示为“失败-没有文件”。

我注意到两件事-1)打开后立即下载的文件为空白。 2)当我查看settings.py中由文件路径定义的文件夹时,我可以看到该文件已经存在并且已经按原样填充。显然,我在View中做错了什么,但是有什么想法我可能做错了吗?我认为这应该可以正常工作,因为我可以看到.docx的生成正确。

settings.py

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

...

MEDIA_ROOT = os.path.join(BASE_DIR, 'web_unit')
MEDIA_URL = '/web_unit/'

views.py

创建.docx文件并将其保存

def docjawn(request):

    reference = request.POST.get('Reference_IDs')
    manifest = Manifests.objects.all().filter(reference__reference=reference)
    order = Orders.objects.get(reference=reference)

    doc = DocxTemplate("template.docx")
    totalCNF = 0
    totalFOB = 0
    for item in manifest:
        totalCNF += item.cases * item.CNF
        totalFOB += item.cases * item.FOB
    context = {

        'ultimate_consignee' : order.ultimate_consignee,
        'reference' : order.reference,
        'ship_to' : order.ship_to,
        'terms' : order.terms,
        'date' : "12",
        'ship_date' : "7/4/19",
        'vessel' : order.vessel,
        'POE' : order.POE,
        'ETA' : order.ETA,
        'booking_no' : order.booking_no,
        'manifest' : manifest,
        'totalCNF' : totalCNF,
        'totalFOB' : totalFOB,
}


    doc.render(context)

    doc_io = io.BytesIO()
    doc.save(doc_io)
    doc_io.seek(0)

    # Save the BytesIO to the field here
    order.order_file.save("generated_doc.docx", File(doc_io))

    response = HttpResponse(doc_io.read())
    response["Content-Disposition"] = "attachment; filename=generated_doc.docx"
    response["Content-Type"] = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"

    return response

index.html

显示如何在模板中具有指向文件url设置的链接

  {% for order in orders %}

    <tr>

   ...

      {% if order.order_file %}
        <td><a href="{{ order.order_file.url|default_if_none:'#' }}" download>Download</a></td>
      {% endif %}  
    </tr>
    {% endfor %}

1 个答案:

答案 0 :(得分:1)

您需要始终在媒体URL之前加上MEDIA_URL。为FileField保存的URL始终相对于MEDIA_ROOT。并且MEDIA_URL指向MEDIA_ROOT,因此您应该添加以下内容:

href="{% get_media_prefix %}{{ order.order_file.url }}"

您还需要配置Django,以便开发服务器在遇到以described here为首的MEDIA_URL开头的网址时知道该怎么做。