Tyler Bell
Tyler Bell

Reputation: 897

Django, How to Download a Docx file, or any file in general

My current website creates and saves a Docx file to the server based on the the current users inputs/information. I have the program saving it to the server, so the user can access it later. So I am assuming the docx file can be considered static? Well anyways, I am having trouble getting the download to work.

I have looked at many different threads on how to get a Docx to download and none have worked for me so far. 1. Downloadable docx file in Django 2. Django create .odt or .docx documents to download Generate the MS word document in django

The closest I have gotten, was a docx file that downloaded, but the content was the path and not the actual docx file that I wanted. Hoping someone can help, Thanks.

Code:

response = HttpResponse('docx_temps/extracted3/test.docx', content_type='application/vnd')
response['Content-Disposition'] = 'attachment; filename=test.doc'
return response 

Code for Link, Still cannot get it to work.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Download</title>
</head>
<body>

<a href="users/Tyler/Desktop/Django_Formatically/mysite/Formatically/docx_temps/extracted3/test.docx"
  download="Test.docx"> 
   Test.docx
</a>

</body>
</html>

Upvotes: 1

Views: 2845

Answers (1)

ohrstrom
ohrstrom

Reputation: 2970

Solution A - static files

To be able to download a file considered static it has to be served in a way. In a production environment this task likely will be handled by a webserver like Apache or nginx.

To serve your media root via Django development server you can add the following pattern to your urls.py:

# urls.py
if settings.DEBUG:
    urlpatterns = patterns('',
    (r'^media/(?P<path>.*)$', 'django.views.static.serve',
        {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
    (r'', include('django.contrib.staticfiles.urls')),
) + urlpatterns

So any path below /media/ will be served directly. You also have to make sure you have correctly set MEDIA_ROOT and MEDIA_URL in your settings:

# settings.py
MEDIA_ROOT = 'Users/Tyler/Desktop/Django_Formatically/mysite/media/'
MEDIA_URL = '/media/'

However - this approach does not allow you to interact on the Django level. So you cannot e.g. check for user permissions or track/log requests in Django. Every user knowing the URL to a file is able to access it.

Solution B - through Django view

    # views.py
    def file_view(request):

        filename = '<path to your file>'
        data = open(filename, "rb").read()
        response = HttpResponse(data, content_type='application/vnd')
        response['Content-Length'] = os.path.getsize(filename)

        return response

This is just the most simple way that has some drawbacks. The whole file content is loaded in python - so it is not very efficient when sending large files and having a lot of requests. A solution using FileWrapper can be found here: Serving large files ( with high loads ) in Django

Or you could use django-sendfile which allows easy use of Apache mod_xsendfile or nginx XSendfile.

Upvotes: 0

Related Questions