494 lines
18 KiB
Plaintext
494 lines
18 KiB
Plaintext
===================
|
|
The staticfiles app
|
|
===================
|
|
|
|
.. module:: django.contrib.staticfiles
|
|
:synopsis: An app for handling static files.
|
|
|
|
``django.contrib.staticfiles`` collects static files from each of your
|
|
applications (and any other places you specify) into a single location that
|
|
can easily be served in production.
|
|
|
|
.. seealso::
|
|
|
|
For an introduction to the static files app and some usage examples, see
|
|
:doc:`/howto/static-files/index`. For guidelines on deploying static files,
|
|
see :doc:`/howto/static-files/deployment`.
|
|
|
|
.. _staticfiles-settings:
|
|
|
|
Settings
|
|
========
|
|
|
|
See :ref:`staticfiles settings <settings-staticfiles>` for details on the
|
|
following settings:
|
|
|
|
* :setting:`STATIC_ROOT`
|
|
* :setting:`STATIC_URL`
|
|
* :setting:`STATICFILES_DIRS`
|
|
* :setting:`STATICFILES_STORAGE`
|
|
* :setting:`STATICFILES_FINDERS`
|
|
|
|
Management Commands
|
|
===================
|
|
|
|
``django.contrib.staticfiles`` exposes three management commands.
|
|
|
|
collectstatic
|
|
-------------
|
|
|
|
.. django-admin:: collectstatic
|
|
|
|
Collects the static files into :setting:`STATIC_ROOT`.
|
|
|
|
Duplicate file names are by default resolved in a similar way to how template
|
|
resolution works: the file that is first found in one of the specified
|
|
locations will be used. If you're confused, the :djadmin:`findstatic` command
|
|
can help show you which files are found.
|
|
|
|
On subsequent ``collectstatic`` runs (if ``STATIC_ROOT`` isn't empty), files
|
|
are copied only if they have a modified timestamp greater than the timestamp of
|
|
the file in ``STATIC_ROOT``. Therefore if you remove an application from
|
|
:setting:`INSTALLED_APPS`, it's a good idea to use the :djadminopt:`--clear`
|
|
option in order to remove stale static files.
|
|
|
|
Files are searched by using the :setting:`enabled finders
|
|
<STATICFILES_FINDERS>`. The default is to look in all locations defined in
|
|
:setting:`STATICFILES_DIRS` and in the ``'static'`` directory of apps
|
|
specified by the :setting:`INSTALLED_APPS` setting.
|
|
|
|
The :djadmin:`collectstatic` management command calls the
|
|
:meth:`~django.contrib.staticfiles.storage.StaticFilesStorage.post_process`
|
|
method of the :setting:`STATICFILES_STORAGE` after each run and passes
|
|
a list of paths that have been found by the management command. It also
|
|
receives all command line options of :djadmin:`collectstatic`. This is used
|
|
by the :class:`~django.contrib.staticfiles.storage.CachedStaticFilesStorage`
|
|
by default.
|
|
|
|
By default, collected files receive permissions from
|
|
:setting:`FILE_UPLOAD_PERMISSIONS` and collected directories receive permissions
|
|
from :setting:`FILE_UPLOAD_DIRECTORY_PERMISSIONS`. If you would like different
|
|
permissions for these files and/or directories, you can subclass either of the
|
|
:ref:`static files storage classes <staticfiles-storages>` and specify the
|
|
``file_permissions_mode`` and/or ``directory_permissions_mode`` parameters,
|
|
respectively. For example::
|
|
|
|
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(MyStaticFilesStorage, self).__init__(*args, **kwargs)
|
|
|
|
Then set the :setting:`STATICFILES_STORAGE` setting to
|
|
``'path.to.MyStaticFilesStorage'``.
|
|
|
|
.. highlight:: console
|
|
|
|
Some commonly used options are:
|
|
|
|
.. django-admin-option:: --noinput
|
|
|
|
Do NOT prompt the user for input of any kind.
|
|
|
|
.. django-admin-option:: -i <pattern>
|
|
.. django-admin-option:: --ignore <pattern>
|
|
|
|
Ignore files or directories matching this glob-style pattern. Use multiple
|
|
times to ignore more.
|
|
|
|
.. django-admin-option:: -n
|
|
.. django-admin-option:: --dry-run
|
|
|
|
Do everything except modify the filesystem.
|
|
|
|
.. django-admin-option:: -c
|
|
.. django-admin-option:: --clear
|
|
|
|
Clear the existing files before trying to copy or link the original file.
|
|
|
|
.. django-admin-option:: -l
|
|
.. django-admin-option:: --link
|
|
|
|
Create a symbolic link to each file instead of copying.
|
|
|
|
.. django-admin-option:: --no-post-process
|
|
|
|
Don't call the
|
|
:meth:`~django.contrib.staticfiles.storage.StaticFilesStorage.post_process`
|
|
method of the configured :setting:`STATICFILES_STORAGE` storage backend.
|
|
|
|
.. django-admin-option:: --no-default-ignore
|
|
|
|
Don't ignore the common private glob-style patterns ``'CVS'``, ``'.*'``
|
|
and ``'*~'``.
|
|
|
|
For a full list of options, refer to the commands own help by running::
|
|
|
|
$ python manage.py collectstatic --help
|
|
|
|
findstatic
|
|
----------
|
|
|
|
.. django-admin:: findstatic
|
|
|
|
Searches for one or more relative paths with the enabled finders.
|
|
|
|
For example::
|
|
|
|
$ 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
|
|
|
|
By default, all matching locations are found. To only return the first match
|
|
for each relative path, use the ``--first`` option::
|
|
|
|
$ python manage.py findstatic css/base.css --first
|
|
Found 'css/base.css' here:
|
|
/home/special.polls.com/core/static/css/base.css
|
|
|
|
This is a debugging aid; it'll show you exactly which static file will be
|
|
collected for a given path.
|
|
|
|
By setting the :djadminopt:`--verbosity` flag to 0, you can suppress the extra
|
|
output and just get the path names::
|
|
|
|
$ 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
|
|
|
|
On the other hand, by setting the :djadminopt:`--verbosity` flag to 2, you can
|
|
get all the directories which were searched::
|
|
|
|
$ 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
|
|
|
|
.. _staticfiles-runserver:
|
|
|
|
runserver
|
|
---------
|
|
|
|
.. django-admin:: runserver
|
|
|
|
Overrides the core :djadmin:`runserver` command if the ``staticfiles`` app
|
|
is :setting:`installed<INSTALLED_APPS>` and adds automatic serving of static
|
|
files and the following new options.
|
|
|
|
.. django-admin-option:: --nostatic
|
|
|
|
Use the ``--nostatic`` option to disable serving of static files with the
|
|
:doc:`staticfiles </ref/contrib/staticfiles>` app entirely. This option is
|
|
only available if the :doc:`staticfiles </ref/contrib/staticfiles>` app is
|
|
in your project's :setting:`INSTALLED_APPS` setting.
|
|
|
|
Example usage::
|
|
|
|
django-admin runserver --nostatic
|
|
|
|
.. django-admin-option:: --insecure
|
|
|
|
Use the ``--insecure`` option to force serving of static files with the
|
|
:doc:`staticfiles </ref/contrib/staticfiles>` app even if the :setting:`DEBUG`
|
|
setting is ``False``. By using this you acknowledge the fact that it's
|
|
**grossly inefficient** and probably **insecure**. This is only intended for
|
|
local development, should **never be used in production** and is only
|
|
available if the :doc:`staticfiles </ref/contrib/staticfiles>` app is
|
|
in your project's :setting:`INSTALLED_APPS` setting. :djadmin:`runserver`
|
|
``--insecure`` doesn't work with
|
|
:class:`~django.contrib.staticfiles.storage.CachedStaticFilesStorage`.
|
|
|
|
Example usage::
|
|
|
|
django-admin runserver --insecure
|
|
|
|
.. _staticfiles-storages:
|
|
|
|
Storages
|
|
========
|
|
|
|
StaticFilesStorage
|
|
------------------
|
|
|
|
.. class:: storage.StaticFilesStorage
|
|
|
|
A subclass of the :class:`~django.core.files.storage.FileSystemStorage`
|
|
storage backend that uses the :setting:`STATIC_ROOT` setting as the base
|
|
file system location and the :setting:`STATIC_URL` setting respectively
|
|
as the base URL.
|
|
|
|
.. method:: storage.StaticFilesStorage.post_process(paths, **options)
|
|
|
|
This method is called by the :djadmin:`collectstatic` management command
|
|
after each run and gets passed the local storages and paths of found
|
|
files as a dictionary, as well as the command line options.
|
|
|
|
The :class:`~django.contrib.staticfiles.storage.CachedStaticFilesStorage`
|
|
uses this behind the scenes to replace the paths with their hashed
|
|
counterparts and update the cache appropriately.
|
|
|
|
ManifestStaticFilesStorage
|
|
--------------------------
|
|
|
|
.. class:: storage.ManifestStaticFilesStorage
|
|
|
|
A subclass of the :class:`~django.contrib.staticfiles.storage.StaticFilesStorage`
|
|
storage backend which stores the file names it handles by appending the MD5
|
|
hash of the file's content to the filename. For example, the file
|
|
``css/styles.css`` would also be saved as ``css/styles.55e7cbb9ba48.css``.
|
|
|
|
The purpose of this storage is to keep serving the old files in case some
|
|
pages still refer to those files, e.g. because they are cached by you or
|
|
a 3rd party proxy server. Additionally, it's very helpful if you want to
|
|
apply `far future Expires headers`_ to the deployed files to speed up the
|
|
load time for subsequent page visits.
|
|
|
|
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 :meth:`~django.contrib.staticfiles.storage.StaticFilesStorage.post_process`
|
|
method). The regular expressions used to find those paths
|
|
(``django.contrib.staticfiles.storage.HashedFilesMixin.patterns``)
|
|
by default covers the `@import`_ rule and `url()`_ statement of `Cascading
|
|
Style Sheets`_. For example, the ``'css/styles.css'`` file with the
|
|
content
|
|
|
|
.. code-block:: css+django
|
|
|
|
@import url("../admin/css/base.css");
|
|
|
|
would be replaced by calling the :meth:`~django.core.files.storage.Storage.url`
|
|
method of the ``ManifestStaticFilesStorage`` storage backend, ultimately
|
|
saving a ``'css/styles.55e7cbb9ba48.css'`` file with the following
|
|
content:
|
|
|
|
.. code-block:: css+django
|
|
|
|
@import url("../admin/css/base.27e20196a850.css");
|
|
|
|
To enable the ``ManifestStaticFilesStorage`` you have to make sure the
|
|
following requirements are met:
|
|
|
|
* the :setting:`STATICFILES_STORAGE` setting is set to
|
|
``'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'``
|
|
* the :setting:`DEBUG` setting is set to ``False``
|
|
* you use the ``staticfiles`` :ttag:`static<staticfiles-static>` template
|
|
tag to refer to your static files in your templates
|
|
* you've collected all your static files by using the
|
|
:djadmin:`collectstatic` management command
|
|
|
|
Since creating the MD5 hash can be a performance burden to your website
|
|
during runtime, ``staticfiles`` will automatically store the mapping with
|
|
hashed names for all processed files in a file called ``staticfiles.json``.
|
|
This happens once when you run the :djadmin:`collectstatic` management
|
|
command.
|
|
|
|
Due to the requirement of running :djadmin:`collectstatic`, this storage
|
|
typically shouldn't be used when running tests as ``collectstatic`` isn't run
|
|
as part of the normal test setup. During testing, ensure that the
|
|
:setting:`STATICFILES_STORAGE` setting is set to something else like
|
|
``'django.contrib.staticfiles.storage.StaticFilesStorage'`` (the default).
|
|
|
|
.. method:: storage.ManifestStaticFilesStorage.file_hash(name, content=None)
|
|
|
|
The method that is used when creating the hashed name of a file.
|
|
Needs to return a hash for the given file name and content.
|
|
By default it calculates a MD5 hash from the content's chunks as
|
|
mentioned above. Feel free to override this method to use your own
|
|
hashing algorithm.
|
|
|
|
.. _`far future Expires headers`: https://developer.yahoo.com/performance/rules.html#expires
|
|
.. _`@import`: http://www.w3.org/TR/CSS2/cascade.html#at-import
|
|
.. _`url()`: http://www.w3.org/TR/CSS2/syndata.html#uri
|
|
.. _`Cascading Style Sheets`: http://www.w3.org/Style/CSS/
|
|
|
|
CachedStaticFilesStorage
|
|
------------------------
|
|
|
|
.. class:: storage.CachedStaticFilesStorage
|
|
|
|
``CachedStaticFilesStorage`` is a similar class like the
|
|
:class:`~django.contrib.staticfiles.storage.ManifestStaticFilesStorage` class
|
|
but uses Django's :doc:`caching framework</topics/cache>` for storing the
|
|
hashed names of processed files instead of a static manifest file called
|
|
``staticfiles.json``. This is mostly useful for situations in which you don't
|
|
have access to the file system.
|
|
|
|
If you want to override certain options of the cache backend the storage uses,
|
|
simply specify a custom entry in the :setting:`CACHES` setting named
|
|
``'staticfiles'``. It falls back to using the ``'default'`` cache backend.
|
|
|
|
.. currentmodule:: django.contrib.staticfiles.templatetags.staticfiles
|
|
|
|
Template tags
|
|
=============
|
|
|
|
static
|
|
------
|
|
|
|
.. templatetag:: staticfiles-static
|
|
|
|
Uses the configured :setting:`STATICFILES_STORAGE` storage to create the
|
|
full URL for the given relative path, e.g.:
|
|
|
|
.. code-block:: html+django
|
|
|
|
{% load static from staticfiles %}
|
|
<img src="{% static "images/hi.jpg" %}" alt="Hi!" />
|
|
|
|
The previous example is equal to calling the ``url`` method of an instance of
|
|
:setting:`STATICFILES_STORAGE` with ``"images/hi.jpg"``. This is especially
|
|
useful when using a non-local storage backend to deploy files as documented
|
|
in :ref:`staticfiles-from-cdn`.
|
|
|
|
If you'd like to retrieve a static URL without displaying it, you can use a
|
|
slightly different call:
|
|
|
|
.. code-block:: html+django
|
|
|
|
{% load static from staticfiles %}
|
|
{% static "images/hi.jpg" as myphoto %}
|
|
<img src="{{ myphoto }}" alt="Hi!" />
|
|
|
|
Finders Module
|
|
==============
|
|
|
|
``staticfiles`` finders has a ``searched_locations`` attribute which is a list
|
|
of directory paths in which the finders searched. Example usage::
|
|
|
|
from django.contrib.staticfiles import finders
|
|
|
|
result = finders.find('css/base.css')
|
|
searched_locations = finders.searched_locations
|
|
|
|
Other Helpers
|
|
=============
|
|
|
|
There are a few other helpers outside of the
|
|
:mod:`staticfiles <django.contrib.staticfiles>` app to work with static
|
|
files:
|
|
|
|
- The :func:`django.template.context_processors.static` context processor
|
|
which adds :setting:`STATIC_URL` to every template context rendered
|
|
with :class:`~django.template.RequestContext` contexts.
|
|
|
|
- The builtin template tag :ttag:`static` which takes a path and
|
|
urljoins it with the static prefix :setting:`STATIC_URL`.
|
|
|
|
- The builtin template tag :ttag:`get_static_prefix` which populates a
|
|
template variable with the static prefix :setting:`STATIC_URL` to be
|
|
used as a variable or directly.
|
|
|
|
- The similar template tag :ttag:`get_media_prefix` which works like
|
|
:ttag:`get_static_prefix` but uses :setting:`MEDIA_URL`.
|
|
|
|
.. _staticfiles-development-view:
|
|
|
|
Static file development view
|
|
----------------------------
|
|
|
|
.. currentmodule:: django.contrib.staticfiles
|
|
|
|
The static files tools are mostly designed to help with getting static files
|
|
successfully deployed into production. This usually means a separate,
|
|
dedicated static file server, which is a lot of overhead to mess with when
|
|
developing locally. Thus, the ``staticfiles`` app ships with a
|
|
**quick and dirty helper view** that you can use to serve files locally in
|
|
development.
|
|
|
|
.. highlight:: python
|
|
|
|
.. function:: views.serve(request, path)
|
|
|
|
This view function serves static files in development.
|
|
|
|
.. warning::
|
|
|
|
This view will only work if :setting:`DEBUG` is ``True``.
|
|
|
|
That's because this view is **grossly inefficient** and probably
|
|
**insecure**. This is only intended for local development, and should
|
|
**never be used in production**.
|
|
|
|
.. note::
|
|
|
|
To guess the served files' content types, this view relies on the
|
|
:py:mod:`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 need to be updated. This can be achieved, for
|
|
example, by installing or updating the ``mailcap`` package on a Red Hat
|
|
distribution, or ``mime-support`` on a Debian distribution.
|
|
|
|
This view is automatically enabled by :djadmin:`runserver` (with a
|
|
:setting:`DEBUG` setting set to ``True``). To use the view with a different
|
|
local development server, add the following snippet to the end of your
|
|
primary URL configuration::
|
|
|
|
from django.conf import settings
|
|
from django.contrib.staticfiles import views
|
|
|
|
if settings.DEBUG:
|
|
urlpatterns += [
|
|
url(r'^static/(?P<path>.*)$', views.serve),
|
|
]
|
|
|
|
Note, the beginning of the pattern (``r'^static/'``) should be your
|
|
:setting:`STATIC_URL` setting.
|
|
|
|
Since this is a bit finicky, there's also a helper function that'll do this for
|
|
you:
|
|
|
|
.. function:: urls.staticfiles_urlpatterns()
|
|
|
|
This will return the proper URL pattern for serving static files to your
|
|
already defined pattern list. Use it like this::
|
|
|
|
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
|
|
|
# ... the rest of your URLconf here ...
|
|
|
|
urlpatterns += staticfiles_urlpatterns()
|
|
|
|
This will inspect your :setting:`STATIC_URL` setting and wire up the view
|
|
to serve static files accordingly. Don't forget to set the
|
|
:setting:`STATICFILES_DIRS` setting appropriately to let
|
|
``django.contrib.staticfiles`` know where to look for files in addition to
|
|
files in app directories.
|
|
|
|
.. warning::
|
|
|
|
This helper function will only work if :setting:`DEBUG` is ``True``
|
|
and your :setting:`STATIC_URL` setting is neither empty nor a full
|
|
URL such as ``http://static.example.com/``.
|
|
|
|
That's because this view is **grossly inefficient** and probably
|
|
**insecure**. This is only intended for local development, and should
|
|
**never be used in production**.
|
|
|
|
Specialized test case to support 'live testing'
|
|
-----------------------------------------------
|
|
|
|
.. class:: testing.StaticLiveServerTestCase
|
|
|
|
This unittest TestCase subclass extends :class:`django.test.LiveServerTestCase`.
|
|
|
|
Just like its parent, you can use it to write tests that involve running the
|
|
code under test and consuming it with testing tools through HTTP (e.g. Selenium,
|
|
PhantomJS, etc.), because of which it's needed that the static assets are also
|
|
published.
|
|
|
|
But given the fact that it makes use of the
|
|
:func:`django.contrib.staticfiles.views.serve` view described above, it can
|
|
transparently overlay at test execution-time the assets provided by the
|
|
``staticfiles`` finders. This means you don't need to run
|
|
:djadmin:`collectstatic` before or as a part of your tests setup.
|