This view has the same functionality as Django's builtin static view function but when the configuration option USE_XSENDFILE = True
is specified in the settings it returns the absolute path of the file instead of its contents.
This allows the mod_xsendfile module in Apache or Lighttpd to take care of efficiently serving the file while still allowing for Django to take care of other processing of the request, like access control or counting the amount of downloads.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | import posixpath
import urllib
import os
from django.conf import settings
from django.views.static import serve
from django.http import HttpResponse
USE_XSENDFILE = getattr(settings, 'USE_XSENDFILE', False)
def xsendfileserve(request, path, document_root=None):
"""
Serve static files using X-Sendfile below a given point
in the directory structure.
This is a thin wrapper around Django's built-in django.views.static,
which optionally uses USE_XSENDFILE to tell webservers to send the
file to the client. This can, for example, be used to enable Django's
authentication for static files.
To use, put a URL pattern such as::
(r'^(?P<path>.*)$', login_required(xsendfileserve),
{'document_root' : '/path/to/my/files/'})
in your URLconf. You must provide the ``document_root`` param. You may
also set ``show_indexes`` to ``True`` if you'd like to serve a basic index
of the directory. This index view will use the template hardcoded below,
but if you'd like to override it, you can create a template called
``static/directory_index.html``.
"""
if USE_XSENDFILE:
# This code comes straight from the static file serve
# code in Django 1.2.
# Clean up given path to only allow serving files below document_root.
path = posixpath.normpath(urllib.unquote(path))
path = path.lstrip('/')
newpath = ''
for part in path.split('/'):
if not part:
# Strip empty path components.
continue
drive, part = os.path.splitdrive(part)
head, part = os.path.split(part)
if part in (os.curdir, os.pardir):
# Strip '.' and '..' in path.
continue
newpath = os.path.join(newpath, part).replace('\\', '/')
if newpath and path != newpath:
return HttpResponseRedirect(newpath)
fullpath = os.path.join(document_root, newpath)
# This is where the magic takes place.
response = HttpResponse()
response['X-Sendfile'] = fullpath
# Unset the Content-Type as to allow for the webserver
# to determine it.
response['Content-Type'] = ''
return response
return serve(request, path, document_root)
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
- Help text hyperlinks by sa2812 1 year, 7 months ago
Comments
Is there anyway to change the default name of the saved file? Currently, it's being saved as 'download'. I've tried:
response['Content-Disposition'] = 'attachment; filename=AnotherName'
but that doesn't help.
Any ideas?
#
Please login first before commenting.