DJANGO: как обслуживать статические файлы (HOWTO - перевод с английского)

Jun 17, 2010 09:54

Только начал разрабатывать свое первое веб-приложение на django, и уже наткнулся на первую трудность. При создании шаблона (так, как это описано в четвертой главе djbook.ru) у меня почему-то возникли трудности с css и изображениями. То есть сам html-файл загружается, то css и изображения (то есть медиа-файлы) - нет.

Как выяснилось,это довольно распространенная проблема, о которой много написано в Интернете, и есть соответствующая инструкция решения этой проблемы на сайте djangoproject.com. Но на русском перевода этой страницы нет. Я решил исправить эту ситуацию, тем более что мне самому так проще было вчитаться и изучить эту проблему. Перевод предельно близкий к оригиналу, но все же не всегда дословный - прошу иметь это в виду, если будете читать.

Оригинал: http://docs.djangoproject.com/en/dev/howto/static-files/

КАК ОБСЛУЖИВАТЬ СТАТИЧЕСКИЕ ФАЙЛЫ

Джанго сама по себе не обслуживает статические файлы, такие как css, изображения, видео и т.д. Эту работу должен выполнять веб-сервер, который вы выбрали. Дело в том, что стандартные веб-сервера, такие как Apache, lighttpd и Cherokee, гораздо лучше работают с такими файлами, нежели фреймворк для разработки веб-приложений.

Учитывая сказанное, Джанго в действительности поддерживает статические файлы в процессе разработки. Вы можете использовать представление djago.views.static.serve() для обслуживания медиа-файлов.

ПРИМЕЧАНИЕ. --- Если вам необходимо, чтобы admin обслуживал медиа при нестандартном размещении, обратите внимание на --adminmedia, параметр runserver ---

ПРЕДУПРЕЖДЕНИЕ! --- Использование этой команды неэффективно и небезопасно. Используйте ее только для разработки, но не для производства программных продуктов. Для получения информации об обслуживании статических файлов продуктами Apache обратитесь по ссылке: Django mod_python documentation. ---

КАК ЭТО ДЕЛАЕТСЯ

Формальное определение функции serve():

def serve(request, path, document_root, show_indexes=False)

Для использования этой функции введите в ваш файл URLconf :

(r'^site_media/(?P
.*)$', 'django.views.static.serve',
        {'document_root': '/path/to/media'}),

где site_media - это URL, в котором будут отображены ваши медиа-файлы;
/path/to/media/ - это адрес в файловой системе, по которому следует искать ваши медиа-файлы.

Это [регулярное] выражение вызывает представление serve(), передавая ей соответствующий URL и адрес каталога с медиа-файлами.

Для случая с вышеозначенным URLconf:
  • файл /path/to/media/foo.jpg будет доступен по URL /site_media/foo.jpg
  • файл /path/to/media/css/mystyles.css будет доступен по URL site_media/css/mystyles.css
  • файл /path/bar.jpg не будет доступен, так как он не находится в корневом каталоге

Конечно, совсем не обязательно использовать фиксированное значение 'document_root'. Возможно, вы пожелаете определить это значение в качестве используемого параметра. Это позволит вам и другим разработчикам, работающим с вашим кодом, проще изменять это значение, если потребуется. Например, если в файле settings.py вы пропишете следующую строку:

STATIC_DOC_ROOT = '/path/to/media'

то в URLconf вы могли бы прописать следующее выражение:

from django.conf import settings
...
(r'^site_media/(?P
.*)$', 'django.views.static.serve',
        {'document_root': settings.STATIC_DOC_ROOT}),

Будьте осторожны, не используйте тот же адрес в вашем ADMIN_MEDIA_PREFIX (который определяет путь по умолчанию к /media/), иначе вы измените путь к вшему URLconf.

ЛИСТИНГ ДИРЕКТОРИЙ

Пожеланию вы можете определить параметр show_indexes для функции serve(). По умолчанию этот параметр равен False. Если параметр равен True, то Джанго покажет вам листинг директорий.

Например:

(r'^site_media/(?P
.*)$', 'django.views.static.serve',
        {'document_root': '/path/to/media', 'show_indexes': True}),

Вы можете изменить вывод, используя шаблон static/directory_index.html. Этот шаблон принимает два объекта в своем контексте:
  • directory - наименование каталога (строка)
  • file_list - перечень наименований файлов (строка) внутри каталога
Так выглядит шаблон static/directory_index.html по умолчанию:

xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

http-equiv="Content-type" content="text/html; charset=utf-8" />
     http-equiv="Content-Language" content="en-us" />
     name="robots" content="NONE,NOARCHIVE" />
    Index of {{ directory }}

Index of {{ directory }}


        {% for f in file_list %}
        
  •  href="{{ f }}">{{ f }}

  •     {% endfor %}
        


Изменения по сравнению Джанго 1.0.3. --- В предшествующей версии Джанго 1.0.3 существует ошибка , которая возникает при просмотре листинга директорий. Загружаемый шаблон должен называться static/directory_listing (без расширения .html). В целях своместимости с ранними версиями, Джанго все еще загружает шаблоны со старым именем (без расширения), но все-таки более предпочительно использовать шаблон directory_index.html. ---

ОГРАНИЧЕННОЕ ИСПОЛЬЗОВАНИЕ DEBUG=True

Поскольку URLconf - это простой модуль Python, вы можете использовать питоновскую логику, чтобы обеспечивать поддержку статических файлов только на этапе разработки. Это небольшая хитрость, которая позволяет гарантировать, что использование статических файлов на приведет к ошибке на боевом сервере.

Трюк состоит в использовании параметра DEBUG, который определяет условие использования serve(). Так выглядит полноценный 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\d{4})/$', 'news.views.year_archive'),
    (r'^articles/(?P\d{4})/(?P\d{2})/$', 'news.views.month_archive'),
    (r'^articles/(?P\d{4})/(?P\d{2})/(?P\d+)/$', 'news.views.article_detail'),
)

if settings.DEBUG:
    urlpatterns += patterns('',
        (r'^site_media/(?P
.*)$', 'django.views.static.serve', {'document_root': '/path/to/media'}),
    )

Это простой пример. Он импортирует установки и проверяет значение параметра DEBUG. Если параметр возвращает значение ИСТИНА, то site_media ассоциируется с представлением django.views.static.serve. Если нет, то представление остается недоступным.

Конечно, для этого вы должны не забывать определять значение DEBUG = False. Но об этом вы должны помнить в любом случае.

django, python, перевод