* Updated StaticFilesHandler and AdminMediaHandler to make use of the 404 handler if needed. * Updated runserver management command to serve static files only in DEBUG mode (or if specified the --insecure option) and if the staticfiles app is in INSTALLED_APPS. Also added an option to disable serving completely (--nostatic). * Added check in debug mode if STATICFILES_* settings are different to MEDIA_* settings. * Removed a faulty PendingDeprecationWarning in AdminMediaHandler that is triggered every time runserver is used. * Fixed an issue with the modification time checks when running collectstatic. * Extended and refined documentation. Thanks to everyone for input, especially to Carl Meyer, Ted Kaemming and Adam Vandenberg for patches. git-svn-id: http://code.djangoproject.com/svn/django/trunk@14533 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
216fdfab61
commit
8e96584f63
|
@ -1,10 +1,10 @@
|
||||||
import os
|
|
||||||
import urllib
|
import urllib
|
||||||
from urlparse import urlparse
|
from urlparse import urlparse
|
||||||
|
|
||||||
from django.core.handlers.wsgi import WSGIHandler, STATUS_CODE_TEXT
|
from django.conf import settings
|
||||||
from django.http import Http404
|
from django.core.handlers.wsgi import WSGIHandler
|
||||||
|
|
||||||
|
from django.contrib.staticfiles import utils
|
||||||
from django.contrib.staticfiles.views import serve
|
from django.contrib.staticfiles.views import serve
|
||||||
|
|
||||||
class StaticFilesHandler(WSGIHandler):
|
class StaticFilesHandler(WSGIHandler):
|
||||||
|
@ -18,16 +18,28 @@ class StaticFilesHandler(WSGIHandler):
|
||||||
self.media_dir = media_dir
|
self.media_dir = media_dir
|
||||||
else:
|
else:
|
||||||
self.media_dir = self.get_media_dir()
|
self.media_dir = self.get_media_dir()
|
||||||
self.media_url = self.get_media_url()
|
self.media_url = urlparse(self.get_media_url())
|
||||||
|
if settings.DEBUG:
|
||||||
|
utils.check_settings()
|
||||||
|
super(StaticFilesHandler, self).__init__()
|
||||||
|
|
||||||
def get_media_dir(self):
|
def get_media_dir(self):
|
||||||
from django.conf import settings
|
|
||||||
return settings.STATICFILES_ROOT
|
return settings.STATICFILES_ROOT
|
||||||
|
|
||||||
def get_media_url(self):
|
def get_media_url(self):
|
||||||
from django.conf import settings
|
|
||||||
return settings.STATICFILES_URL
|
return settings.STATICFILES_URL
|
||||||
|
|
||||||
|
def _should_handle(self, path):
|
||||||
|
"""
|
||||||
|
Checks if the path should be handled. Ignores the path if:
|
||||||
|
|
||||||
|
* the host is provided as part of the media_url
|
||||||
|
* the request's path isn't under the media path (or equal)
|
||||||
|
* settings.DEBUG isn't True
|
||||||
|
"""
|
||||||
|
return (self.media_url[2] != path and
|
||||||
|
path.startswith(self.media_url[2]) and not self.media_url[1])
|
||||||
|
|
||||||
def file_path(self, url):
|
def file_path(self, url):
|
||||||
"""
|
"""
|
||||||
Returns the relative path to the media file on disk for the given URL.
|
Returns the relative path to the media file on disk for the given URL.
|
||||||
|
@ -37,36 +49,28 @@ class StaticFilesHandler(WSGIHandler):
|
||||||
is raised.
|
is raised.
|
||||||
"""
|
"""
|
||||||
# Remove ``media_url``.
|
# Remove ``media_url``.
|
||||||
relative_url = url[len(self.media_url):]
|
relative_url = url[len(self.media_url[2]):]
|
||||||
return urllib.url2pathname(relative_url)
|
return urllib.url2pathname(relative_url)
|
||||||
|
|
||||||
def serve(self, request, path):
|
def serve(self, request):
|
||||||
from django.contrib.staticfiles import finders
|
"""
|
||||||
absolute_path = finders.find(path)
|
Actually serves the request path.
|
||||||
if not absolute_path:
|
"""
|
||||||
raise Http404('%r could not be matched to a static file.' % path)
|
return serve(request, self.file_path(request.path), insecure=True)
|
||||||
absolute_path, filename = os.path.split(absolute_path)
|
|
||||||
return serve(request, path=filename, document_root=absolute_path)
|
def get_response(self, request):
|
||||||
|
from django.http import Http404
|
||||||
|
|
||||||
|
if self._should_handle(request.path):
|
||||||
|
try:
|
||||||
|
return self.serve(request)
|
||||||
|
except Http404, e:
|
||||||
|
if settings.DEBUG:
|
||||||
|
from django.views import debug
|
||||||
|
return debug.technical_404_response(request, e)
|
||||||
|
return super(StaticFilesHandler, self).get_response(request)
|
||||||
|
|
||||||
def __call__(self, environ, start_response):
|
def __call__(self, environ, start_response):
|
||||||
media_url_bits = urlparse(self.media_url)
|
if not self._should_handle(environ['PATH_INFO']):
|
||||||
# Ignore all requests if the host is provided as part of the media_url.
|
|
||||||
# Also ignore requests that aren't under the media path.
|
|
||||||
if (media_url_bits[1] or
|
|
||||||
not environ['PATH_INFO'].startswith(media_url_bits[2])):
|
|
||||||
return self.application(environ, start_response)
|
return self.application(environ, start_response)
|
||||||
request = self.application.request_class(environ)
|
return super(StaticFilesHandler, self).__call__(environ, start_response)
|
||||||
try:
|
|
||||||
response = self.serve(request, self.file_path(environ['PATH_INFO']))
|
|
||||||
except Http404:
|
|
||||||
status = '404 NOT FOUND'
|
|
||||||
start_response(status, {'Content-type': 'text/plain'}.items())
|
|
||||||
return [str('Page not found: %s' % environ['PATH_INFO'])]
|
|
||||||
status_text = STATUS_CODE_TEXT[response.status_code]
|
|
||||||
status = '%s %s' % (response.status_code, status_text)
|
|
||||||
response_headers = [(str(k), str(v)) for k, v in response.items()]
|
|
||||||
for c in response.cookies.values():
|
|
||||||
response_headers.append(('Set-Cookie', str(c.output(header=''))))
|
|
||||||
start_response(status, response_headers)
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,9 @@ Type 'yes' to continue, or 'no' to cancel: """)
|
||||||
if confirm != 'yes':
|
if confirm != 'yes':
|
||||||
raise CommandError("Static files build cancelled.")
|
raise CommandError("Static files build cancelled.")
|
||||||
|
|
||||||
|
# Use ints for file times (ticket #14665)
|
||||||
|
os.stat_float_times(False)
|
||||||
|
|
||||||
for finder in finders.get_finders():
|
for finder in finders.get_finders():
|
||||||
for source, prefix, storage in finder.list(ignore_patterns):
|
for source, prefix, storage in finder.list(ignore_patterns):
|
||||||
self.copy_file(source, prefix, storage, **options)
|
self.copy_file(source, prefix, storage, **options)
|
||||||
|
@ -126,7 +129,7 @@ Type 'yes' to continue, or 'no' to cancel: """)
|
||||||
else:
|
else:
|
||||||
destination_is_link = os.path.islink(
|
destination_is_link = os.path.islink(
|
||||||
self.destination_storage.path(destination))
|
self.destination_storage.path(destination))
|
||||||
if destination_last_modified == source_last_modified:
|
if destination_last_modified >= source_last_modified:
|
||||||
if (not symlink and not destination_is_link):
|
if (not symlink and not destination_is_link):
|
||||||
if verbosity >= 2:
|
if verbosity >= 2:
|
||||||
self.stdout.write("Skipping '%s' (not modified)\n"
|
self.stdout.write("Skipping '%s' (not modified)\n"
|
||||||
|
|
|
@ -27,6 +27,8 @@ class StaticFilesStorage(FileSystemStorage):
|
||||||
raise ImproperlyConfigured("You're using the staticfiles app "
|
raise ImproperlyConfigured("You're using the staticfiles app "
|
||||||
"without having set the STATICFILES_URL setting. Set it to "
|
"without having set the STATICFILES_URL setting. Set it to "
|
||||||
"URL that handles the files served from STATICFILES_ROOT.")
|
"URL that handles the files served from STATICFILES_ROOT.")
|
||||||
|
if settings.DEBUG:
|
||||||
|
utils.check_settings()
|
||||||
super(StaticFilesStorage, self).__init__(location, base_url, *args, **kwargs)
|
super(StaticFilesStorage, self).__init__(location, base_url, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,10 +19,14 @@ def staticfiles_urlpatterns(prefix=None):
|
||||||
return []
|
return []
|
||||||
if prefix is None:
|
if prefix is None:
|
||||||
prefix = settings.STATICFILES_URL
|
prefix = settings.STATICFILES_URL
|
||||||
|
if not prefix:
|
||||||
|
raise ImproperlyConfigured(
|
||||||
|
"The prefix for the 'staticfiles_urlpatterns' helper is empty. "
|
||||||
|
"Make sure the STATICFILES_URL setting is set correctly.")
|
||||||
if '://' in prefix:
|
if '://' in prefix:
|
||||||
raise ImproperlyConfigured(
|
raise ImproperlyConfigured(
|
||||||
"The STATICFILES_URL setting is a full URL, not a path and "
|
"The STATICFILES_URL setting is a full URL, not a path and "
|
||||||
"can't be used with the urls.staticfiles_urlpatterns() helper.")
|
"can't be used with the 'staticfiles_urlpatterns' helper.")
|
||||||
if prefix.startswith("/"):
|
if prefix.startswith("/"):
|
||||||
prefix = prefix[1:]
|
prefix = prefix[1:]
|
||||||
return patterns('',
|
return patterns('',
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import fnmatch
|
import fnmatch
|
||||||
|
from django.conf import settings
|
||||||
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
|
||||||
def get_files(storage, ignore_patterns=[], location=''):
|
def get_files(storage, ignore_patterns=[], location=''):
|
||||||
"""
|
"""
|
||||||
|
@ -28,3 +30,16 @@ def get_files(storage, ignore_patterns=[], location=''):
|
||||||
dir = '/'.join([location, dir])
|
dir = '/'.join([location, dir])
|
||||||
static_files.extend(get_files(storage, ignore_patterns, dir))
|
static_files.extend(get_files(storage, ignore_patterns, dir))
|
||||||
return static_files
|
return static_files
|
||||||
|
|
||||||
|
def check_settings():
|
||||||
|
"""
|
||||||
|
Checks if the MEDIA_(ROOT|URL) and STATICFILES_(ROOT|URL)
|
||||||
|
settings have the same value.
|
||||||
|
"""
|
||||||
|
if settings.MEDIA_URL == settings.STATICFILES_URL:
|
||||||
|
raise ImproperlyConfigured("The MEDIA_URL and STATICFILES_URL "
|
||||||
|
"settings must have individual values")
|
||||||
|
if ((settings.MEDIA_ROOT and settings.STATICFILES_ROOT) and
|
||||||
|
(settings.MEDIA_ROOT == settings.STATICFILES_ROOT)):
|
||||||
|
raise ImproperlyConfigured("The MEDIA_ROOT and STATICFILES_ROOT "
|
||||||
|
"settings must have individual values")
|
||||||
|
|
|
@ -17,10 +17,10 @@ from django.http import Http404, HttpResponse, HttpResponseRedirect, HttpRespons
|
||||||
from django.template import loader, Template, Context, TemplateDoesNotExist
|
from django.template import loader, Template, Context, TemplateDoesNotExist
|
||||||
from django.utils.http import http_date
|
from django.utils.http import http_date
|
||||||
|
|
||||||
from django.contrib.staticfiles import finders
|
from django.contrib.staticfiles import finders, utils
|
||||||
|
|
||||||
|
|
||||||
def serve(request, path, document_root=None, show_indexes=False):
|
def serve(request, path, document_root=None, show_indexes=False, insecure=False):
|
||||||
"""
|
"""
|
||||||
Serve static files below a given point in the directory structure or
|
Serve static files below a given point in the directory structure or
|
||||||
from locations inferred from the static files finders.
|
from locations inferred from the static files finders.
|
||||||
|
@ -41,13 +41,15 @@ def serve(request, path, document_root=None, show_indexes=False):
|
||||||
template hardcoded below, but if you'd like to override it, you can create
|
template hardcoded below, but if you'd like to override it, you can create
|
||||||
a template called ``static/directory_index.html``.
|
a template called ``static/directory_index.html``.
|
||||||
"""
|
"""
|
||||||
if not settings.DEBUG:
|
if not settings.DEBUG and not insecure:
|
||||||
raise ImproperlyConfigured("The view to serve static files can only "
|
raise ImproperlyConfigured("The view to serve static files can only "
|
||||||
"be used if the DEBUG setting is True")
|
"be used if the DEBUG setting is True or "
|
||||||
|
"the --insecure option of 'runserver' is "
|
||||||
|
"used")
|
||||||
if not document_root:
|
if not document_root:
|
||||||
absolute_path = finders.find(path)
|
absolute_path = finders.find(path)
|
||||||
if not absolute_path:
|
if not absolute_path:
|
||||||
raise Http404("%r could not be matched to a static file." % path)
|
raise Http404('"%s" could not be found' % path)
|
||||||
document_root, path = os.path.split(absolute_path)
|
document_root, path = os.path.split(absolute_path)
|
||||||
# Clean up given path to only allow serving files below document_root.
|
# Clean up given path to only allow serving files below document_root.
|
||||||
path = posixpath.normpath(urllib.unquote(path))
|
path = posixpath.normpath(urllib.unquote(path))
|
||||||
|
|
|
@ -9,6 +9,10 @@ class Command(BaseCommand):
|
||||||
option_list = BaseCommand.option_list + (
|
option_list = BaseCommand.option_list + (
|
||||||
make_option('--noreload', action='store_false', dest='use_reloader', default=True,
|
make_option('--noreload', action='store_false', dest='use_reloader', default=True,
|
||||||
help='Tells Django to NOT use the auto-reloader.'),
|
help='Tells Django to NOT use the auto-reloader.'),
|
||||||
|
make_option('--nostatic', action="store_false", dest='use_static_handler', default=True,
|
||||||
|
help='Tells Django to NOT automatically serve static files at STATICFILES_URL.'),
|
||||||
|
make_option('--insecure', action="store_true", dest='insecure_serving', default=False,
|
||||||
|
help='Allows serving static files even if DEBUG is True.'),
|
||||||
make_option('--adminmedia', dest='admin_media_path', default='',
|
make_option('--adminmedia', dest='admin_media_path', default='',
|
||||||
help='Specifies the directory from which to serve admin media.'),
|
help='Specifies the directory from which to serve admin media.'),
|
||||||
)
|
)
|
||||||
|
@ -42,6 +46,8 @@ class Command(BaseCommand):
|
||||||
use_reloader = options.get('use_reloader', True)
|
use_reloader = options.get('use_reloader', True)
|
||||||
admin_media_path = options.get('admin_media_path', '')
|
admin_media_path = options.get('admin_media_path', '')
|
||||||
shutdown_message = options.get('shutdown_message', '')
|
shutdown_message = options.get('shutdown_message', '')
|
||||||
|
use_static_handler = options.get('use_static_handler', True)
|
||||||
|
insecure_serving = options.get('insecure_serving', False)
|
||||||
quit_command = (sys.platform == 'win32') and 'CTRL-BREAK' or 'CONTROL-C'
|
quit_command = (sys.platform == 'win32') and 'CTRL-BREAK' or 'CONTROL-C'
|
||||||
|
|
||||||
def inner_run():
|
def inner_run():
|
||||||
|
@ -60,7 +66,11 @@ class Command(BaseCommand):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
handler = WSGIHandler()
|
handler = WSGIHandler()
|
||||||
handler = StaticFilesHandler(handler)
|
allow_serving = (settings.DEBUG and use_static_handler or
|
||||||
|
(use_static_handler and insecure_serving))
|
||||||
|
if (allow_serving and
|
||||||
|
"django.contrib.staticfiles" in settings.INSTALLED_APPS):
|
||||||
|
handler = StaticFilesHandler(handler)
|
||||||
# serve admin media like old-school (deprecation pending)
|
# serve admin media like old-school (deprecation pending)
|
||||||
handler = AdminMediaHandler(handler, admin_media_path)
|
handler = AdminMediaHandler(handler, admin_media_path)
|
||||||
run(addr, int(port), handler)
|
run(addr, int(port), handler)
|
||||||
|
|
|
@ -651,12 +651,6 @@ class AdminMediaHandler(StaticFilesHandler):
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
return settings.ADMIN_MEDIA_PREFIX
|
return settings.ADMIN_MEDIA_PREFIX
|
||||||
|
|
||||||
def __init__(self, application, media_dir=None):
|
|
||||||
warnings.warn('The AdminMediaHandler handler is deprecated; use the '
|
|
||||||
'`django.contrib.staticfiles.handlers.StaticFilesHandler` instead.',
|
|
||||||
PendingDeprecationWarning)
|
|
||||||
super(AdminMediaHandler, self).__init__(application, media_dir)
|
|
||||||
|
|
||||||
def file_path(self, url):
|
def file_path(self, url):
|
||||||
"""
|
"""
|
||||||
Returns the path to the media file on disk for the given URL.
|
Returns the path to the media file on disk for the given URL.
|
||||||
|
@ -666,13 +660,23 @@ class AdminMediaHandler(StaticFilesHandler):
|
||||||
is raised.
|
is raised.
|
||||||
"""
|
"""
|
||||||
# Remove ``media_url``.
|
# Remove ``media_url``.
|
||||||
relative_url = url[len(self.media_url):]
|
relative_url = url[len(self.media_url[2]):]
|
||||||
relative_path = urllib.url2pathname(relative_url)
|
relative_path = urllib.url2pathname(relative_url)
|
||||||
return safe_join(self.media_dir, relative_path)
|
return safe_join(self.media_dir, relative_path)
|
||||||
|
|
||||||
def serve(self, request, path):
|
def serve(self, request):
|
||||||
document_root, path = os.path.split(path)
|
document_root, path = os.path.split(self.file_path(request.path))
|
||||||
return static.serve(request, path, document_root=document_root)
|
return static.serve(request, path,
|
||||||
|
document_root=document_root, insecure=True)
|
||||||
|
|
||||||
|
def _should_handle(self, path):
|
||||||
|
"""
|
||||||
|
Checks if the path should be handled. Ignores the path if:
|
||||||
|
|
||||||
|
* the host is provided as part of the media_url
|
||||||
|
* the request's path isn't under the media path
|
||||||
|
"""
|
||||||
|
return path.startswith(self.media_url[2]) and not self.media_url[1]
|
||||||
|
|
||||||
|
|
||||||
def run(addr, port, wsgi_handler):
|
def run(addr, port, wsgi_handler):
|
||||||
|
|
|
@ -21,7 +21,7 @@ from django.contrib.staticfiles.views import \
|
||||||
directory_index, was_modified_since, serve as staticfiles_serve
|
directory_index, was_modified_since, serve as staticfiles_serve
|
||||||
|
|
||||||
|
|
||||||
def serve(request, path, document_root=None, show_indexes=False):
|
def serve(request, path, document_root=None, show_indexes=False, insecure=False):
|
||||||
"""
|
"""
|
||||||
Serve static files below a given point in the directory structure.
|
Serve static files below a given point in the directory structure.
|
||||||
|
|
||||||
|
@ -38,4 +38,4 @@ def serve(request, path, document_root=None, show_indexes=False):
|
||||||
warnings.warn("The view at `django.views.static.serve` is deprecated; "
|
warnings.warn("The view at `django.views.static.serve` is deprecated; "
|
||||||
"use the path `django.contrib.staticfiles.views.serve` "
|
"use the path `django.contrib.staticfiles.views.serve` "
|
||||||
"instead.", PendingDeprecationWarning)
|
"instead.", PendingDeprecationWarning)
|
||||||
return staticfiles_serve(request, path, document_root, show_indexes)
|
return staticfiles_serve(request, path, document_root, show_indexes, insecure)
|
||||||
|
|
|
@ -37,7 +37,7 @@ Using ``django.contrib.staticfiles``
|
||||||
|
|
||||||
Here's the basic usage in a nutshell:
|
Here's the basic usage in a nutshell:
|
||||||
|
|
||||||
1. Put your media somewhere that staticfiles will find it..
|
1. Put your media somewhere that staticfiles will find it.
|
||||||
|
|
||||||
Most of the time this place will be in a ``static`` directory within your
|
Most of the time this place will be in a ``static`` directory within your
|
||||||
application, but it could also be a specific directory you've put into
|
application, but it could also be a specific directory you've put into
|
||||||
|
@ -69,12 +69,19 @@ Here's the basic usage in a nutshell:
|
||||||
./manage.py collectstatic
|
./manage.py collectstatic
|
||||||
|
|
||||||
This'll churn through your static file storage and move them into the
|
This'll churn through your static file storage and move them into the
|
||||||
directory given by :setting:`STATICFILES_ROOT`.
|
directory given by :setting:`STATICFILES_ROOT`. (This is not necessary
|
||||||
|
in local development if you are using :djadmin:`runserver` or adding
|
||||||
|
``staticfiles_urlpatterns`` to your URLconf; see below).
|
||||||
|
|
||||||
4. Deploy that media.
|
4. Deploy that media.
|
||||||
|
|
||||||
If you're using the built-in development server, you can quickly
|
If you're using the built-in development server (the
|
||||||
serve static media locally by adding::
|
:djadmin:`runserver` management command) and have the :setting:`DEBUG`
|
||||||
|
setting set to ``True``, your staticfiles will automatically be served
|
||||||
|
from :setting:`STATICFILES_URL` in development.
|
||||||
|
|
||||||
|
If you are using some other server for local development, you can
|
||||||
|
quickly serve static media locally by adding::
|
||||||
|
|
||||||
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
||||||
urlpatterns += staticfiles_urlpatterns()
|
urlpatterns += staticfiles_urlpatterns()
|
||||||
|
@ -100,6 +107,18 @@ 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
|
for a detailed reference of the settings, commands, and other bits included with
|
||||||
the framework see :doc:`the staticfiles reference </ref/contrib/staticfiles>`.
|
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 will probably want to make your
|
||||||
|
:setting:`MEDIA_ROOT` and :setting:`MEDIA_URL` different from your
|
||||||
|
:setting:`STATICFILES_ROOT` and :setting:`STATICFILES_URL`. You will need to
|
||||||
|
arrange for serving of files in :setting:`MEDIA_ROOT` yourself;
|
||||||
|
``staticfiles`` does not deal with user-uploaded media at all.
|
||||||
|
|
||||||
.. _staticfiles-in-templates:
|
.. _staticfiles-in-templates:
|
||||||
|
|
||||||
Referring to static files in templates
|
Referring to static files in templates
|
||||||
|
@ -192,8 +211,12 @@ media 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
|
Thus, the ``staticfiles`` app ships with a quick and dirty helper view that you
|
||||||
can use to serve files locally in development.
|
can use to serve files locally in development.
|
||||||
|
|
||||||
To enable this view, you'll add a couple of lines to your URLconf. The first
|
This view is automatically enabled and will serve your static files at
|
||||||
line goes at the top of the file, and the last line at the bottom::
|
:setting:`STATICFILES_URL` when you use the built-in :djadmin:`runserver`.
|
||||||
|
|
||||||
|
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
|
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
||||||
|
|
||||||
|
@ -242,7 +265,7 @@ app, the basic outline gets modified to look something like:
|
||||||
* On the server, run :djadmin:`collectstatic` to move all the media into
|
* On the server, run :djadmin:`collectstatic` to move all the media into
|
||||||
:setting:`STATICFILES_ROOT`.
|
:setting:`STATICFILES_ROOT`.
|
||||||
* Point your web server at :setting:`STATICFILES_ROOT`. For example, here's
|
* Point your web server at :setting:`STATICFILES_ROOT`. For example, here's
|
||||||
of :ref:`how to do this under Apache and mod_wsgi <serving-media-files>`.
|
:ref:`how to do this under Apache and mod_wsgi <serving-media-files>`.
|
||||||
|
|
||||||
You'll probably want to automate this process, especially if you've got multiple
|
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
|
web servers. There's any number of ways to do this automation, but one option
|
||||||
|
@ -393,6 +416,10 @@ you'll need to make a few changes:
|
||||||
``staticfiles.storage.StaticFileStorage`` to
|
``staticfiles.storage.StaticFileStorage`` to
|
||||||
``staticfiles.storage.StaticFilesStorage``
|
``staticfiles.storage.StaticFilesStorage``
|
||||||
|
|
||||||
|
* If using :djadmin:`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
|
Learn more
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ Runs this project as a FastCGI application. Requires flup. Use
|
||||||
.B runfcgi help
|
.B runfcgi help
|
||||||
for help on the KEY=val pairs.
|
for help on the KEY=val pairs.
|
||||||
.TP
|
.TP
|
||||||
.BI "runserver [" "\-\-noreload" "] [" "\-\-adminmedia=ADMIN_MEDIA_PATH" "] [" "port|ipaddr:port" "]"
|
.BI "runserver [" "\-\-noreload" "] [" "\-\-nostatic" "] [" "\-\-insecure" "] [" "\-\-adminmedia=ADMIN_MEDIA_PATH" "] [" "port|ipaddr:port" "]"
|
||||||
Starts a lightweight Web server for development.
|
Starts a lightweight Web server for development.
|
||||||
.TP
|
.TP
|
||||||
.BI "shell [" "\-\-plain" "]"
|
.BI "shell [" "\-\-plain" "]"
|
||||||
|
|
|
@ -34,13 +34,21 @@ STATICFILES_ROOT
|
||||||
|
|
||||||
Default: ``''`` (Empty string)
|
Default: ``''`` (Empty string)
|
||||||
|
|
||||||
The absolute path to the directory that holds static files::
|
The absolute path to the directory that the :djadmin:`collectstatic` management
|
||||||
|
command will collect static files into, for serving from
|
||||||
|
:setting:`STATICFILES_URL`::
|
||||||
|
|
||||||
STATICFILES_ROOT = "/home/example.com/static/"
|
STATICFILES_ROOT = "/home/example.com/static/"
|
||||||
|
|
||||||
This is a **required setting** unless you've overridden
|
This is a **required setting** unless you've overridden
|
||||||
:setting:`STATICFILES_STORAGE` and are using a custom storage backend.
|
:setting:`STATICFILES_STORAGE` and are using a custom storage backend.
|
||||||
|
|
||||||
|
This is not a place to store your static files permanently under version
|
||||||
|
control; you should do that in directories that will be found by your
|
||||||
|
:setting:`STATICFILES_FINDERS` (by default, per-app ``static/`` subdirectories,
|
||||||
|
and any directories you include in :setting:`STATICFILES_DIRS`). Files from
|
||||||
|
those locations will be collected into :setting:`STATICFILES_ROOT`.
|
||||||
|
|
||||||
.. setting:: STATICFILES_URL
|
.. setting:: STATICFILES_URL
|
||||||
|
|
||||||
STATICFILES_URL
|
STATICFILES_URL
|
||||||
|
@ -51,7 +59,7 @@ Default: ``'/static/'``
|
||||||
The URL that handles the files served from :setting:`STATICFILES_ROOT`, e.g.::
|
The URL that handles the files served from :setting:`STATICFILES_ROOT`, e.g.::
|
||||||
|
|
||||||
STATICFILES_URL = '/site_media/static/'
|
STATICFILES_URL = '/site_media/static/'
|
||||||
|
|
||||||
... or perhaps::
|
... or perhaps::
|
||||||
|
|
||||||
STATICFILES_URL = 'http://static.example.com/'
|
STATICFILES_URL = 'http://static.example.com/'
|
||||||
|
@ -130,7 +138,7 @@ your :setting:`STATICFILES_FINDERS` setting, it will look for static files in
|
||||||
the default file storage as defined by the :setting:`DEFAULT_FILE_STORAGE`
|
the default file storage as defined by the :setting:`DEFAULT_FILE_STORAGE`
|
||||||
setting.
|
setting.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
When using the :class:`AppDirectoriesFinder` finder, make sure your apps can
|
When using the :class:`AppDirectoriesFinder` finder, make sure your apps can
|
||||||
be found by Django's app loading mechanism. Simply include a ``models``
|
be found by Django's app loading mechanism. Simply include a ``models``
|
||||||
|
@ -271,11 +279,13 @@ This view function serves static files in development.
|
||||||
**insecure**. This is only intended for local development, and should
|
**insecure**. This is only intended for local development, and should
|
||||||
**never be used in production**.
|
**never be used in production**.
|
||||||
|
|
||||||
To use the view, add the following snippet to the end of your primary URL
|
This view is automatically enabled by :djadmin:`runserver` (with a
|
||||||
configuration::
|
: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.conf import settings
|
||||||
|
|
||||||
if settings.DEBUG:
|
if settings.DEBUG:
|
||||||
urlpatterns = patterns('django.contrib.staticfiles.views',
|
urlpatterns = patterns('django.contrib.staticfiles.views',
|
||||||
url(r'^static/(?P<path>.*)$', 'serve'),
|
url(r'^static/(?P<path>.*)$', 'serve'),
|
||||||
|
@ -292,8 +302,8 @@ This will return the proper URL pattern for serving static files to your
|
||||||
already defined pattern list. Use it like this::
|
already defined pattern list. Use it like this::
|
||||||
|
|
||||||
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
||||||
|
|
||||||
# ... the rest of your URLconf here ...
|
# ... the rest of your URLconf here ...
|
||||||
|
|
||||||
urlpatterns += staticfiles_urlpatterns()
|
urlpatterns += staticfiles_urlpatterns()
|
||||||
|
|
||||||
|
|
|
@ -681,6 +681,31 @@ Example usage::
|
||||||
|
|
||||||
django-admin.py runserver --noreload
|
django-admin.py runserver --noreload
|
||||||
|
|
||||||
|
.. django-admin-option:: --nostatic
|
||||||
|
|
||||||
|
Use the ``--nostatic`` option to disable serving of static files with the
|
||||||
|
:doc:`staticfiles </ref/contrib/staticfiles>` app entirely.
|
||||||
|
|
||||||
|
Example usage::
|
||||||
|
|
||||||
|
django-admin.py 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 acknoledge the fact that it's
|
||||||
|
**grossly inefficient** and probably **insecure**. This is only intended for
|
||||||
|
local development, and should **never be used in production**.
|
||||||
|
|
||||||
|
See the :doc:`reference documentation of the app </ref/contrib/staticfiles>`
|
||||||
|
for more details and learn how to :doc:`manage and deploy static files
|
||||||
|
</howto/static-files>` correctly.
|
||||||
|
|
||||||
|
Example usage::
|
||||||
|
|
||||||
|
django-admin.py runserver --insecure
|
||||||
|
|
||||||
Examples of using different ports and addresses
|
Examples of using different ports and addresses
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ Default: ``'/media/'``
|
||||||
|
|
||||||
The URL prefix for admin media -- CSS, JavaScript and images used by
|
The URL prefix for admin media -- CSS, JavaScript and images used by
|
||||||
the Django administrative interface. Make sure to use a trailing
|
the Django administrative interface. Make sure to use a trailing
|
||||||
slash, and to have this be different from the ``MEDIA_URL`` setting
|
slash, and to have this be different from the :setting:`MEDIA_URL` setting
|
||||||
(since the same URL cannot be mapped onto two different sets of
|
(since the same URL cannot be mapped onto two different sets of
|
||||||
files).
|
files).
|
||||||
|
|
||||||
|
@ -1104,8 +1104,12 @@ MEDIA_ROOT
|
||||||
|
|
||||||
Default: ``''`` (Empty string)
|
Default: ``''`` (Empty string)
|
||||||
|
|
||||||
Absolute path to the directory that holds media for this installation.
|
Absolute path to the directory that holds media for this installation, used
|
||||||
Example: ``"/home/media/media.lawrence.com/"`` See also ``MEDIA_URL``.
|
for :doc:`managing stored files </topics/files>`.
|
||||||
|
|
||||||
|
Example: ``"/home/media/media.lawrence.com/"``
|
||||||
|
|
||||||
|
See also :setting:`MEDIA_URL`.
|
||||||
|
|
||||||
.. setting:: MEDIA_URL
|
.. setting:: MEDIA_URL
|
||||||
|
|
||||||
|
@ -1114,15 +1118,15 @@ MEDIA_URL
|
||||||
|
|
||||||
Default: ``''`` (Empty string)
|
Default: ``''`` (Empty string)
|
||||||
|
|
||||||
URL that handles the media served from ``MEDIA_ROOT``.
|
URL that handles the media served from :setting:`MEDIA_ROOT`, used
|
||||||
|
for :doc:`managing stored files </topics/files>`.
|
||||||
|
|
||||||
Example: ``"http://media.lawrence.com"``
|
Example: ``"http://media.lawrence.com"``
|
||||||
|
|
||||||
Note that this should have a trailing slash if it has a path component.
|
Note that this should have a trailing slash if it has a path component.
|
||||||
|
|
||||||
Good: ``"http://www.example.com/static/"``
|
* Good: ``"http://www.example.com/static/"``
|
||||||
Bad: ``"http://www.example.com/static"``
|
* Bad: ``"http://www.example.com/static"``
|
||||||
|
|
||||||
.. setting:: MIDDLEWARE_CLASSES
|
|
||||||
|
|
||||||
MESSAGE_LEVEL
|
MESSAGE_LEVEL
|
||||||
-------------
|
-------------
|
||||||
|
@ -1161,6 +1165,8 @@ Default::
|
||||||
Sets the mapping of message levels to message tags. See the
|
Sets the mapping of message levels to message tags. See the
|
||||||
:doc:`messages documentation </ref/contrib/messages>` for more details.
|
:doc:`messages documentation </ref/contrib/messages>` for more details.
|
||||||
|
|
||||||
|
.. setting:: MIDDLEWARE_CLASSES
|
||||||
|
|
||||||
MIDDLEWARE_CLASSES
|
MIDDLEWARE_CLASSES
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue