123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508 |
- =====================
- Managing static files
- =====================
- Django developers mostly concern themselves with the dynamic parts of web
- applications -- the views and templates that render anew for each request. But
- web applications have other parts: the static files (images, CSS,
- Javascript, etc.) that are needed to render a complete web page.
- For small projects, this isn't a big deal, because you can just keep the
- static files somewhere your web server can find it. However, in bigger
- projects -- especially those comprised of multiple apps -- dealing with the
- multiple sets of static files provided by each application starts to get
- tricky.
- That's what ``django.contrib.staticfiles`` is for: it 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.
- .. note::
- If you've used the `django-staticfiles`_ third-party app before, then
- ``django.contrib.staticfiles`` will look very familiar. That's because
- they're essentially the same code: ``django.contrib.staticfiles`` started
- its life as `django-staticfiles`_ and was merged into Django 1.3.
- If you're upgrading from ``django-staticfiles``, please see `Upgrading from
- django-staticfiles`_, below, for a few minor changes you'll need to make.
- .. _django-staticfiles: http://pypi.python.org/pypi/django-staticfiles/
- Using ``django.contrib.staticfiles``
- ====================================
- Basic usage
- -----------
- 1. Put your static files somewhere that ``staticfiles`` will find them.
- By default, this means within ``static/`` subdirectories of apps in your
- :setting:`INSTALLED_APPS`.
- Your project will probably also have static assets that aren't tied to a
- particular app. The :setting:`STATICFILES_DIRS` setting is a tuple of
- filesystem directories to check when loading static files. It's a search
- path that is by default empty. See the :setting:`STATICFILES_DIRS` docs
- how to extend this list of additional paths.
- Additionally, see the documentation for the :setting:`STATICFILES_FINDERS`
- setting for details on how ``staticfiles`` finds your files.
- 2. Make sure that ``django.contrib.staticfiles`` is included in your
- :setting:`INSTALLED_APPS`.
- For :ref:`local development<staticfiles-development>`, if you are using
- :ref:`runserver<staticfiles-runserver>` or adding
- :ref:`staticfiles_urlpatterns<staticfiles-development>` to your
- URLconf, you're done with the setup -- your static files will
- automatically be served at the default (for
- :djadmin:`newly created<startproject>` projects) :setting:`STATIC_URL`
- of ``/static/``.
- 3. You'll probably need to refer to these files in your templates. The
- easiest method is to use the included context processor which allows
- template code like:
- .. code-block:: html+django
- <img src="{{ STATIC_URL }}images/hi.jpg" alt="Hi!" />
- See :ref:`staticfiles-in-templates` for more details, **including** an
- alternate method using a template tag.
- Deploying static files in a nutshell
- ------------------------------------
- When you're ready to move out of local development and deploy your project:
- 1. Set the :setting:`STATIC_URL` setting to the public URL for your static
- files (in most cases, the default value of ``/static/`` is just fine).
- 2. Set the :setting:`STATIC_ROOT` setting to point to the filesystem path
- you'd like your static files collected to when you use the
- :djadmin:`collectstatic` management command. For example::
- STATIC_ROOT = "/home/jacob/projects/mysite.com/sitestatic"
- 3. Run the :djadmin:`collectstatic` management command::
- ./manage.py collectstatic
- This'll churn through your static file storage and copy them into the
- directory given by :setting:`STATIC_ROOT`.
- 4. Deploy those files by configuring your webserver of choice to serve the
- files in :setting:`STATIC_ROOT` at :setting:`STATIC_URL`.
- :ref:`staticfiles-production` covers some common deployment strategies
- for static files.
- Those are the **basics**. For more details on common configuration options,
- read on; for a detailed reference of the settings, commands, and other bits
- included with the framework see
- :doc:`the staticfiles reference </ref/contrib/staticfiles>`.
- .. note::
- In previous versions of Django, it was common to place static assets in
- :setting:`MEDIA_ROOT` along with user-uploaded files, and serve them both
- at :setting:`MEDIA_URL`. Part of the purpose of introducing the
- ``staticfiles`` app is to make it easier to keep static files separate
- from user-uploaded files.
- For this reason, you need to make your :setting:`MEDIA_ROOT` and
- :setting:`MEDIA_URL` different from your :setting:`STATIC_ROOT` and
- :setting:`STATIC_URL`. You will need to arrange for serving of files in
- :setting:`MEDIA_ROOT` yourself; ``staticfiles`` does not deal with
- user-uploaded files at all. You can, however, use
- :func:`django.views.static.serve` view for serving :setting:`MEDIA_ROOT`
- in development; see :ref:`staticfiles-other-directories`.
- .. _staticfiles-in-templates:
- Referring to static files in templates
- ======================================
- At some point, you'll probably need to link to static files in your templates.
- You could, of course, simply hardcode the path to you assets in the templates:
- .. code-block:: html
- <img src="http://static.example.com/static/myimage.jpg" alt="Sample image" />
- Of course, there are some serious problems with this: it doesn't work well in
- development, and it makes it *very* hard to change where you've deployed your
- static files. If, for example, you wanted to switch to using a content
- delivery network (CDN), then you'd need to change more or less every single
- template.
- A far better way is to use the value of the :setting:`STATIC_URL` setting
- directly in your templates. This means that a switch of static files servers
- only requires changing that single value. Much better!
- Django includes multiple built-in ways of using this setting in your
- templates: a context processor and a template tag.
- With a context processor
- ------------------------
- The included context processor is the easy way. Simply make sure
- ``'django.core.context_processors.static'`` is in your
- :setting:`TEMPLATE_CONTEXT_PROCESSORS`. It's there by default, and if you're
- editing that setting by hand it should look something like::
- TEMPLATE_CONTEXT_PROCESSORS = (
- 'django.core.context_processors.debug',
- 'django.core.context_processors.i18n',
- 'django.core.context_processors.media',
- 'django.core.context_processors.static',
- 'django.contrib.auth.context_processors.auth',
- 'django.contrib.messages.context_processors.messages',
- )
- Once that's done, you can refer to :setting:`STATIC_URL` in your templates:
- .. code-block:: html+django
- <img src="{{ STATIC_URL }}images/hi.jpg" alt="Hi!" />
- If ``{{ STATIC_URL }}`` isn't working in your template, you're probably not
- using :class:`~django.template.RequestContext` when rendering the template.
- As a brief refresher, context processors add variables into the contexts of
- every template. However, context processors require that you use
- :class:`~django.template.RequestContext` when rendering templates. This happens
- automatically if you're using a :doc:`generic view </ref/class-based-views/index>`,
- but in views written by hand you'll need to explicitly use ``RequestContext``
- To see how that works, and to read more details, check out
- :ref:`subclassing-context-requestcontext`.
- Another option is the :ttag:`get_static_prefix` template tag that is part of
- Django's core.
- With a template tag
- -------------------
- The more powerful tool is the :ttag:`static<staticfiles-static>` template
- tag. It builds the URL for the given relative path by using the configured
- :setting:`STATICFILES_STORAGE` storage.
- .. code-block:: html+django
- {% load staticfiles %}
- <img src="{% static "images/hi.jpg" %}" alt="Hi!"/>
- It is also able to consume standard context variables, e.g. assuming a
- ``user_stylesheet`` variable is passed to the template:
- .. code-block:: html+django
- {% load staticfiles %}
- <link rel="stylesheet" href="{% static user_stylesheet %}" type="text/css" media="screen" />
- .. note::
- There is also a template tag named :ttag:`static` in Django's core set
- of :ref:`built in template tags<ref-templates-builtins-tags>` which has
- the same argument signature but only uses `urlparse.urljoin()`_ with the
- :setting:`STATIC_URL` setting and the given path. This has the
- disadvantage of not being able to easily switch the storage backend
- without changing the templates, so in doubt use the ``staticfiles``
- :ttag:`static<staticfiles-static>`
- template tag.
- .. _`urlparse.urljoin()`: http://docs.python.org/library/urlparse.html#urlparse.urljoin
- .. _staticfiles-development:
- Serving static files in development
- ===================================
- 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.
- This view is automatically enabled and will serve your static files at
- :setting:`STATIC_URL` when you use the built-in
- :ref:`runserver<staticfiles-runserver>` management command.
- To enable this view if you are using some other server for local development,
- you'll add a couple of lines to your URLconf. The first line goes at the top
- of the file, and the last line at the bottom::
- from django.contrib.staticfiles.urls import staticfiles_urlpatterns
- # ... the rest of your URLconf goes 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 additionally to
- files in app directories.
- .. warning::
- This 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**.
- Additionally, when using ``staticfiles_urlpatterns`` your
- :setting:`STATIC_URL` setting can't be empty or a full URL, such as
- ``http://static.example.com/``.
- For a few more details on how the ``staticfiles`` can be used during
- development, see :ref:`staticfiles-development-view`.
- .. _staticfiles-other-directories:
- Serving other directories
- -------------------------
- .. currentmodule:: django.views.static
- .. function:: serve(request, path, document_root, show_indexes=False)
- There may be files other than your project's static assets that, for
- convenience, you'd like to have Django serve for you in local development.
- The :func:`~django.views.static.serve` view can be used to serve any directory
- you give it. (Again, this view is **not** hardened for production
- use, and should be used only as a development aid; you should serve these files
- in production using a real front-end webserver).
- The most likely example is user-uploaded content in :setting:`MEDIA_ROOT`.
- ``staticfiles`` is intended for static assets and has no built-in handling
- for user-uploaded files, but you can have Django serve your
- :setting:`MEDIA_ROOT` by appending something like this to your URLconf::
- from django.conf import settings
- # ... the rest of your URLconf goes here ...
- if settings.DEBUG:
- urlpatterns += patterns('',
- url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
- 'document_root': settings.MEDIA_ROOT,
- }),
- )
- Note, the snippet assumes your :setting:`MEDIA_URL` has a value of
- ``'/media/'``. This will call the :func:`~django.views.static.serve` view,
- passing in the path from the URLconf and the (required) ``document_root``
- parameter.
- .. currentmodule:: django.conf.urls.static
- .. function:: static(prefix, view='django.views.static.serve', **kwargs)
- Since it can become a bit cumbersome to define this URL pattern, Django
- ships with a small URL helper function
- :func:`~django.conf.urls.static.static` that takes as parameters the prefix
- such as :setting:`MEDIA_URL` and a dotted path to a view, such as
- ``'django.views.static.serve'``. Any other function parameter will be
- transparently passed to the view.
- An example for serving :setting:`MEDIA_URL` (``'/media/'``) during
- development::
- from django.conf import settings
- from django.conf.urls.static import static
- urlpatterns = patterns('',
- # ... the rest of your URLconf goes here ...
- ) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
- .. note::
- This helper function will only be operational in debug mode and if
- the given prefix is local (e.g. ``/static/``) and not a URL (e.g.
- ``http://static.example.com/``).
- .. _staticfiles-production:
- Serving static files in production
- ==================================
- The basic outline of putting static files into production is simple: run the
- :djadmin:`collectstatic` command when static files change, then arrange for
- the collected static files directory (:setting:`STATIC_ROOT`) to be moved to
- the static file server and served.
- Of course, as with all deployment tasks, the devil's in the details. Every
- production setup will be a bit different, so you'll need to adapt the basic
- outline to fit your needs. Below are a few common patterns that might help.
- Serving the app and your static files from the same server
- ----------------------------------------------------------
- If you want to serve your static files from the same server that's already
- serving your site, the basic outline gets modified to look something like:
- * Push your code up to the deployment server.
- * On the server, run :djadmin:`collectstatic` to copy all the static files
- into :setting:`STATIC_ROOT`.
- * Point your web server at :setting:`STATIC_ROOT`. For example, here's
- :ref:`how to do this under Apache and mod_wsgi <serving-files>`.
- You'll probably want to automate this process, especially if you've got
- multiple web servers. There's any number of ways to do this automation, but
- one option that many Django developers enjoy is `Fabric`__.
- __ http://fabfile.org/
- Below, and in the following sections, we'll show off a few example fabfiles
- (i.e. Fabric scripts) that automate these file deployment options. The syntax
- of a fabfile is fairly straightforward but won't be covered here; consult
- `Fabric's documentation`__, for a complete explanation of the syntax..
- __ http://docs.fabfile.org/
- So, a fabfile to deploy static files to a couple of web servers might look
- something like::
- from fabric.api import *
- # Hosts to deploy onto
- env.hosts = ['www1.example.com', 'www2.example.com']
- # Where your project code lives on the server
- env.project_root = '/home/www/myproject'
- def deploy_static():
- with cd(env.project_root):
- run('./manage.py collectstatic -v0 --noinput')
- Serving static files from a dedicated server
- --------------------------------------------
- Most larger Django apps use a separate Web server -- i.e., one that's not also
- running Django -- for serving static files. This server often runs a different
- type of web server -- faster but less full-featured. Some good choices are:
- * lighttpd_
- * Nginx_
- * TUX_
- * Cherokee_
- * A stripped-down version of Apache_
- .. _lighttpd: http://www.lighttpd.net/
- .. _Nginx: http://wiki.nginx.org/Main
- .. _TUX: http://en.wikipedia.org/wiki/TUX_web_server
- .. _Apache: http://httpd.apache.org/
- .. _Cherokee: http://www.cherokee-project.com/
- Configuring these servers is out of scope of this document; check each
- server's respective documentation for instructions.
- Since your static file server won't be running Django, you'll need to modify
- the deployment strategy to look something like:
- * When your static files change, run :djadmin:`collectstatic` locally.
- * Push your local :setting:`STATIC_ROOT` up to the static file server
- into the directory that's being served. ``rsync`` is a good
- choice for this step since it only needs to transfer the
- bits of static files that have changed.
- Here's how this might look in a fabfile::
- from fabric.api import *
- from fabric.contrib import project
- # Where the static files get collected locally
- env.local_static_root = '/tmp/static'
- # Where the static files should go remotely
- env.remote_static_root = '/home/www/static.example.com'
- @roles('static')
- def deploy_static():
- local('./manage.py collectstatic')
- project.rsync_project(
- remote_dir = env.remote_static_root,
- local_dir = env.local_static_root,
- delete = True
- )
- .. _staticfiles-from-cdn:
- Serving static files from a cloud service or CDN
- ------------------------------------------------
- Another common tactic is to serve static files from a cloud storage provider
- like Amazon's S3__ and/or a CDN (content delivery network). This lets you
- ignore the problems of serving static files, and can often make for
- faster-loading webpages (especially when using a CDN).
- When using these services, the basic workflow would look a bit like the above,
- except that instead of using ``rsync`` to transfer your static files to the
- server you'd need to transfer the static files to the storage provider or CDN.
- There's any number of ways you might do this, but if the provider has an API a
- :doc:`custom file storage backend </howto/custom-file-storage>` will make the
- process incredibly simple. If you've written or are using a 3rd party custom
- storage backend, you can tell :djadmin:`collectstatic` to use it by setting
- :setting:`STATICFILES_STORAGE` to the storage engine.
- For example, if you've written an S3 storage backend in
- ``myproject.storage.S3Storage`` you could use it with::
- STATICFILES_STORAGE = 'myproject.storage.S3Storage'
- Once that's done, all you have to do is run :djadmin:`collectstatic` and your
- static files would be pushed through your storage package up to S3. If you
- later needed to switch to a different storage provider, it could be as simple
- as changing your :setting:`STATICFILES_STORAGE` setting.
- For details on how you'd write one of these backends,
- :doc:`/howto/custom-file-storage`.
- .. seealso::
- The `django-storages`__ project is a 3rd party app that provides many
- storage backends for many common file storage APIs (including `S3`__).
- __ http://s3.amazonaws.com/
- __ http://code.larlet.fr/django-storages/
- __ http://django-storages.readthedocs.org/en/latest/backends/amazon-S3.html
- Upgrading from ``django-staticfiles``
- =====================================
- ``django.contrib.staticfiles`` began its life as `django-staticfiles`_. If
- you're upgrading from `django-staticfiles`_ older than 1.0 (e.g. 0.3.4) to
- ``django.contrib.staticfiles``, you'll need to make a few changes:
- * Application files should now live in a ``static`` directory in each app
- (`django-staticfiles`_ used the name ``media``, which was slightly
- confusing).
- * The management commands ``build_static`` and ``resolve_static`` are now
- called :djadmin:`collectstatic` and :djadmin:`findstatic`.
- * The settings ``STATICFILES_PREPEND_LABEL_APPS``,
- ``STATICFILES_MEDIA_DIRNAMES`` and ``STATICFILES_EXCLUDED_APPS`` were
- removed.
- * The setting ``STATICFILES_RESOLVERS`` was removed, and replaced by the
- new :setting:`STATICFILES_FINDERS`.
- * The default for :setting:`STATICFILES_STORAGE` was renamed from
- ``staticfiles.storage.StaticFileStorage`` to
- ``staticfiles.storage.StaticFilesStorage``
- * If using :ref:`runserver<staticfiles-runserver>` for local development
- (and the :setting:`DEBUG` setting is ``True``), you no longer need to add
- anything to your URLconf for serving static files in development.
- Learn more
- ==========
- This document has covered the basics and some common usage patterns. For
- complete details on all the settings, commands, template tags, and other pieces
- include in ``django.contrib.staticfiles``, see :doc:`the staticfiles reference
- </ref/contrib/staticfiles>`.
|