Ticket #14514: static-files.patch

File static-files.patch, 15.7 KB (added by Andy McKay, 14 years ago)
Line 
1=====================
2Managing static files
3=====================
4
5.. currentmodule:: django.contrib.staticfiles
6
7.. versionadded:: 1.3
8
9Django developers mostly concern themselves with the dynamic parts of web
10applications -- the views and templates that render anew for each request. But
11web applications have other parts: the static media files (images, CSS,
12Javascript, etc.) that are needed to render a complete web page.
13
14For small projects, this isn't a big deal, because you can just keep the media
15somewhere your web server can find it. However, in bigger projects -- especially
16those comprised of multiple apps -- dealing with the multiple sets of static
17files provided by each application starts to get tricky.
18
19That's what ``django.contrib.staticfiles`` is for: it collects media from each
20of your applications (and any other places you specify) into a single location
21that can easily be served in production.
22
23.. note::
24
25 If you've used the `django-staticfiles`_ third-party app before, then
26 ``django.contrib.staticfiles`` will look very familiar. That's because
27 they're essentially the same code: ``django.contrib.staticfiles`` started
28 its life as `django-staticfiles`_ and was merged into Django 1.3.
29
30 If you're upgrading from ``django-staticfiles``, please see `Upgrading from
31 django-staticfiles`_, below, for a few minor changes you'll need to make.
32
33.. _django-staticfiles: http://pypi.python.org/pypi/django-staticfiles/
34
35Using ``django.contrib.staticfiles``
36====================================
37
38Here's the basic usage in a nutshell:
39
40 1. Put your media somewhere that staticfiles will find it..
41
42 Most of the time this place will be in a ``static`` directory within your
43 application, but it could also be a specific directory you've put into
44 your settings file. See the the documentation for the
45 :setting:`STATICFILES_DIRS` and :setting:`STATICFILES_FINDERS` settings
46 for details on where you can put media.
47
48 2. Add some ``staticfiles``-related settings to your settings file.
49
50 First, you'll need to make sure that ``django.contrib.staticfiles`` is in
51 your :setting:`INSTALLED_APPS`.
52
53 Next, you'll need to edit :setting:`STATICFILES_ROOT` to point to where
54 you'd like your static media stored. For example::
55
56 STATICFILES_ROOT = "/home/jacob/projects/mysite.com/static_media"
57
58 You may also want to set the :setting:`STATICFILES_URL` setting at this
59 time, though the default value (of ``/static/``) is perfect for local
60 development.
61
62 There are a number of other options available that let you control *how*
63 media is stored, where ``staticfiles`` searches for files, and how files
64 will be served; see :ref:`the staticfiles settings reference
65 <staticfiles-settings>` for details.
66
67 3. Run the :djadmin:`collectstatic` management command::
68
69 ./manage.py collectstatic
70
71 This'll churn through your static file storage and move them into the
72 directory given by :setting:`STATICFILES_ROOT`.
73
74 4. Deploy that media.
75
76 If you're using the built-in development server, you can quickly
77 serve static media locally by adding::
78
79 from django.contrib.staticfiles.urls import staticfiles_urlpatterns
80 urlpatterns += staticfiles_urlpatterns()
81
82 to the bottom of your URLconf. See :ref:`staticfiles-development` for
83 details.
84
85 When it comes time to deploy to production, :ref:`staticfiles-production`
86 covers some common deployment strategies for static files.
87
88 However you choose to deploy those files, you'll probably need to refer
89 to them in your templates. The easiest method is to use the included
90 context processor which will allow template code like:
91
92 .. code-block:: html+django
93
94 <img src="{{ STATICFILES_URL }}images/hi.jpg />
95
96 See :ref:`staticfiles-in-templates` for more details, including an
97 alternate method (using a template tag).
98
99Those are the basics. For more details on common configuration options, read on;
100for a detailed reference of the settings, commands, and other bits included with
101the framework see :doc:`the staticfiles reference </ref/contrib/staticfiles>`.
102
103.. _staticfiles-in-templates:
104
105Referring to static files in templates
106======================================
107
108At some point, you'll probably need to link to static files in your templates.
109You could, of course, simply hardcode the path to you assets in the templates:
110
111.. code-block:: html
112
113 <img src="http://media.example.com/static/myimage.jpg" />
114
115Of course, there are some serious problems with this: it doesn't work well in
116development, and it makes it *very* hard to change where you've deployed your
117media. If, for example, you wanted to switch to using a content delivery network
118(CDN), then you'd need to change more or less every single template.
119
120A far better way is to use the value of the :setting:`STATICFILES_URL` setting
121directly in your templates. This means that a switch of media servers only
122requires changing that single value. Much better!
123
124``staticfiles`` inludes two built-in ways of getting at this setting in your
125templates: a context processor and a template tag.
126
127With a context processor
128------------------------
129
130The included context processor is the easy way. Simply make sure
131``'django.contrib.staticfiles.context_processors.staticfiles'`` is in your
132:setting:`TEMPLATE_CONTEXT_PROCESSORS`. It's there by default, and if you're
133editing that setting by hand it should look something like::
134
135 TEMPLATE_CONTEXT_PROCESSORS = (
136 'django.core.context_processors.debug',
137 'django.core.context_processors.i18n',
138 'django.contrib.auth.context_processors.auth',
139 'django.contrib.messages.context_processors.messages',
140 'django.contrib.staticfiles.context_processors.staticfiles',
141 )
142
143Once that's done, you can refer to :setting:`STATICFILES_URL` in your templates:
144
145.. code-block:: html+django
146
147 <img src="{{ STATICFILES_URL }}images/hi.jpg />
148
149If ``{{ STATICFILES_URL }}`` isn't working in your template, you're probably not
150using :class:`~django.template.RequestContext` when rendering the template.
151
152As a brief refresher, context processors add variables into the contexts of
153every template. However, context processors require that you use
154:class:`~django.template.RequestContext` when rendering templates. This happens
155automatically if you're using a :doc:`generic view </ref/class-based-views>`,
156but in views written by hand you'll need to explicitally use ``RequestContext``
157To see how that works, and to read more details, check out
158:ref:`subclassing-context-requestcontext`.
159
160With a template tag
161-------------------
162
163The second option is the :ttag:`get_staticfiles_prefix` template tag. You can
164use this if you're not using :class:`~django.template.RequestContext`, or if you
165need more control over exactly where and how :setting:`STATICFILES_URL` is
166injected into the template. Here's an example:
167
168.. code-block:: html+django
169
170 {% load staticfiles %}
171 <img src="{% get_staticfiles_prefix %}images/hi.jpg" />
172
173There's also a second form you can use to avoid extra processing if you need the
174value multiple times:
175
176.. code-block:: html+django
177
178 {% load staticfiles %}
179 {% get_staticfiles_prefix as STATIC_PREFIX %}
180
181 <img src="{{ STATIC_PREFIX }}images/hi.jpg" />
182 <img src="{{ STATIC_PREFIX }}images/hi2.jpg" />
183
184.. _staticfiles-development:
185
186Serving static files in development
187===================================
188
189The static files tools are mostly designed to help with getting static media
190successfully deployed into production. This usually means a separate, dedicated
191media server, which is a lot of overhead to mess with when developing locally.
192Thus, the ``staticfiles`` app ships with a quick and dirty helper view that you
193can use to serve media locally in development.
194
195To enable this view, you'll add a couple of lines to your URLconf. The first
196line goes at the top of the file, and the last line at the bottom::
197
198 from django.contrib.staticfiles.urls import staticfiles_urlpatterns
199
200 # ... the rest of your URLconf goes here ...
201
202 urlpatterns += staticfiles_urlpatterns()
203
204This will inspect your :setting:`STATICFILES_URL` and
205:setting:`STATICFILES_ROOT` settings and wire up the view to serve static media
206accordingly. Remember to run :djadmin:`collectstatic` when your media changes;
207the view only serves static files that have been collected.
208
209.. warning::
210
211 This will only work if :setting:`DEBUG` is ``True``.
212
213 That's because this view is **grossly inefficient** and probably
214 **insecure**. This is only intended for local development, and should
215 **never be used in production**.
216
217For a few more details, including an alternate method of enabling this view,
218see :ref:`staticfiles-development-view`.
219
220.. _staticfiles-production:
221
222Serving static files in production
223==================================
224
225The basic outline of putting static files into production a simple: run the
226:djadmin:`collectstatic` command when static media changes, then arrange for the
227collected media directory (:setting:`STATICFILES_ROOT`) to be moved to the media
228server and served.
229
230Of course, as with all deployment tasks, the devil's in the details. Every
231production setup will be a bit different, so you'll need to adapt the basic
232outline to fit your needs. Below are a few common patterns that might help.
233
234Serving the app and your static files from the same server
235----------------------------------------------------------
236
237If you want to serve your media from the same server that's already serving your
238app, the basic outline gets modified to look something like:
239
240 * Push your code up to the deployment server.
241 * On the server, run :djadmin:`collectmedia` to move all the media into
242 :setting:`STATICFILES_ROOT`.
243 * Point your web server at :setting:`STATICFILES_ROOT`. For example, here's
244 of :ref:`how to do this under Apache and mod_wsgi <serving-media-files>`.
245
246You'll probably want to automate this process, especially if you've got multiple
247web servers. There's any number of ways to do this automation, but one option
248that many Django developers enjoy is `Fabric`__.
249
250__ http://fabfile.org/
251
252Below, and in the following sections, we'll show off a few example fabfiles
253(i.e. Fabric scripts) that automate these media deployment options. The syntax
254of a fabfile is fairly streightforward but won't be covered here; consult `Fabric's documentation`__, for a complete explanation of the syntax..
255
256__ http://docs.fabfile.org/
257
258So, a fabfile to deploy media to a couple of web servers might look something
259like::
260
261 from fabric.api import *
262
263 # Hosts to deploy onto
264 env.hosts = ['www1.example.com', 'www2.example.com']
265
266 # Where your project code lives on the server
267 env.project_root = '/home/www/myproject'
268
269 def deploy_static():
270 with cd(env.project_root):
271 run('./manage.py collectstatic')
272
273Serving static files from a dedicated media server
274--------------------------------------------------
275
276Most larger Django apps use a separate Web server -- i.e., one that's not also
277running Django -- for serving media. This server often runs a different type of
278web server -- faster but less full-featured. Some good choices are:
279
280 * lighttpd_
281 * Nginx_
282 * TUX_
283 * Cherokee_
284 * A stripped-down version of Apache_
285
286.. _lighttpd: http://www.lighttpd.net/
287.. _Nginx: http://wiki.nginx.org/Main
288.. _TUX: http://en.wikipedia.org/wiki/TUX_web_server
289.. _Apache: http://httpd.apache.org/
290.. _Cherokee: http://www.cherokee-project.com/
291
292Configuring these servers is out of scope of this document; check each server's
293respective documentation for instructions.
294
295Since your media server won't be running Django, you'll need to modify the
296deployment strategy to look something like:
297
298 * When your media changes, run :djadmin:`collectstatic` locally.
299 * Push your local :setting:`STATICFILES_ROOT` up to the media server
300 into the directory that's being served. ``rsync`` is a good
301 choice for this step since it only needs to transfer the
302 bits of static media that have changed.
303
304Here's how this might look in a fabfile::
305
306 from fabric.api import *
307 from fabric.contrib import project
308
309 # Where the static files get collected locally
310 env.local_static_root = '/tmp/static'
311
312 # Where the static files should go remotely
313 env.remote_static_root = '/home/www/media.example.com'
314
315 @roles('media')
316 def deploy_static():
317 local('./manage.py collectstatic')
318 project.rysnc_project(
319 remote_dir = env.remote_static_root,
320 local_dir = env.local_static_root,
321 delete = True
322 )
323
324.. _staticfiles-from-cdn:
325
326Serving static media from a cloud service or CDN
327------------------------------------------------
328
329Another common tactic is to serve media from a cloud storage provider like
330Amazon's S3__ and/or a CDN (content delivery network). This lets you ignore the
331problems of serving media, and can often make for faster-loading webpages
332(especially when using a CDN).
333
334When using these services, the basic workflow would look a bit like the above,
335except that instead of using ``rsync`` to transfer your media to the server
336you'd need to transfer the media to the storage provider or CDN.
337
338There's any number of ways you might do this, but if the provider has an API a
339:doc:`custom file storage backend </howto/custom-file-storage>` will make the
340process incredibly simple. If you've written or are using a 3rd party custom
341storage backend, you can tell :djadmin:`collectstatic` to use it by setting
342:setting:`STATICFILES_STORAGE` to the storage engine.
343
344For example, if you've written an S3 storage backend in
345``myproject.storage.S3Storage`` you could use it with::
346
347 STATICFILES_STORAGE = 'storages.backends.s3.S3Storage'
348
349Once that's done, all you have to do is run :djadmin:`collectstatic` and your
350media would be pushed through your storage package up to S3. If you later needed
351to swich to a different storage provider, it could be as simple as changing your
352:setting:`STATICFILES_STORAGE` setting.
353
354For details on how you'd write one of these backends,
355:doc:`/howto/custom-file-storage`.
356
357.. seealso::
358
359 The `django-storages`__ project is a 3rd party app that provides many
360 storage backends for many common file storage APIs (including S3).
361
362__ http://s3.amazonaws.com/
363__ http://code.welldev.org/django-storages/wiki/S3Storage
364
365Upgrading from ``django-staticfiles``
366=====================================
367
368``django.contrib.staticfiles`` began its life as `django-staticfiles`_. If
369you're upgrading from `django-staticfiles`_ to ``django.contrib.staticfiles``,
370you'll need to make a few changes:
371
372 * Application files should now live in a ``static`` directory in each app
373 (`django-staticfiles`_ used the name ``media``, which was slightly
374 confusing).
375
376 * The management commands ``build_static`` and ``resolve_static`` are now
377 called :djadmin:`collectstatic` and :djadmin:`findstatic`.
378
379 * The settings ``STATIC_URL`` and ``STATIC_ROOT`` were renamed to
380 :setting:`STATICFILES_URL` and :setting:`STATICFILES_ROOT`.
381
382 * The settings ``STATICFILES_PREPEND_LABEL_APPS``,
383 ``STATICFILES_MEDIA_DIRNAMES`` and ``STATICFILES_EXCLUDED_APPS`` were
384 removed.
385
386 * The setting ``STATICFILES_RESOLVERS`` was removed, and replaced by the new
387 :setting:`STATICFILES_FINDERS`.
388
389 * The default for :setting:`STATICFILES_STORAGE` was renamed from
390 ``staticfiles.storage.StaticFileStorage`` to
391 ``staticfiles.storage.StaticFilesStorage``
392
393Learn more
394==========
395
396This document has covered the basics and some common usage patterns. For
397complete details on all the settings, commands, template tags, and other pieces
398include in ``django.contrib.staticfiles``, see :doc:`the statcfiles reference
399</ref/contrib/staticfiles>`.
Back to Top