Главная > web, Программирование > Django: Настраиваем STATIC_ROOT, STATICFILES_DIRS и MEDIA_ROOT правильно.

Django: Настраиваем STATIC_ROOT, STATICFILES_DIRS и MEDIA_ROOT правильно.

Для начала определимся с разницей между статикой и медиа-файлами в терминах Django. Первое - это все ваши файлы, которые вы сами создавали: css-стили, js-скрипты, картинки для дизайна и т.п. Медиа-файлы - всё, что загружает пользователь на ваш сервер (автарки, фотки), т.е. пользовательский контент. С пользовательским контентом всё более-менее просто и поэтому мы рассмотрим настройку только в конце поста.

Честно говоря, я как-то упустил из виду когда появилось встроенное приложение django.contrib.staticfiles, поэтому, столкнулся с ним только на последнем проекте, пришлось потратить какое-то время чтобы понять что к чему и почему не достаточно использовать просто STATIC_ROOT, как раньше.

Итак, сначала ответим на последний вопрос: главная проблема использования в Django просто STATIC_ROOT в качестве указателя пути до статики заключается в том, что не вся наша статика может быть связана с нашим проектом. Ущербность такого подхода ощущал каждый, кто подключал статику встроенной в Django админки на боевом сервере - приходилось либо делать ссылку на папку в дебрях Django со статикой для админки, либо вообще копировать всё оттуда в STATIC_ROOT. А представьте если таких приложений с нужной статикой у вас много - всё собирать ручками занятие не благородное. Более того, статика вообще может лежать какой-нибудь CDN (Content Delivery Network - сеть доставки контента) по типу Amazon S3.

В текущих реалиях в Django мы имеем два "вида" статики:

  1. Специфичная для приложения, которая, по-хорошему, должна лежать внутри этого приложения в папке static, желательно даже ещё глубже: "/static//" дабы исключить вероятность пересечения путей файлов с другими приложениями.
  2. Специфичная для проекта статика. Для неё можно создать папку в корне, в примерах назовём эту папку assets.

Первым пунктом можно пренебречь и хранить всё на уровне проекта, если вы не планируете делать переносимое приложение ("reusable"), тут есть как плюсы: всё в одном месте, так и минусы: если вы захотите убрать приложение, может потребоваться больше усилий, либо, на больших проектах, это может создать кашу.

При таком подходе настройки STATIC_ROOT и STATICFILES_DIRS должны указывать на следующее:

  • STATIC_ROOT - указывает на изначально пустую папку, в которую будет собрана вся статика: как project-wide, так и app-specific. Эту папку, в общем случае, должен обслуживать frontend web-сервер (например, nginx).
  • STATICFILES_DIRS - должна содержать путь до assets:
    STATICFILES_DIRS = ('/path/to/assets/', )

После этого на боевом сервере (читай "DEBUG = False") перед развёртыванием приложения надо выполнить команду:
python manage.py collectstatic

Которая соберёт все файлы в папку STATIC_ROOT.

Для dev-сервера Django (т.е. если вы используете команду "python manage.py runserver" для разработки) настройка статики закончена и запускать команду collectstatic не обязательно - статика будет подцеплена автоматом. Однако, если вы используете другой сервер для разработки, то вы можете заставить Django обрабатывать статику добавив немного "магии" в ваш urls.py. Также в urls.py надо будет добавить URL для медиа-файлов. Итак, вот фрагменты файла настроек settings.py:

# эта переменная будет указывать на папку проекта
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))

# путь до папки media, в общем случае она пуста в начале
MEDIA_ROOT = os.path.join(PROJECT_ROOT, 'media')
MEDIA_URL = '/media/' # URL для медии в шаблонах

STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static') # пустая папка, сюда будет собирать статику collectstatic
STATIC_URL = '/static/' # URL для шаблонов

STATICFILES_DIRS = (
os.path.join(PROJECT_ROOT, 'assets'),
)

# "Поисковики" статики. Первый ищет статику в STATICFILES_DIRS,
# второй в папках приложений.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)

# Тут должно быть добавлено встроенное в Django приложение для работы со статикой.
INSTALLED_APPS = (
<...>
'django.contrib.staticfiles',
<...>
)

А вот содержимое urls.py:

from django.conf.urls.static import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.conf import settings

<..>

# В конце файла:
if settings.DEBUG:
if settings.MEDIA_ROOT:
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)
# Эта строка опциональна и будет добавлять url'ы только при DEBUG = True
urlpatterns += staticfiles_urlpatterns()

Напоследок, хочу заметить, что некоторые описанные детали справедливы только для общего случая. Рекомендую также прочитать официальную документацию Django.

Пожалуйста, оцените полезность и качество данной статьи. Одна звезда - плохо, 5 - хорошо.
1/5. Мы будем признательны, если вы напишете комментарий с причиной низкой оценки.2/5. Мы будем признательны, если вы напишете комментарий с причиной низкой оценки.3/5. Мы будем признательны, если вы напишете комментарий с причиной низкой оценки.4/5.5/5. (7 голосов, средний: 4,14 из 5)
Загрузка...
  1. baloon
    14 июля 2013 в 16:03 | #1

    Спасибо большое. Кратко и по делу)). Помогло немного разобраться.

    Только для Django 1.5 путь для staticfiles_urlpatterns() немного другой:

    from django.contrib.staticfiles.urls import staticfiles_urlpatterns

    # ... the rest of your URLconf here ...

    urlpatterns += staticfiles_urlpatterns()

    http://www.djbook.ru/rel1.5/ref/contrib/staticfiles.html?highlight=staticfiles_urlpatterns#django.contrib.staticfiles.templatetags.staticfiles.django.contrib.staticfiles.urls.staticfiles_urlpatterns

  2. lizz
    14 июля 2013 в 23:42 | #2

    @baloon
    Спасибо за уточнение, поправим пост.

  3. Viktor
    15 января 2017 в 21:01 | #3

    Спасибо!

  4. Александр
    22 ноября 2017 в 22:14 | #4

    Друг, сделал всё по твоей инструкции, и всёравно не помогло.
    Стилей нет ни у сайта ни у админ панели.
    У меня django 1.11.7 работает на virtualenv на виртуальной машине
    Есть еще какой-нибудь реальный способ оживить стили?
    Помоги, уже месяц парюсь.

  1. Пока что нет уведомлений.