Como servir arquivos estáticos¶
Django, por si só, não serve arquivos estáticos (media), como imagens, folhas de estilo (CSS), ou vídeo. Esse trabalho é deixado para o servidor Web de sua escolha.
O motivo para isso é que servidores Web comuns, como Apache e lighttpd e Cherokee, são muito mais apropriados para servir arquivos estáticos do que um framework de aplicações web.
Dito isso, Django suporta arquivos estáticos durante o desenvolvimento. Você
pode usar a view django.views.static.serve() para servir arquivos
estáticos.
See also
Se você precisa servir mídia administrativa de uma localização não padrão, veja
o parâmetro --adminmedia para runserver.
Não diga que não avisamos¶
Usar este método é ineficiente e inseguro. Não use isso em um ambiente de produçao. Use apenas para desenvolvimento.
Para informações sobre servir arquivos estáticos em um ambiente de produção com Apache, veja a documentação Django mod_python.
Como proceder¶
Aqui temos a definição formal da view serve():
-
def serve(request, path, document_root, show_indexes=False):
Para usá-la, somente coloque isto na sua URLconf:
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': '/path/to/media'}),
...onde site_media é a URL onde a sua mídia será mapeada, e
/path/to/media é a pasta raiz para sua mídia. Isto irá chamar a view
serve(), passando o caminho da URLconf e o parâmetro
(obrigatório) document_root.
Dado o URLconf acima:
- O arquivo
/path/to/media/foo.jpgserá mapeado para a URL/site_media/foo.jpg. - O arquivo
/path/to/media/css/mystyles.cssserá mapeado para a URL/site_media/css/mystyles.css. - O arquivo
/path/bar.jpgnão será acessível, pois não é mapeado para a pasta raiz.
É claro, não é obrigatória a utilização de uma string fixa para o valor
'document_root'. Você pode querer ter uma variável em seu arquivo settings
e usar o valor que estiver nela. Que permitirá a você e outros desenvolvedores
trabalhar sobre o código facilmente, mudando o valor como quiserem. Por exemplo,
se nós tivermos uma linha no settings.py que diz:
STATIC_DOC_ROOT = '/path/to/media'
...nós poderiamos escrever uma entrada URLconf desta forma:
from django.conf import settings
...
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.STATIC_DOC_ROOT}),
Tome cuidado para não usar o mesmo caminho da sua configuração ADMIN_MEDIA_PREFIX (cujo padrão
é /media/) já que isso irá sobrescrever sua entrada na configuração de URL.
Listagem de diretórios¶
Opcionalmente, você pode passar um parâmetro show_indexes para a view
serve(). O valor padrão é False. Se for True,
o Django exibirá uma listagem dos arquivos dos diretórios.
Exemplo:
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': '/path/to/media', 'show_indexes': True}),
Você pode customizar a exibição do índice criando um template chamado
static/directory_index. Esse template recebe dois objetos em seu contexto:
directory– o nome do diretório (como string)file_list– a lista de nomes de arquivos (como strings) no diretório
Aqui está o template static/directory_index.html padrão:
<!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>
static/directory_listing (sem extensão .html). Para compatibilidade
retroativa, o Django ainda carrega templates com o nome
antigo (sem extensão), mas irá preferir a versão
directory_index.html, com extensão.Limitando o uso para DEBUG=True¶
Como URLconfs são simples módulos Python, você pode usar lógica Python para fazer com que a exibição de arquivos estáticos seja possível apenas em fase de desenvolvimento. Esse é um truque útil para se certificar de que a exibição de arquivos estáticos não seja usada em modo de produção por engano.
Faça isso inserindo uma instrução if DEBUG em volta da inclusão do
django.views.static.serve(). Aqui está um exemplo completo de URLconf:
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'}),
)
Este código é simples. Ele importa as configurações e checa o valor do
DEBUG. Se for avaliado como True, então site_media será
associada com a view django.views.static.serve. Caso contrário então a view
não estará disponível.
Obviamente, a questão aqui é lembrar-se de colocar DEBUG=False no arquivo de
configurações. Mas você já devia fazer isso de qualquer forma.