Django selbst ist nicht dafür konzipiert, statische Dateien wie Bilder, Stylesheets oder Videos auszuliefern. Standard Web-Server wie Apache, lighttpd und Cherokee sind für diese Aufgabe optimiert, folglich sollte man ihnen diese Arbeit überlassen.
Django kann jedoch zumindest während der Entwicklungsphase auch dazu genutzt werden, solche Dateien auszuliefern und bietet hierfür den django.views.static.serve()-View.
Siehe auch
Wenn du lediglich die Admin-Dateien aus einem bestimmten Verzeichnis anbieten möchtest, dann sollte dir der --adminmedia-Parameter von runserver helfen.
Diese Methode ist ineffizient und unsicher. Verwende sie nie in einem Produktivsystem sondern lediglich während der Entwicklungsphase.
Für Information wie du statische Dateine mit Apache in einem Produktivsystem ausliefern kannst, schau dir die “Django mit mod_python”-Documentation an.
So sieht die Signatur vom serve()-View aus:
Um ihn zu verwende, trage folgende Zeilen in deine URLconf ein:
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': '/path/to/media'}),
... wobei site_media die Basis-URL ist und /path/to/media das Basisverzeichnis im Dateisystem darstellt. Der document_root-Parameter, mit dem die View-Funktion dann schlussendlich aufgerufen wird, ist für dies View verpflichtend.
Mit dieser URLConf steht ...
Natürlich musst du den Document-Root nicht dermaßen fix in der URLConf angeben. Einfacher verwaltbar wäre eine neue Einstellung innerhalb der settings.py für diesen Pfad:
STATIC_DOC_ROOT = '/path/to/media'
Der URLconf-Eintrag von oben würde dann so aussehen:
from django.conf import settings
...
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.STATIC_DOC_ROOT}),
Sei jedoch vorsichtig, dass du nicht denselben Pfad wie für die ADMIN_MEDIA_PREFIX-Einstellung (welche standardmässig auf /media/ gesetzt ist) verwendest, da diese deinen URLConf-Eintrag überschreibt.
Wenn du dem serve()-View den optionalen Parameter show_indexes übergibst und diesen auf True setzt, wird Django auch die Dateien in Verzeichnissen auflisten. Standardmässig ist dieser Parameter auf False gesetzt.
Zum Beispiel:
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': '/path/to/media', 'show_indexes': True}),
Du kannst die Darstellung auch über das static/directory_index.html-Template verändern. Es erhält zwei Objekte über den Kontext:
So sieht das ursprüngliche static/directory_index.html-Template aus:
<!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" />
<meta name="robots" content="NONE,NOARCHIVE" />
<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>
Da Djangos URLConfs normale Python-Module sind, kannst du einfach erreichen, dass der hier behandelte View lediglich während der Entwicklungsphase deines Projektes verwendet wird.
Umschließe einfach den django.views.static.serve()-Eintrag mit if settings.DEBUG:
from django.conf.urls.defaults import *
from django.conf import settings
urlpatterns = patterns('',
(r'^articles/2003/$', 'news.views.special_case_2003'),
(r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'news.views.month_archive'),
(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d+)/$', 'news.views.article_detail'),
)
if settings.DEBUG:
urlpatterns += patterns('',
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': '/path/to/media'}),
)
Hier wird das settings-Modul geladen und dazu genutzt, der django.views.static.serve-View nur dann eine URL zuzuweisen, wenn sich die Seite im DEBUG-Modus befindet. Wenn nicht, steht dieser View nicht zur Verfügung und die statischen Dateien werden nicht durch Django selbst ausgeliefert.
Natürlich musst du dich nun daran erinnern, DEBUG=False zu setzen, sobald du die Seite im Produktivsystem einsetzt. Aber das solltest du ohnehin immer.
Mar 01, 2010