Приложения для работы со статическими файлами¶
django.contrib.staticfiles собирает статические файлы со всех ваших приложений (и остальных мест, которые вы укажите) в одном месте, что позволяет легко настроить выдачу статических файлов на боевом сервере.
См.также
Примеры использования этого приложения для работы со статикой можно найти в разделе Как управлять статическими файлами (изображениями, скриптами JS, CSS и т.д.). Как работать со статикой на боевом сервере описано в разделе Развертывание статических файлов.
Настройки¶
Команды¶
django.contrib.staticfiles предоставляет три команды.
collectstatic¶
- django-admin collectstatic¶
Собирает статические файлы в STATIC_ROOT.
Одинаковые имена файлов обрабатываются как и шаблоны: будет использоваться первый найденный файл. Если вы запутались, команда findstatic может показать какой конкретно файл используется.
При последующем запуске collectstatic (если STATIC_ROOT не пустой), файлы копируются, только если время их изменения больше, чем у файла в STATIC_ROOT. Также, если вы удалите приложение из INSTALLED_APPS, следует использовать опцию :djadminopt:`--clear`, чтобы удалить неиспользуемые статические файлы.
Файлы ищутся используя бэкенды из enabled finders. По умолчанию проверяются каталоги из STATICFILES_DIRS и подкаталоги 'static' приложений из INSTALLED_APPS.
Команда управления collectstatic вызывает метод post_process() бэкенда хранилища staticfiles из STORAGES после каждого запуска и передает список путей, найденных командой управления. Он также получает все параметры командной строки collectstatic. По умолчанию используется ManifestStaticFilesStorage.
По умолчанию, созданные файлы получают права доступа из FILE_UPLOAD_PERMISSIONS, а каталоги из FILE_UPLOAD_DIRECTORY_PERMISSIONS. Если вы хотите использовать другие права доступа для файлов и/или каталогов, вы можете создать дочерний класс бэкенда статических файлов и указать file_permissions_mode и/или directory_permissions_mode параметры соответственно. Например:
from django.contrib.staticfiles import storage
class MyStaticFilesStorage(storage.StaticFilesStorage):
def __init__(self, *args, **kwargs):
kwargs["file_permissions_mode"] = 0o640
kwargs["directory_permissions_mode"] = 0o760
super().__init__(*args, **kwargs)
Затем установите для хранилища staticfiles в настройке STORAGES значение 'path.to.MyStaticFilesStorage'.
Обычно используются следующие параметры:
- --noinput, --no-input¶
Никогда НЕ запрашивать ввод у пользователя. Для этого используйте опцию
--no-input.
- --ignore PATTERN, -i PATTERN¶
Игнорировать файлы и каталоги подходящие под шаблон. Используйте несколько раз, если необходимо передать несколько шаблонов.
- --dry-run, -n¶
Выполнить все операции, кроме тех, которые изменяют файловую систему.
- --clear, -c¶
Удалить существующие файлы перед копированием новых.
- --link, -l¶
Создать симлинк для каждого файла вместо копирования.
- --no-post-process¶
Не вызывайте метод
post_process()сконфигурированного хранилищаstaticfilesизSTORAGES.
Полный список параметров можно посмотреть выполнив:
$ python manage.py collectstatic --help
...\> py manage.py collectstatic --help
Настройка списка игнорируемых шаблонов¶
Список игнорируемых шаблонов по умолчанию, ['CVS', '.*', '*~'], можно настроить более постоянным образом, чем предоставление опции команды --ignore при каждом вызове collectstatic. Предоставьте собственный класс AppConfig, переопределите атрибут ignore_patterns этого класса и замените 'django.contrib.staticfiles' этим путем к классу в настройках INSTALLED_APPS:
from django.contrib.staticfiles.apps import StaticFilesConfig
class MyStaticFilesConfig(StaticFilesConfig):
ignore_patterns = [...] # your custom ignore list
findstatic¶
- django-admin findstatic staticfile [staticfile ...]¶
Ищет файлы по указанному относительному пути(или путях) используя активные бэкенды для поиска файлов.
Например:
$ python manage.py findstatic css/base.css admin/js/core.js
Found 'css/base.css' here:
/home/special.polls.com/core/static/css/base.css
/home/polls.com/core/static/css/base.css
Found 'admin/js/core.js' here:
/home/polls.com/src/django/contrib/admin/media/js/core.js
...\> py manage.py findstatic css\base.css admin\js\core.js
Found 'css/base.css' here:
/home/special.polls.com/core/static/css/base.css
/home/polls.com/core/static/css/base.css
Found 'admin/js/core.js' here:
/home/polls.com/src/django/contrib/admin/media/js/core.js
- findstatic --first¶
По умолчанию, выводятся все найденные файлы. Чтобы вернуть только первый найденный файл, используйте параметр --first:
$ python manage.py findstatic css/base.css --first
Found 'css/base.css' here:
/home/special.polls.com/core/static/css/base.css
...\> py manage.py findstatic css\base.css --first
Found 'css/base.css' here:
/home/special.polls.com/core/static/css/base.css
Предназначена для отладки, чтобы понять какие файлы будут использоваться при сборе статики.
Установив :djadminopt:`--verbosity` флаг в 0, вы можете отфильтровать лишний вывод и получить только пути к файлам:
$ python manage.py findstatic css/base.css --verbosity 0
/home/special.polls.com/core/static/css/base.css
/home/polls.com/core/static/css/base.css
...\> py manage.py findstatic css\base.css --verbosity 0
/home/special.polls.com/core/static/css/base.css
/home/polls.com/core/static/css/base.css
Установив же :djadminopt:`--verbosity` флаг в 2, вы можете увидеть все каталоги, в которых выполняется поиск:
$ python manage.py findstatic css/base.css --verbosity 2
Found 'css/base.css' here:
/home/special.polls.com/core/static/css/base.css
/home/polls.com/core/static/css/base.css
Looking in the following locations:
/home/special.polls.com/core/static
/home/polls.com/core/static
/some/other/path/static
...\> py manage.py findstatic css\base.css --verbosity 2
Found 'css/base.css' here:
/home/special.polls.com/core/static/css/base.css
/home/polls.com/core/static/css/base.css
Looking in the following locations:
/home/special.polls.com/core/static
/home/polls.com/core/static
/some/other/path/static
runserver¶
- django-admin runserver [addrport]
Переопределяет встроенную команду runserver, если приложение staticfiles добавлено в installed, которая автоматом добавляет раздачу статических файлов.
Обычно используются следующие параметры:
- --nostatic¶
Используйте --nostatic чтобы отключить раздачу статических файлов через staticfiles. Опция доступна только если приложение staticfiles добавлено в INSTALLED_APPS.
Пример использования:
$ django-admin runserver --nostatic
...\> django-admin runserver --nostatic
- --insecure¶
Используйте --insecure чтобы раздавать статические файлы через staticfiles даже при DEBUG равном False. Помните, что это крайне неэффективно и возможно небезопасно. Используйте только при разработке, никогда не используйте на боевом сервере. Опция доступна только если приложение staticfiles добавлено в INSTALLED_APPS. runserver --insecure не работает с CachedStaticFilesStorage.
--insecure не работает с ManifestStaticFilesStorage.
Пример использования:
$ django-admin runserver --insecure
...\> django-admin runserver --insecure
Бэкенды¶
StaticFilesStorage¶
- class storage.StaticFilesStorage¶
Наследуется от FileSystemStorage, используйте STATIC_ROOT как расположение файлов и STATIC_URL как основной URL.
- storage.StaticFilesStorage.post_process(paths, **options)¶
Если этот метод определен в хранилище, он вызывается командой управления collectstatic после каждого запуска и получает в виде словаря локальные хранилища и пути к найденным файлам, а также параметры командной строки. Он дает кортежи из трех значений: «исходный_путь, обработанный_путь, обработанный». Значения пути представляют собой строки, а processed представляет собой логическое значение, указывающее, было ли значение подвергнуто постобработке, или исключение, если постобработка не удалась.
CachedStaticFilesStorage использует этот метод, чтобы подменить путь на хешированную версию и соответственно обновить кэш при необходимости.
ManifestStaticFilesStorage¶
- class storage.ManifestStaticFilesStorage¶
Подкласс StaticFilesStorage, который кеширует файлы добавляя MD5 хеш содержимого файла к его названию. Например, файл css/styles.css будет сохранен как css/styles.55e7cbb9ba48.css.
Этот бэкенд необходим, чтобы раздавать старые версии файлов, если они все еще используются некоторыми страницами, например, если страницы кэшированы вами или прокси-сервером. Также, это полезно при большом значении заголовка Expires для статических файлов, чтобы ускорить загрузку страниц.
Серверная часть хранилища автоматически заменяет пути, найденные в сохраненных файлах, совпадающие с другими сохраненными файлами, на путь к кэшированной копии (с использованием метода post_process()). Регулярные выражения, используемые для поиска этих путей (django.contrib.staticfiles.storage.HashedFilesMixin.patterns), охватывают:
Правило @import и оператор url() Каскадных таблиц стилей.
Исходная карта комментариев в файлах CSS и JavaScript.
Подкласс ManifestStaticFilesStorage и установите для атрибута support_js_module_import_aggregation значение True, если вы хотите использовать экспериментальные регулярные выражения для покрытия:
Импорт модулей в JavaScript.
Агрегация модулей в JavaScript.
Например, файл 'css/styles.css' с таким содержимым:
@import url("../admin/css/base.css");
…будет заменен вызовом метода url() бэкенда хранилища ManifestStaticFilesStorage, в конечном итоге сохраняя файл 'css/styles.55e7cbb9ba48.css' со следующим содержимым:
@import url("../admin/css/base.27e20196a850.css");
Использование HTML-атрибута integrity с локальными файлами.
При использовании дополнительного атрибута Integrity в таких тегах, как <script> или <link>, его значение должно рассчитываться на основе файлов в том виде, в котором они обслуживаются, а не на основе того, что хранится в файловой системе. Это особенно важно, поскольку в зависимости от способа сбора статических файлов их контрольная сумма может измениться (например, при использовании collectstatic). На данный момент для этого не существует готового инструмента.
Вы можете изменить местоположение файла манифеста, используя собственный подкласс ManifestStaticFilesStorage, который устанавливает аргумент manifest_storage. Например:
from django.conf import settings
from django.contrib.staticfiles.storage import (
ManifestStaticFilesStorage,
StaticFilesStorage,
)
class MyManifestStaticFilesStorage(ManifestStaticFilesStorage):
def __init__(self, *args, **kwargs):
manifest_storage = StaticFilesStorage(location=settings.BASE_DIR)
super().__init__(*args, manifest_storage=manifest_storage, **kwargs)
- storage.ManifestStaticFilesStorage.manifest_hash¶
Этот атрибут предоставляет единый хэш, который меняется при каждом изменении файла в манифесте. Это может быть полезно для информирования SPA о том, что активы на сервере изменились (из-за нового развертывания).
- storage.ManifestStaticFilesStorage.max_post_process_passes¶
Поскольку статические файлы могут ссылаться на другие статические файлы, пути которых необходимо заменить, может потребоваться несколько проходов замены путей, пока хэши файлов не сойдутся. Чтобы предотвратить бесконечный цикл из-за несхождения хэшей (например, если 'foo.css' ссылается на 'bar.css', который ссылается на 'foo.css'), существует максимальное количество проходов, прежде чем постобработка будет прекращена. В случаях с большим количеством ссылок может потребоваться большее количество проходов. Увеличьте максимальное количество проходов, создав подкласс ManifestStaticFilesStorage и установив атрибут max_post_process_passes. По умолчанию установлено значение 5.
Чтобы включить ManifestStaticFilesStorage, необходимо выполнить следующие действия:
серверная часть хранилища staticfiles в настройке
STORAGESустановлена на'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'установить
DEBUGвFalseвы собрали статические файлы командой
collectstatic
Т.к. вычисление MD5 хеша может понизить производительность приложения, staticfiles автоматически сохраняет соответствия названий файлов с новыми в файле staticfiles.json. Это выполняется один раз при вызове команды collectstatic.
- storage.ManifestStaticFilesStorage.manifest_strict¶
Если файл не найден в манифесте staticfiles.json во время выполнения, выдается ошибка ValueError. Это поведение можно отключить, создав подкласс ManifestStaticFilesStorage и установив для атрибута manifest_strict значение False — несуществующие пути останутся неизменными.
Из-за необходимости запуска collectstatic это хранилище обычно не следует использовать при запуске тестов, поскольку collectstatic не запускается как часть обычной настройки теста. Во время тестирования убедитесь, что серверная часть хранилища staticfiles в настройке STORAGES установлена на что-то другое, например, 'django.contrib.staticfiles.storage.StaticFilesStorage' (по умолчанию).
- storage.ManifestStaticFilesStorage.file_hash(name, content=None)¶
Метод, который вычисляет хеш для файла. Должен вернуть хеш названия и содержимого файла. По умолчанию вычисляет MD5 хеш содержимого файла, как описано выше. Вы можете переопределить этот метод и использовать собственный алгоритм хеширования.
ManifestStaticFilesStorage¶
- class storage.ManifestFilesMixin¶
Используйте этот миксин с пользовательским хранилищем, чтобы добавить MD5-хэш содержимого файла к имени файла, как это делает ManifestStaticFilesStorage.
Модуль поиска файлов¶
Модуль поиска файлов staticfiles содержит атрибут searched_locations, который содержит список каталогов, где происходит поиск файлов. Например:
from django.contrib.staticfiles import finders
result = finders.find("css/base.css")
searched_locations = finders.searched_locations
Дополнительные функции¶
Есть дополнительные функции вне staticfiles для работы со статическими файлами:
Контекстный процессор
django.core.context_processors.static(), который добавляетSTATIC_URLв контекст каждого шаблона отрендеренного с использованиемRequestContext.Встроенный тег шаблона
static, который принимает путь и объединяет его со статическим префиксомSTATIC_URL. Если установленdjango.contrib.staticfiles, тег вместо этого использует методurl()серверной части хранилищаstaticfilesизSTORAGES.Шаблонный тег
get_static_prefix, который создает в шаблоне переменную или просто выводит значениеSTATIC_URL.Шаблонный тег
get_media_prefix, который работает как иget_static_prefix, но дляMEDIA_URL.Ключ
staticfilesвdjango.core.files.storage.storagesсодержит готовый к использованию экземпляр серверной части хранилища staticfiles.
Представления для разработки¶
Инструменты для работой со статикой предназначены для простого развертывания на боевом сервере. Обычно это выделенный сервер, которые не практично использовать при разработке. Поэтому приложение staticfiles содержит простые представления для раздачи статики dev-сервером.
- views.serve(request, path)¶
Представление, которое раздает статические файлы при разработке.
Предупреждение
Работает только при DEBUG равном True.
Потому что представление крайне неэффективно и возможно небезопасно. Оно предназначено для разработки и никогда не должно использоваться на боевом сервере.
Примечание
Чтобы угадать типы содержимого обслуживаемых файлов, это представление использует модуль mimetypes из стандартной библиотеки Python, который в свою очередь опирается на файлы карт базовой платформы. Если вы обнаружите, что это представление не возвращает правильные типы контента для определенных файлов, скорее всего, файлы карт платформы неверны или их необходимо обновить. Этого можно добиться, например, установив или обновив пакет mailcap в дистрибутиве Red Hat, mime-support в дистрибутиве Debian или отредактировав ключи в разделе HKEY_CLASSES_ROOT в реестре Windows.
Это представление автоматически используется командой runserver (при DEBUG равном True). Чтобы использовать его с другим dev-сервером, добавьте следующий код в настройки URL-ов:
from django.conf import settings
from django.contrib.staticfiles import views
from django.urls import re_path
if settings.DEBUG:
urlpatterns += [
re_path(r"^static/(?P<path>.*)$", views.serve),
]
Обратите внимание, что начало URL-шаблона (r'^static/') должно быть равным STATIC_URL.
Т.к. это все немного сложно, можно воспользоваться специальной функцией:
- urls.staticfiles_urlpatterns()¶
Это вернет правильный URL-шаблон для раздачи статических файлов. Используйте ее следующим образом:
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
# ... the rest of your URLconf here ...
urlpatterns += staticfiles_urlpatterns()
Этот код будет использовать значение настройки STATIC_URL для раздачи статических файлов. Не забывайте указать STATICFILES_DIRS чтобы django.contrib.staticfiles мог найти статические файлы.
Предупреждение
Эта функция работает только при DEBUG равном True, настройка STATIC_URL не может быть пустой или полным URL-ом, таким как http://static.example.com/.
Потому что представление крайне неэффективно и возможно небезопасно. Оно предназначено для разработки и никогда не должно использоваться на боевом сервере.
Специальный test case для «живого тестирования»¶
- class testing.StaticLiveServerTestCase¶
Этот unittest TestCase является дочерним классом django.test.LiveServerTestCase.
Как и родительский класс, позволяет писать тесты с использованием Selenium, PhantomJS, и др., для которых необходим доступ к статическим файлам.
Для раздачи статики использует django.contrib.staticfiles.views.serve(). Поэтому вам не нужно выполнять collectstatic перед запуском тестов.
Ссылки в комментариях
ManifestStaticFilesStorageне игнорирует закомментированные пути в операторах. Этот может привести к сбою на несуществующих путях. Вам следует проверить и в конечном итоге удалить комментарии.