Browse Source

Fixed #19897 - Updated static files howto.

Thanks Jan Murre, Reinout van Rees and Wim Feijen,
plus Remco Wendt for reviewing.
Tim Graham 12 years ago
parent
commit
6c730da1f6

+ 1 - 1
docs/howto/deployment/checklist.txt

@@ -113,7 +113,7 @@ Static files are automatically served by the development server. In
 production, you must define a :setting:`STATIC_ROOT` directory where
 :djadmin:`collectstatic` will copy them.
 
-See :doc:`/howto/static-files` for more information.
+See :doc:`/howto/static-files/index` for more information.
 
 :setting:`MEDIA_ROOT` and :setting:`MEDIA_URL`
 ----------------------------------------------

+ 2 - 1
docs/howto/index.txt

@@ -21,7 +21,8 @@ you quickly accomplish common tasks.
    legacy-databases
    outputting-csv
    outputting-pdf
-   static-files
+   static-files/index
+   static-files/deployment
 
 .. seealso::
 

+ 159 - 0
docs/howto/static-files/deployment.txt

@@ -0,0 +1,159 @@
+======================
+Deploying static files
+======================
+
+.. seealso::
+
+    For an introduction to the use of :mod:`django.contrib.staticfiles`, see
+    :doc:`/howto/static-files/index`.
+
+.. _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. Depending on :setting:`STATICFILES_STORAGE`,
+files may need to be moved to a new location manually or the :func:`post_process
+<django.contrib.staticfiles.storage.StaticFilesStorage.post_process>` method
+of the ``Storage`` class might take care of that.
+
+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 site 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 process may 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`.
+* Configure your web server to serve the files in :setting:`STATIC_ROOT`
+  under the URL :setting:`STATIC_URL`. For example, here's
+  :ref:`how to do this with 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 <http://docs.fabfile.org/>`_, for a complete
+explanation of the syntax.
+
+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 sites 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 common 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 <https://rsync.samba.org/>`_ is a
+  common 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. Your STATIC_ROOT setting.
+    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, see
+:doc:`/howto/custom-file-storage`. There are 3rd party apps available that
+provide storage backends for many common file storage APIs. A good starting
+point is the `overview at djangopackages.com
+<https://www.djangopackages.com/grids/g/storage-backends/>`_.
+
+Learn more
+==========
+
+For complete details on all the settings, commands, template tags, and other
+pieces included in :mod:`django.contrib.staticfiles`, see :doc:`the
+staticfiles reference </ref/contrib/staticfiles>`.

+ 69 - 458
docs/howto/static-files/index.txt

@@ -1,314 +1,79 @@
-=====================
-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/
+===================================
+Managing static files (CSS, images)
+===================================
 
-Using ``django.contrib.staticfiles``
-====================================
+Websites generally need to serve additional files such as images, JavaScript,
+or CSS. In Django, we refer to these files as "static files".  Django provides
+:mod:`django.contrib.staticfiles` to help you manage them.
 
-Basic usage
------------
+This page describes how you can serve these static files.
 
-1. Put your static files somewhere that ``staticfiles`` will find them.
+Configuring static files
+========================
 
-   By default, this means within ``static/`` subdirectories of apps in your
+1. Make sure that ``django.contrib.staticfiles`` is included 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.
+2. In your settings file, define :setting:`STATIC_URL`, for example::
 
-   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`.
+      STATIC_URL = '/static/'
 
-   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. In your templates, either hardcode the url like
+   ``/static/my_app/myexample.jpg`` or, preferably, use the
+   :ttag:`static<staticfiles-static>` template tag to build the URL for the given
+   relative path by using the configured :setting:`STATICFILES_STORAGE` storage
+   (this makes it much easier when you want to switch to a content delivery
+   network (CDN) for serving static files).
 
-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:
+   .. _staticfiles-in-templates:
 
    .. 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`.
+        {% load staticfiles %}
+        <img src="{% static "my_app/myexample.jpg" %}" alt="My image"/>
 
-.. _staticfiles-in-templates:
+3. Store your static files in a folder called ``static`` in your app. For
+   example ``my_app/static/my_app/myimage.jpg``.
 
-Referring to static files in templates
-======================================
+Now, if you use ``./manage.py runserver``, all static files should be served
+automatically at the :setting:`STATIC_URL` and be shown correctly.
 
-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:
+Your project will probably also have static assets that aren't tied to a
+particular app. In addition to using a ``static/`` directory inside your apps,
+you can define a list of directories (:setting:`STATICFILES_DIRS`) in your
+settings file where Django will also look for static files. For example::
 
-.. 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',
+    STATICFILES_DIRS = (
+        os.path.join(BASE_DIR, "static"),
+        '/var/www/static/',
     )
 
