Приложение staticfiles
django.contrib.staticfiles собирает статические файлы из каждого из ваших приложений (и любых других указанных вами мест) в одно место, которое легко обслуживать в рабочей среде.
См. также
Для знакомства с приложением static files и примерами его использования см. Как управлять статическими файлами (например, изображениями, JavaScript, CSS). Сведения о развертывании статических файлов см. в Как развернуть статические файлы.
Настройки
Подробные сведения о следующих настройках см. в настройках staticfiles:
Команды управления
django.contrib.staticfiles предоставляет три команды управления.
collectstatic
-
django-admin collectstatic
Собирает статические файлы в STATIC_ROOT.
Дублирующие имена файлов по умолчанию разрешаются аналогично тому, как работает разрешение шаблонов: будет использоваться файл, который первый найден в одном из указанных мест. Если вы запутались, команда findstatic поможет вам увидеть, какие файлы найдены.
При последующих collectstatic запусках (если STATIC_ROOT не пусто), файлы копируются только в том случае, если отметка времени изменения больше, чем отметка времени файла в STATIC_ROOT. Поэтому, если вы удаляете приложение из INSTALLED_APPS, рекомендуется использовать опцию collectstatic
--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 -
Не запрашивать у пользователя ввод.
-
--ignore PATTERN, -i PATTERN -
Игнорировать файлы, каталоги или пути, соответствующие этому шаблону в стиле glob. Используйте несколько раз для игнорирования большего количества. При указании пути всегда используйте прямые слэши, даже в Windows.
-
--dry-run, -n -
Выполнить все действия, кроме изменения файловой системы.
-
--clear, -c -
Очистить существующие файлы перед копированием или созданием ссылки на исходный файл.
-
--link, -l -
Создать символическую ссылку на каждый файл вместо копирования.
-
--no-post-process -
Не вызывать метод
post_process()конфигурированного хранилищаstaticfilesизSTORAGES.
-
--no-default-ignore -
Не игнорировать общие шаблоны для частных случаев в стиле glob:
'CVS','.*'и'*~'.
Полный список опций можно посмотреть, запустив помощь для команды:
$ 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
Это вспомогательная функция отладки; она точно покажет, какой статический файл будет собран для заданного пути.
Установив флаг --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
С другой стороны, установив флаг --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, и добавляет автоматическое предоставление статических файлов. Обслуживание файлов не происходит через MIDDLEWARE.
Команда добавляет следующие опции:
-
--nostatic
Используйте опцию --nostatic для отключения предоставления статических файлов с помощью приложения staticfiles полностью. Эта опция доступна только в том случае, если приложение staticfiles указано в вашей настройке INSTALLED_APPS.
Пример использования:
$ django-admin runserver --nostatic
...\> django-admin runserver --nostatic
-
--insecure
Используйте опцию --insecure для принудительного предоставления статических файлов с приложением staticfiles, даже если значение настройки DEBUG равно False. Используя этот метод, вы подтверждаете, что он крайне неэффективен и, вероятно, небезопасен. Он предназначен только для разработки, его никогда нельзя использовать в производстве и доступен только в том случае, если приложение staticfiles указано в настройке INSTALLED_APPS вашего проекта.
--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 после каждого выполнения и получает в качестве аргумента словарь с локальными хранилищами и путями найденных файлов, а также опции командной строки. Он возвращает кортежи из трех значений: original_path, processed_path, processed. Пути представляют собой строки, а processed — булево значение, указывающее, был ли результат обработан, или исключение в случае неудачной обработки.
Хранилище ManifestStaticFilesStorage использует его «под капотом», чтобы заменить пути на их хешированные аналоги и соответствующим образом обновить кэш.
ManifestStaticFilesStorage
-
class storage.ManifestStaticFilesStorage
Подкласс хранилища бэкенда StaticFilesStorage, который хранит имена файлов, добавляя к имени файла хэш MD5 содержимого файла. Например, файл css/styles.css также будет сохранен как css/styles.55e7cbb9ba48.css.
Цель этого хранилища — обеспечить доступ к старым файлам в случае, если некоторые страницы все еще ссылаются на эти файлы, например, из-за кэширования с вашей или сторонней стороны. Кроме того, это очень полезно, если вы хотите применить заголовки Expires на большое будущее (https://developer.yahoo.com/performance/rules.html#expires) к развернутым файлам для ускорения времени загрузки при последующих посещениях страниц.
Хранилище бэкенда автоматически заменяет пути, найденные в сохраненных файлах, соответствующие другим сохраненным файлам, на путь к кэшированной копии (используя метод post_process()). Регулярные выражения, используемые для поиска этих путей (django.contrib.staticfiles.storage.HashedFilesMixin.patterns), охватывают:
- Правило @import и оператор url() Каскадных таблиц стилей.
- Комментарии карты исходных данных (https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Use_a_source_map) в файлах CSS и JavaScript.
Подкласса ManifestStaticFilesStorage и установите атрибут support_js_module_import_aggregation на значение True, если вы хотите использовать экспериментальные регулярные выражения для покрытия:
- Импорт модулей (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#importing_features_into_your_script) в JavaScript.
- Агрегацию модулей (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#aggregating_modules) в JavaScript.
Например, файл 'css/styles.css' с этим содержимым:
@import url("../admin/css/base.css");
…будет заменен вызовом метода url() хранилища бэкенда ManifestStaticFilesStorage, в конечном итоге сохраняя файл 'css/styles.55e7cbb9ba48.css' с приведенным ниже содержимым:
@import url("../admin/css/base.27e20196a850.css");
Использование атрибута integrity HTML с локальными файлами
При использовании необязательного атрибута integrity в тегах, таких как <script> или <link>, его значение должно рассчитываться на основе файлов, как они предоставляются, а не как они хранятся в файловой системе. Это особенно важно, так как в зависимости от того, как собираются статические файлы, их контрольная сумма может измениться (например, при использовании collectstatic). В настоящее время для этого нет встроенных инструментов.
Вы можете изменить расположение файла manifest, используя пользовательский подкласс 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)
Добавлена экспериментальная необязательная поддержка поиска путей к модулям JavaScript в import и export операторах.
-
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 из фрагментов содержимого, как указано выше. Вы можете переопределить этот метод, чтобы использовать свой собственный алгоритм хеширования.
ManifestFilesMixin
-
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.template.context_processors.static(), который добавляетSTATIC_URLв контекст каждой шаблона, рендерящейся с контекстамиRequestContext. - Встроенная метка шаблона
static, которая принимает путь и склеивает его с префиксом URL статического ресурсаSTATIC_URL. Еслиdjango.contrib.staticfilesустановлен, метка использует методurl()бэкенда храненияstaticfilesизSTORAGESвместо этого. - Встроенная метка шаблона
get_static_prefix, которая заполняет переменную шаблона префиксом URL статического ресурсаSTATIC_URLдля использования в качестве переменной или напрямую. - Аналогичная метка шаблона
get_media_prefix, которая работает так же, какget_static_prefix, но используетMEDIA_URL. - Ключ
staticfilesвdjango.core.files.storage.storagesсодержит готовый экземпляр бэкенда хранения статических файлов.
Просмотр разработки статических файлов
Инструменты для работы со статическими файлами в основном предназначены для успешной публикации статических файлов в рабочей среде. Обычно это означает отдельный, выделенный сервер статических файлов, что создаёт много накладных расходов при локальной разработке. Поэтому приложение staticfiles поставляется с быстрым и грязным вспомогательным представлением, которое можно использовать для обслуживания файлов локально в процессе разработки.
-
views.serve(request, path)
Эта функция представления обслуживает статические файлы в процессе разработки.
Предупреждение
Это представление будет работать только если DEBUG значение True.
Это связано с тем, что это представление чрезвычайно неэффективно и, вероятно, небезопасно. Оно предназначено только для локальной разработки и никогда не должно использоваться в рабочей среде.
Примечание
Для определения типов содержимого обслуживаемых файлов это представление полагается на модуль mimetypes из стандартной библиотеки Python, который, в свою очередь, зависит от файлов отображения платформы. Если вы обнаружите, что это представление не возвращает правильные типы содержимого для определенных файлов, скорее всего, файлы отображения платформы некорректны или требуют обновления. Это можно сделать, например, установив или обновив пакет mailcap на дистрибутивах Red Hat, mime-support на дистрибутивах Debian или отредактировав ключи в HKEY_CLASSES_ROOT в реестре Windows.
Это представление автоматически включается runserver (с установкой DEBUG в True).
Чтобы использовать представление с другим локальным сервером разработки, добавьте следующий фрагмент в конец вашей основной конфигурации 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),
]
Обратите внимание, что начало шаблона (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/.
Это связано с тем, что это представление чрезвычайно неэффективно и, вероятно, небезопасно. Оно предназначено только для локальной разработки и никогда не должно использоваться в рабочей среде.
Специализированный тестовый случай для поддержки «тестирования в реальном времени»
-
class testing.StaticLiveServerTestCase
Этот подкласс тестового случая unittest расширяет django.test.LiveServerTestCase.
Так же как и его родитель, вы можете использовать его для написания тестов, которые включают запуск тестируемого кода и его потребление средствами тестирования через HTTP (например, Selenium, PhantomJS и т. д.), поэтому необходимо, чтобы статические ресурсы также были опубликованы.
Но учитывая тот факт, что он использует представление django.contrib.staticfiles.views.serve(), описанное выше, он может прозрачно перекрывать во время выполнения теста ресурсы, предоставляемые поисковыми инструментами staticfiles. Это означает, что вам не нужно запускать collectstatic перед или в качестве части настройки ваших тестов.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/5.0/ref/contrib/staticfiles/
Ссылки в комментариях
ManifestStaticFilesStorageне игнорирует пути в комментариях. Это может привести к сбою по несуществующим путям. Вам следует проверить и, при необходимости, удалить комментарии.