I want users on the site to be able to download files whose paths are obscured so they cannot be directly downloaded.
For instance, I'd like the URL to be something like this, "http://example.com/download/?f=somefile.txt
And on the server, I know that all downloadable files reside in a folder "/home/user/files/".
Is there a way to make Django serve that file for download as opposed to trying to find a URL and View to display it?
Django recommend that you use another server to serve static media (another server running on the same machine is fine.) They recommend the use of such servers as lighttp.
This is very simple to set up. However. if 'somefile.txt' is generated on request (content is dynamic) then you may want django to serve it.
Django Docs - Static Files
Just mentioning the FileResponse object available in Django 1.10
Edit: Just ran into my own answer while searching for an easy way to stream files via Django, so here is a more complete example (to future me). It assumes that the FileField name is
imported_file
views.py
urls.py
Another project to have a look at: http://readthedocs.org/docs/django-private-files/en/latest/usage.html Looks promissing, haven't tested it myself yet tho.
Basically the project abstracts the mod_xsendfile configuration and allows you to do things like:
It was mentioned above that the mod_xsendfile method does not allow for non-ASCII characters in filenames.
For this reason, I have a patch available for mod_xsendfile that will allow any file to be sent, as long as the name is url encoded, and the additional header:
Is sent as well.
http://ben.timby.com/?p=149
For the "best of both worlds" you could combine S.Lott's solution with the xsendfile module: django generates the path to the file (or the file itself), but the actual file serving is handled by Apache/Lighttpd. Once you've set up mod_xsendfile, integrating with your view takes a few lines of code:
Of course, this will only work if you have control over your server, or your hosting company has mod_xsendfile already set up.
EDIT:
EDIT: For
nginx
check this, it usesX-Accel-Redirect
instead ofapache
X-Sendfile header.For a very simple but not efficient or scalable solution, you can just use the built in django
serve
view. This is excellent for quick prototypes or one-off work, but as has been mentioned throughout this question, you should use something like apache or nginx in production.