Приложение staticfiles

django.contrib.staticfiles собирает статические файлы из каждого из ваших приложений (и любых других мест, которые вы укажете) в одно место, которое можно легко обслуживать в продакшене.

См.также

Введение в приложение статических файлов и некоторые примеры использования см. в How to manage static files (e.g. images, JavaScript, CSS). Рекомендации по развертыванию статических файлов см. в How to deploy static files.

Настройки

См. раздел staticfiles settings для получения подробной информации о следующих настройках:

Команды управления

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_STORAGE после каждого запуска и передает список путей, которые были найдены командой управления. Она также получает все опции командной строки collectstatic. Этот метод используется ManifestStaticFilesStorage по умолчанию.

По умолчанию собранные файлы получают разрешения FILE_UPLOAD_PERMISSIONS, а собранные каталоги получают разрешения FILE_UPLOAD_DIRECTORY_PERMISSIONS. Если вы хотите получить разные разрешения для этих файлов и/или каталогов, вы можете подклассифицировать любой из static files storage classes и указать параметры 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_STORAGE на 'path.to.MyStaticFilesStorage'.

Некоторые часто используемые варианты:

--noinput, --no-input

НЕ запрашивайте у пользователя какие-либо данные.

--ignore PATTERN, -i PATTERN

Игнорировать файлы, каталоги или пути, соответствующие этому шаблону в стиле glob. Используйте несколько раз, чтобы игнорировать больше. При указании пути всегда используйте прямые косые черты, даже в Windows.

--dry-run, -n

Делайте все, кроме изменения файловой системы.

--clear, -c

Очистите существующие файлы, прежде чем пытаться скопировать или связать исходный файл.

Вместо копирования создайте символическую ссылку на каждый файл.

--no-post-process

Не вызывайте метод post_process() настроенного бэкенда хранилища STATICFILES_STORAGE.

--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. Используя это, вы признаете тот факт, что это очень неэффективно и, вероятно, небезопасно. Это предназначено только для локальной разработки, никогда не должно использоваться в production и доступно только если в настройках вашего проекта staticfiles app находится в настройках 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.

Цель такого хранения - продолжать обслуживать старые файлы в случае, если некоторые страницы все еще ссылаются на эти файлы, например, потому что они кэшируются вами или сторонним прокси-сервером. Кроме того, это очень полезно, если вы хотите применить far future Expires headers к развернутым файлам, чтобы ускорить время загрузки при последующих посещениях страниц.

The storage backend automatically replaces the paths found in the saved files matching other saved files with the path of the cached copy (using the post_process() method). The regular expressions used to find those paths (django.contrib.staticfiles.storage.HashedFilesMixin.patterns) cover:

Например, файл 'css/styles.css' с таким содержанием:

@import url("../admin/css/base.css");

…would be replaced by calling the url() method of the ManifestStaticFilesStorage storage backend, ultimately saving a 'css/styles.55e7cbb9ba48.css' file with the following content:

@import url("../admin/css/base.27e20196a850.css");

Вы можете изменить расположение файла манифеста, используя пользовательский подкласс 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)
Changed in Django Development version:

Support for finding paths in CSS source map comments was added.

Changed in Django 4.2:

Support for finding paths to JavaScript modules in import and export statements was added.

storage.ManifestStaticFilesStorage.max_post_process_passes

Поскольку статические файлы могут ссылаться на другие статические файлы, пути к которым необходимо заменить, может потребоваться несколько проходов замены путей, пока хэши файлов не сойдутся. Для предотвращения бесконечного цикла из-за не сходящихся хэшей (например, если 'foo.css' ссылается на 'bar.css', который ссылается на 'foo.css') существует максимальное количество проходов до отказа от постобработки. В случаях с большим количеством ссылок может потребоваться большее количество проходов. Увеличьте максимальное число проходов, создав подкласс ManifestStaticFilesStorage и установив атрибут max_post_process_passes. По умолчанию он равен 5.

Чтобы включить ManifestStaticFilesStorage, необходимо убедиться в выполнении следующих требований:

  • настройка STATICFILES_STORAGE устанавливается на '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_STORAGE установлен на что-то другое, например 'django.contrib.staticfiles.storage.StaticFilesStorage' (по умолчанию).

storage.ManifestStaticFilesStorage.file_hash(name, content=None)

Метод, который используется при создании хэшированного имени файла. Должен возвращать хэш для заданного имени файла и содержимого. По умолчанию он вычисляет хэш MD5 из фрагментов содержимого, как указано выше. Не стесняйтесь переопределить этот метод, чтобы использовать свой собственный алгоритм хэширования.

ManifestFilesMixin

class storage.ManifestFilesMixin

Используйте этот миксин с пользовательским хранилищем для добавления MD5-хэша содержимого файла к имени файла, как это делает ManifestStaticFilesStorage.

Модуль искателей

staticfiles finders имеет атрибут searched_locations, который представляет собой список путей каталогов, в которых искал finders. Пример использования:

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, который принимает путь и соединяет его со статическим префиксом STATIC_URL. Если установлен django.contrib.staticfiles, то вместо него тег использует метод url() из STATICFILES_STORAGE.
  • Встроенный тег шаблона get_static_prefix, который заполняет переменную шаблона статическим префиксом STATIC_URL для использования в качестве переменной или напрямую.
  • Аналогичный шаблонный тег get_media_prefix, который работает как get_static_prefix, но использует MEDIA_URL.

Представление разработки статических файлов

Инструменты для работы со статическими файлами в основном предназначены для помощи в успешном развертывании статических файлов в производстве. Обычно это означает отдельный, выделенный сервер статических файлов, который требует больших накладных расходов при локальной разработке. Таким образом, приложение staticfiles поставляется с быстрым и грязным вспомогательным представлением, которое вы можете использовать для локального обслуживания файлов при разработке.

views.serve(request, path)

Эта функция просмотра обслуживает статические файлы в процессе разработки.

Предупреждение

Это представление будет работать только в том случае, если DEBUG будет True.

Это потому, что такой вид очень неэффективен и, вероятно, небезопасен. Оно предназначено только для локальной разработки и никогда не должно использоваться в производстве.

Примечание

To guess the served files“ content types, this view relies on the mimetypes module from the Python standard library, which itself relies on the underlying platform’s map files. If you find that this view doesn’t return proper content types for certain files, it is most likely that the platform’s map files are incorrect or need to be updated. This can be achieved, for example, by installing or updating the mailcap package on a Red Hat distribution, mime-support on a Debian distribution, or by editing the keys under HKEY_CLASSES_ROOT in the Windows registry.

Это представление автоматически включается по 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 TestCase расширяет django.test.LiveServerTestCase.

Как и его родитель, вы можете использовать его для написания тестов, которые включают в себя запуск тестируемого кода и его потребление инструментами тестирования через HTTP (например, Selenium, PhantomJS и т.д.), из-за чего необходимо, чтобы статические активы также были опубликованы.

Но учитывая тот факт, что он использует представление django.contrib.staticfiles.views.serve(), описанное выше, он может прозрачно накладывать во время выполнения теста активы, предоставляемые искателями staticfiles. Это означает, что вам не нужно запускать collectstatic до или как часть настройки ваших тестов.

Вернуться на верх