-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::
+See the documentation for the :setting:`STATICFILES_FINDERS` setting for
+details on how ``staticfiles`` finds your files.
 
-    from django.contrib.staticfiles.urls import staticfiles_urlpatterns
+.. admonition:: Static file namespacing
 
-    # ... the rest of your URLconf goes here ...
+    Now we *might* be able to get away with putting our static files directly
+    in ``my_app/static/`` (rather than creating another ``my_app``
+    subdirectory), but it would actually be a bad idea. Django will use the
+    last static file it finds whose name matches, and if you had a static file
+    with the same name in a *different* application, Django would be unable to
+    distinguish between them. We need to be able to point Django at the right
+    one, and the easiest way to ensure this is by *namespacing* them. That is,
+    by putting those static files inside *another* directory named for the
+    application itself.
 
-    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.
+Serving files uploaded by a user
+================================
 
-.. warning::
+During development, you can serve user-uploaded media files from
+:setting:`MEDIA_ROOT` using the :func:`django.contrib.staticfiles.views.serve`
+view. This is not suitable for production use! For some common deployment
+strategies, see :doc:`/howto/static-files/deployment`.
 
-    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::
+For example, if your :setting:`MEDIA_URL` is defined as '/media/', you can do
+this by adding the following snippet to your urls.py::
 
     from django.conf import settings
     from django.conf.urls.static import static
@@ -319,190 +84,36 @@ development::
 
 .. note::
 
-    This helper function will only be operational in debug mode and if
+    This helper function works only in debug mode and only 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``
-=====================================
+Deployment
+==========
 
-``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:
+:mod:`django.contrib.staticfiles` provides a convenience management command
+for gathering static files in a single directory so you can serve them easily.
 
-* Application files should now live in a ``static`` directory in each app
-  (`django-staticfiles`_ used the name ``media``, which was slightly
-  confusing).
+1. Set the :setting:`STATIC_ROOT` setting to the directory from which you'd
+   like to serve these files, for example::
 
-* The management commands ``build_static`` and ``resolve_static`` are now
-  called :djadmin:`collectstatic` and :djadmin:`findstatic`.
+       STATIC_ROOT = "/var/www/example.com/static/"
 
-* The settings ``STATICFILES_PREPEND_LABEL_APPS``,
-  ``STATICFILES_MEDIA_DIRNAMES`` and ``STATICFILES_EXCLUDED_APPS`` were
-  removed.
+2. Run the :djadmin:`collectstatic` management command::
 
-* The setting ``STATICFILES_RESOLVERS`` was removed, and replaced by the
-  new :setting:`STATICFILES_FINDERS`.
+       ./manage.py collectstatic
 
-* The default for :setting:`STATICFILES_STORAGE` was renamed from
-  ``staticfiles.storage.StaticFileStorage`` to
-  ``staticfiles.storage.StaticFilesStorage``
+   This will copy all files from your static folders into the
+   :setting:`STATIC_ROOT` directory.
 
-* 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.
+3. Use a webserver of your choice to serve the
+   files. :doc:`/howto/static-files/deployment` covers some common deployment
+   strategies for static files.
 
 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>`.
+included in :mod:`django.contrib.staticfiles`, see :doc:`the staticfiles
+reference </ref/contrib/staticfiles>`.

+ 2 - 1
docs/index.txt

@@ -99,6 +99,7 @@ to know about views via the links below:
   :doc:`Decorators <topics/http/decorators>`
 
 * **Reference:**
+  :doc:`Built-in Views <ref/views>` |
   :doc:`Request/response objects <ref/request-response>` |
   :doc:`TemplateResponse objects <ref/template-response>`
 
@@ -191,7 +192,7 @@ testing of Django applications:
   :doc:`Overview <howto/deployment/index>` |
   :doc:`WSGI servers <howto/deployment/wsgi/index>` |
   :doc:`FastCGI/SCGI/AJP <howto/deployment/fastcgi>` |
-  :doc:`Handling static files <howto/static-files>` |
+  :doc:`Deploying static files <howto/static-files/deployment>` |
   :doc:`Tracking code errors by email <howto/error-reporting>`
 
 The admin

+ 1 - 1
docs/intro/overview.txt

@@ -272,7 +272,7 @@ following blocks." In short, that lets you dramatically cut down on redundancy
 in templates: each template has to define only what's unique to that template.
 
 Here's what the "base.html" template, including the use of :doc:`static files
-</howto/static-files>`, might look like:
+</howto/static-files/index>`, might look like:
 
 .. code-block:: html+django
 

+ 1 - 1
docs/intro/tutorial06.txt

@@ -108,7 +108,7 @@ loaded in the bottom right of the screen.
 
 These are the **basics**. For more details on settings and other bits included
 with the framework see
