Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixed #428 -- added a "static pages" view. Note that this view should…
… only be used for testing! git-svn-id: http://code.djangoproject.com/svn/django/trunk@683 bcc190cf-cafb-0310-a4f2-bffc1f526a37
- Loading branch information
Showing
1 changed file
with
86 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,86 @@ | |||
import os | |||
import urllib | |||
import posixpath | |||
import mimetypes | |||
from django.core import template_loader | |||
from django.core.exceptions import Http404, ImproperlyConfigured | |||
from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect | |||
from django.core.template import Template, Context, TemplateDoesNotExist | |||
|
|||
def serve(request, path, document_root=None, show_indexes=False): | |||
""" | |||
Serve static files below a given point in the directory structure. | |||
To use, put a URL pattern like:: | |||
(r'^(?P<path>).*)$', 'django.views.static.serve', {'document_root' : '/path/to/my/files/'}) | |||
in your URL conf; 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``. | |||
""" | |||
|
|||
# Clean up given path to only allow serving files below document_root. | |||
path = posixpath.normpath(urllib.unquote(path)) | |||
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 '.' amd '..' in path | |||
continue | |||
newpath = os.path.join(newpath, part) | |||
if newpath and path != newpath: | |||
return HttpResponseRedirect(newpath) | |||
fullpath = os.path.join(document_root, newpath) | |||
if os.path.isdir(fullpath): | |||
if show_indexes: | |||
return directory_index(newpath, fullpath) | |||
else: | |||
raise Http404, "Directory indexes are not allowed here." | |||
elif not os.path.exists(fullpath): | |||
raise Http404, '"%s" does not exist' % fullpath | |||
else: | |||
mimetype = mimetypes.guess_type(fullpath)[0] | |||
return HttpResponse(open(fullpath).read(), mimetype=mimetype) | |||
|
|||
DEFAULT_DIRECTORY_INDEX_TEMPLATE = """ | |||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | |||
<head> | |||
<meta http-equiv="Content-type" content="text/html; charset=utf-8" /> | |||
<meta http-equiv="Content-Language" content="en-us" /> | |||
<title>Index of {{ directory }}</title> | |||
</head> | |||
<body> | |||
<h1>Index of {{ directory }}</h1> | |||
<ul> | |||
{% for f in file_list %} | |||
<li><a href="{{ f }}">{{ f }}</a></li> | |||
{% endfor %} | |||
</ul> | |||
</body> | |||
</html> | |||
""" | |||
|
|||
def directory_index(path, fullpath): | |||
try: | |||
t = template_loader.get_template('static/directory_index') | |||
except TemplateDoesNotExist: | |||
t = Template(DEFAULT_DIRECTORY_INDEX_TEMPLATE) | |||
files = [] | |||
for f in os.listdir(fullpath): | |||
if not f.startswith('.'): | |||
if os.path.isdir(os.path.join(fullpath, f)): | |||
f += '/' | |||
files.append(f) | |||
c = Context({ | |||
'directory' : path + '/', | |||
'file_list' : files, | |||
}) | |||
return HttpResponse(t.render(c)) |