-:doc:`the static files howto </howto/static-files>` and the
+:doc:`the static files howto </howto/static-files/index>` and the
 :doc:`the staticfiles reference </ref/contrib/staticfiles>`. :doc:`Deploying
 static files </howto/static-files/deployment>` discusses how to use static
 files on a real server.

+ 25 - 4
docs/ref/contrib/staticfiles.txt

@@ -12,7 +12,8 @@ can easily be served in production.
 .. seealso::
 
     For an introduction to the static files app and some usage examples, see
-    :doc:`/howto/static-files`.
+    :doc:`/howto/static-files/index`. For guidelines on deploying static files,
+    see :doc:`/howto/static-files/deployment`.
 
 .. _staticfiles-settings:
 
@@ -326,9 +327,18 @@ files:
 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:: django.contrib.staticfiles.views.serve(request, path)
+.. function:: views.serve(request, path)
 
 This view function serves static files in development.
 
@@ -355,9 +365,10 @@ primary URL configuration::
 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:
+Since this is a bit finicky, there's also a helper function that'll do this for
+you:
 
-.. function:: django.contrib.staticfiles.urls.staticfiles_urlpatterns()
+.. 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::
@@ -368,8 +379,18 @@ already defined pattern list. Use it like this::
 
    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**.

+ 4 - 3
docs/ref/django-admin.txt

@@ -761,7 +761,8 @@ Serving static files with the development server
 
 By default, the development server doesn't serve any static files for your site
 (such as CSS files, images, things under :setting:`MEDIA_URL` and so forth). If
-you want to configure Django to serve static media, read :doc:`/howto/static-files`.
+you want to configure Django to serve static media, read
+:doc:`/howto/static-files/index`.
 
 shell
 -----
@@ -1289,7 +1290,7 @@ collectstatic
 ~~~~~~~~~~~~~
 
 This command is only available if the :doc:`static files application
-</howto/static-files>` (``django.contrib.staticfiles``) is installed.
+</howto/static-files/index>` (``django.contrib.staticfiles``) is installed.
 
 Please refer to its :djadmin:`description <collectstatic>` in the
 :doc:`staticfiles </ref/contrib/staticfiles>` documentation.
@@ -1298,7 +1299,7 @@ findstatic
 ~~~~~~~~~~
 
 This command is only available if the :doc:`static files application
-</howto/static-files>` (``django.contrib.staticfiles``) is installed.
+</howto/static-files/index>` (``django.contrib.staticfiles``) is installed.
 
 Please refer to its :djadmin:`description <findstatic>` in the :doc:`staticfiles
 </ref/contrib/staticfiles>` documentation.

+ 1 - 0
docs/ref/index.txt

@@ -25,3 +25,4 @@ API Reference
    urls
    utils
    validators
+   views

+ 1 - 1
docs/ref/settings.txt

@@ -2437,7 +2437,7 @@ Example: ``"/var/www/example.com/static/"``
 If the :doc:`staticfiles</ref/contrib/staticfiles>` contrib app is enabled
 (default) the :djadmin:`collectstatic` management command will collect static
 files into this directory. See the howto on :doc:`managing static
-files</howto/static-files>` for more details about usage.
+files</howto/static-files/index>` for more details about usage.
 
 .. warning::
 

+ 4 - 2
docs/ref/templates/builtins.txt

@@ -2418,8 +2418,10 @@ slightly different call::
     The :mod:`staticfiles<django.contrib.staticfiles>` contrib app also ships
     with a :ttag:`static template tag<staticfiles-static>` which uses
     ``staticfiles'`` :setting:`STATICFILES_STORAGE` to build the URL of the
-    given path. Use that instead if you have an advanced use case such as
-    :ref:`using a cloud service to serve static files<staticfiles-from-cdn>`::
+    given path (rather than simply using :func:`urlparse.urljoin` with the
+    :setting:`STATIC_URL` setting and the given path). Use that instead if you
+    have an advanced use case such as :ref:`using a cloud service to serve
+    static files<staticfiles-from-cdn>`::
 
         {% load static from staticfiles %}
         <img src="{% static "images/hi.jpg" %}" alt="Hi!" />

+ 14 - 0
docs/ref/urls.txt

@@ -44,6 +44,20 @@ The ``optional_dictionary`` and ``optional_name`` parameters are described in
     patterns you can construct. The only limit is that you can only create 254
     at a time (the 255th argument is the initial prefix argument).
 
+static()
+--------
+
+.. function:: static.static(prefix, view='django.views.static.serve', **kwargs)
+
+Helper function to return a URL pattern for serving files in debug mode::
+
+    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)
+
 url()
 -----
 

+ 48 - 0
docs/ref/views.txt

@@ -0,0 +1,48 @@
+==============
+Built-in Views
+==============
+
+.. module:: django.views
+   :synopsis: Django's built-in views.
+
+Several of Django's built-in views are documented in
+:doc:`/topics/http/views` as well as elsewhere in the documentation.
+
+Serving files in development
+----------------------------
+
+.. function:: static.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. (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`.
+``django.contrib.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.
+
+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.

+ 1 - 1
docs/releases/1.3-alpha-1.txt

@@ -72,7 +72,7 @@ at :setting:`STATIC_URL`.
 
 See the :doc:`reference documentation of the app </ref/contrib/staticfiles>`
 for more details or learn how to :doc:`manage static files
-</howto/static-files>`.
+</howto/static-files/index>`.
 
 ``unittest2`` support
 ~~~~~~~~~~~~~~~~~~~~~

+ 1 - 1
docs/releases/1.3-beta-1.txt

@@ -37,7 +37,7 @@ Based on feedback from the community this release adds two new options to the
 
 See the :doc:`staticfiles reference documentation </ref/contrib/staticfiles>`
 for more details, or learn :doc:`how to manage static files
-</howto/static-files>`.
+</howto/static-files/index>`.
 
 Translation comments
 ~~~~~~~~~~~~~~~~~~~~

+ 1 - 1
docs/releases/1.3.txt

@@ -115,7 +115,7 @@ at :setting:`STATIC_URL`.
 
 See the :doc:`reference documentation of the app </ref/contrib/staticfiles>`
 for more details or learn how to :doc:`manage static files
-</howto/static-files>`.
+</howto/static-files/index>`.
 
 unittest2 support
 ~~~~~~~~~~~~~~~~~

+ 1 - 1
docs/releases/1.4-alpha-1.txt

@@ -578,7 +578,7 @@ If you've previously used a URL path for ``ADMIN_MEDIA_PREFIX`` (e.g.
 ``/media/``) simply make sure :setting:`STATIC_URL` and :setting:`STATIC_ROOT`
 are configured and your web server serves the files correctly. The development
 server continues to serve the admin files just like before. Don't hesitate to
-consult the :doc:`static files howto </howto/static-files>` for further
+consult the :doc:`static files howto </howto/static-files/index>` for further
 details.
 
 In case your ``ADMIN_MEDIA_PREFIX`` is set to an specific domain (e.g.

+ 1 - 1
docs/releases/1.4-beta-1.txt

@@ -646,7 +646,7 @@ If you've previously used a URL path for ``ADMIN_MEDIA_PREFIX`` (e.g.
 ``/media/``) simply make sure :setting:`STATIC_URL` and :setting:`STATIC_ROOT`
 are configured and your web server serves the files correctly. The development
 server continues to serve the admin files just like before. Don't hesitate to
-consult the :doc:`static files howto </howto/static-files>` for further
+consult the :doc:`static files howto </howto/static-files/index>` for further
 details.
 
 In case your ``ADMIN_MEDIA_PREFIX`` is set to an specific domain (e.g.

+ 1 - 1
docs/releases/1.4.txt

@@ -708,7 +708,7 @@ If you've previously used a URL path for ``ADMIN_MEDIA_PREFIX`` (e.g.
 ``/media/``) simply make sure :setting:`STATIC_URL` and :setting:`STATIC_ROOT`
 are configured and your Web server serves those files correctly. The
 development server continues to serve the admin files just like before. Read
-the :doc:`static files howto </howto/static-files>` for more details.
+the :doc:`static files howto </howto/static-files/index>` for more details.
 
 If your ``ADMIN_MEDIA_PREFIX`` is set to an specific domain (e.g.
 ``http://media.example.com/admin/``), make sure to also set your

+ 1 - 1
docs/topics/files.txt

@@ -5,7 +5,7 @@ Managing files
 This document describes Django's file access APIs for files such as those
 uploaded by a user. The lower level APIs are general enough that you could use
 them for other purposes. If you want to handle "static files" (JS, CSS, etc),
-see :doc:`/howto/static-files`.
+see :doc:`/howto/static-files/index`.
 
 By default, Django stores files locally, using the :setting:`MEDIA_ROOT` and
 :setting:`MEDIA_URL` settings. The examples below assume that you're using these

+ 1 - 1
docs/topics/testing/overview.txt

@@ -1102,7 +1102,7 @@ out the `full reference`_ for more details.
 .. note::
 
     ``LiveServerTestCase`` makes use of the :doc:`staticfiles contrib app
-    </howto/static-files>` so you'll need to have your project configured
+    </howto/static-files/index>` so you'll need to have your project configured
     accordingly (in particular by setting :setting:`STATIC_URL`).
 
 .. note::