Permalink
Browse files

Fixed #14693, #14709 -- Backwards incompatible change to rectify the …

…confusion around the STATICFILES_URL and STATICFILES_ROOT settings.

  * Two new global settings that will be used by -- **but are not limited to** -- the staticfiles app: STATIC_ROOT and STATIC_URL.

  * Moving the 'django.contrib.staticfiles.templatetags.staticfiles' template tag to the core ('django.templatetags.static') and renaming it to 'get_static_prefix'.

  * Moving the context processor 'django.contrib.staticfiles.context_processors.staticfiles' to the core ('django.core.context_processors.static') and renaming it to 'static'.

  * Paths in media definitions will use STATIC_URL as the prefix if the value is not None, and falls back to the previously used MEDIA_URL.

Thanks again to the community for constructive criticism and Carl and Russ for sanity-inducing discussions on IRC.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@14592 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
1 parent 9b45f6c commit 33d8fcde8a317184a627492f008a4eab9333ed88 @jezdez jezdez committed Nov 17, 2010
@@ -195,9 +195,9 @@
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
+ 'django.core.context_processors.static',
# 'django.core.context_processors.request',
'django.contrib.messages.context_processors.messages',
- 'django.contrib.staticfiles.context_processors.staticfiles',
)
# Output to use in template system for invalid (e.g. misspelled) variables.
@@ -256,13 +256,21 @@
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
# Absolute filesystem path to the directory that will hold user-uploaded files.
-# Example: "/home/media/media.lawrence.com/"
+# Example: "/home/media/media.lawrence.com/media/"
MEDIA_ROOT = ''
# URL that handles the media served from MEDIA_ROOT.
-# Example: "http://media.lawrence.com"
+# Example: "http://media.lawrence.com/media/"
MEDIA_URL = ''
+# Absolute path to the directory that holds static files.
+# Example: "/home/media/media.lawrence.com/static/"
+STATIC_ROOT = ''
+
+# URL that handles the static files served from STATIC_ROOT.
+# Example: "http://media.lawrence.com/static/"
+STATIC_URL = None
+
# List of upload handler classes to be applied in order.
FILE_UPLOAD_HANDLERS = (
'django.core.files.uploadhandler.MemoryFileUploadHandler',
@@ -552,14 +560,6 @@
# STATICFILES #
###############
-# Absolute path to the directory that holds media.
-# Example: "/home/media/media.lawrence.com/static/"
-STATICFILES_ROOT = ''
-
-# URL that handles the static files served from STATICFILES_ROOT.
-# Example: "http://media.lawrence.com/static/"
-STATICFILES_URL = '/static/'
-
# A list of locations of additional static files
STATICFILES_DIRS = ()
@@ -49,16 +49,16 @@
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash if there is a path component (optional in other cases).
-# Examples: "http://media.lawrence.com", "http://example.com/media/"
+# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
MEDIA_URL = ''
-# Absolute path to the directory that holds media.
+# Absolute path to the directory that holds static files.
# Example: "/home/media/media.lawrence.com/static/"
-STATICFILES_ROOT = ''
+STATIC_ROOT = ''
-# URL that handles the static files served from STATICFILES_ROOT.
-# Example: "http://static.lawrence.com/", "http://example.com/static/"
-STATICFILES_URL = '/static/'
+# URL that handles the static files served from STATIC_ROOT.
+# Example: "http://media.lawrence.com/static/"
+STATIC_URL = '/static/'
# URL prefix for admin media -- CSS, JavaScript and images.
# Make sure to use a trailing slash.
@@ -1,15 +1,11 @@
from django.template import Library
-from django.utils.encoding import iri_to_uri
+from django.templatetags.static import PrefixNode
register = Library()
+@register.simple_tag
def admin_media_prefix():
"""
Returns the string contained in the setting ADMIN_MEDIA_PREFIX.
"""
- try:
- from django.conf import settings
- except ImportError:
- return ''
- return iri_to_uri(settings.ADMIN_MEDIA_PREFIX)
-admin_media_prefix = register.simple_tag(admin_media_prefix)
+ return PrefixNode.handle_simple("ADMIN_MEDIA_PREFIX")
@@ -1,6 +0,0 @@
-from django.conf import settings
-
-def staticfiles(request):
- return {
- 'STATICFILES_URL': settings.STATICFILES_URL,
- }
@@ -10,46 +10,44 @@
class StaticFilesHandler(WSGIHandler):
"""
WSGI middleware that intercepts calls to the static files directory, as
- defined by the STATICFILES_URL setting, and serves those files.
+ defined by the STATIC_URL setting, and serves those files.
"""
- def __init__(self, application, media_dir=None):
+ def __init__(self, application, base_dir=None):
self.application = application
- if media_dir:
- self.media_dir = media_dir
+ if base_dir:
+ self.base_dir = base_dir
else:
- self.media_dir = self.get_media_dir()
- self.media_url = urlparse(self.get_media_url())
- if settings.DEBUG:
- utils.check_settings()
+ self.base_dir = self.get_base_dir()
+ self.base_url = urlparse(self.get_base_url())
super(StaticFilesHandler, self).__init__()
- def get_media_dir(self):
- return settings.STATICFILES_ROOT
+ def get_base_dir(self):
+ return settings.STATIC_ROOT
- def get_media_url(self):
- return settings.STATICFILES_URL
+ def get_base_url(self):
+ if settings.DEBUG:
+ utils.check_settings()
+ return settings.STATIC_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 host is provided as part of the base_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])
+ return (self.base_url[2] != path and
+ path.startswith(self.base_url[2]) and not self.base_url[1])
def file_path(self, url):
"""
Returns the relative path to the media file on disk for the given URL.
- The passed URL is assumed to begin with ``media_url``. If the
+ The passed URL is assumed to begin with ``base_url``. If the
resultant file path is outside the media directory, then a ValueError
is raised.
"""
- # Remove ``media_url``.
- relative_url = url[len(self.media_url[2]):]
+ relative_url = url[len(self.base_url[2]):]
return urllib.url2pathname(relative_url)
def serve(self, request):
@@ -12,7 +12,7 @@
class Command(NoArgsCommand):
"""
Command that allows to copy or symlink media files from different
- locations to the settings.STATICFILES_ROOT.
+ locations to the settings.STATIC_ROOT.
"""
option_list = NoArgsCommand.option_list + (
make_option('--noinput', action='store_false', dest='interactive',
@@ -85,7 +85,7 @@ def handle_noargs(self, **options):
self.stdout.write("\n%s static file%s %s to '%s'%s.\n"
% (actual_count, actual_count != 1 and 's' or '',
symlink and 'symlinked' or 'copied',
- settings.STATICFILES_ROOT,
+ settings.STATIC_ROOT,
unmodified_count and ' (%s unmodified)'
% unmodified_count or ''))
@@ -8,7 +8,7 @@
class Command(BaseRunserverCommand):
option_list = BaseRunserverCommand.option_list + (
make_option('--nostatic', action="store_false", dest='use_static_handler', default=True,
- help='Tells Django to NOT automatically serve static files at STATICFILES_URL.'),
+ help='Tells Django to NOT automatically serve static files at STATIC_URL.'),
make_option('--insecure', action="store_true", dest='insecure_serving', default=False,
help='Allows serving static files even if DEBUG is False.'),
)
@@ -12,21 +12,22 @@ class StaticFilesStorage(FileSystemStorage):
Standard file system storage for site media files.
The defaults for ``location`` and ``base_url`` are
- ``STATICFILES_ROOT`` and ``STATICFILES_URL``.
+ ``STATIC_ROOT`` and ``STATIC_URL``.
"""
def __init__(self, location=None, base_url=None, *args, **kwargs):
if location is None:
- location = settings.STATICFILES_ROOT
+ location = settings.STATIC_ROOT
if base_url is None:
- base_url = settings.STATICFILES_URL
+ base_url = settings.STATIC_URL
if not location:
raise ImproperlyConfigured("You're using the staticfiles app "
- "without having set the STATICFILES_ROOT setting. Set it to "
+ "without having set the STATIC_ROOT setting. Set it to "
"the absolute path of the directory that holds static media.")
- if not base_url:
+ # check for None since we might use a root URL (``/``)
+ if base_url is None:
raise ImproperlyConfigured("You're using the staticfiles app "
- "without having set the STATICFILES_URL setting. Set it to "
- "URL that handles the files served from STATICFILES_ROOT.")
+ "without having set the STATIC_URL setting. Set it to "
+ "URL that handles the files served from STATIC_ROOT.")
if settings.DEBUG:
utils.check_settings()
super(StaticFilesStorage, self).__init__(location, base_url, *args, **kwargs)
@@ -1,43 +0,0 @@
-from django import template
-from django.utils.encoding import iri_to_uri
-
-register = template.Library()
-
-class StaticFilesPrefixNode(template.Node):
-
- def __init__(self, varname=None):
- self.varname = varname
-
- def render(self, context):
- try:
- from django.conf import settings
- except ImportError:
- prefix = ''
- else:
- prefix = iri_to_uri(settings.STATICFILES_URL)
- if self.varname is None:
- return prefix
- context[self.varname] = prefix
- return ''
-
-@register.tag
-def get_staticfiles_prefix(parser, token):
- """
- Populates a template variable with the prefix (settings.STATICFILES_URL).
-
- Usage::
-
- {% get_staticfiles_prefix [as varname] %}
-
- Examples::
-
- {% get_staticfiles_prefix %}
- {% get_staticfiles_prefix as staticfiles_prefix %}
-
- """
- tokens = token.contents.split()
- if len(tokens) > 1 and tokens[1] != 'as':
- raise template.TemplateSyntaxError(
- "First argument in '%s' must be 'as'" % tokens[0])
- return StaticFilesPrefixNode(varname=(len(tokens) > 1 and tokens[2] or None))
-
@@ -18,15 +18,10 @@ def staticfiles_urlpatterns(prefix=None):
if not settings.DEBUG:
return []
if prefix is None:
- prefix = settings.STATICFILES_URL
- if not prefix:
+ prefix = settings.STATIC_URL
+ if not prefix or '://' in prefix:
raise ImproperlyConfigured(
- "The prefix for the 'staticfiles_urlpatterns' helper is empty. "
- "Make sure the STATICFILES_URL setting is set correctly.")
- if '://' in prefix:
- raise ImproperlyConfigured(
- "The STATICFILES_URL setting is a full URL, not a path and "
- "can't be used with the 'staticfiles_urlpatterns' helper.")
+ "The prefix for the 'staticfiles_urlpatterns' helper is invalid.")
if prefix.startswith("/"):
prefix = prefix[1:]
return patterns('',
@@ -33,13 +33,13 @@ def is_ignored(path):
def check_settings():
"""
- Checks if the MEDIA_(ROOT|URL) and STATICFILES_(ROOT|URL)
+ Checks if the MEDIA_(ROOT|URL) and STATIC_(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")
+ if settings.MEDIA_URL == settings.STATIC_URL:
+ raise ImproperlyConfigured("The MEDIA_URL and STATIC_URL "
+ "settings must have different values")
+ if ((settings.MEDIA_ROOT and settings.STATIC_ROOT) and
+ (settings.MEDIA_ROOT == settings.STATIC_ROOT)):
+ raise ImproperlyConfigured("The MEDIA_ROOT and STATIC_ROOT "
+ "settings must have different values")
@@ -66,6 +66,13 @@ def i18n(request):
return context_extras
+def static(request):
+ """
+ Adds static-related context variables to the context.
+
+ """
+ return {'STATIC_URL': settings.STATIC_URL}
+
def media(request):
"""
Adds media-related context variables to the context.
@@ -17,8 +17,8 @@
from django.core.management.color import color_style
from django.utils.http import http_date
from django.utils._os import safe_join
-from django.contrib.staticfiles.handlers import StaticFilesHandler
-from django.views import static
+
+from django.contrib.staticfiles import handlers, views as static
__version__ = "0.1"
__all__ = ['WSGIServer','WSGIRequestHandler']
@@ -635,34 +635,34 @@ def log_message(self, format, *args):
sys.stderr.write(msg)
-class AdminMediaHandler(StaticFilesHandler):
+class AdminMediaHandler(handlers.StaticFilesHandler):
"""
WSGI middleware that intercepts calls to the admin media directory, as
defined by the ADMIN_MEDIA_PREFIX setting, and serves those images.
Use this ONLY LOCALLY, for development! This hasn't been tested for
security and is not super efficient.
- """
- def get_media_dir(self):
+ This is pending for deprecation since 1.3.
+ """
+ def get_base_dir(self):
import django
return os.path.join(django.__path__[0], 'contrib', 'admin', 'media')
- def get_media_url(self):
+ def get_base_url(self):
from django.conf import settings
return settings.ADMIN_MEDIA_PREFIX
def file_path(self, url):
"""
Returns the path to the media file on disk for the given URL.
- The passed URL is assumed to begin with ``media_url``. If the
- resultant file path is outside the media directory, then a ValueError
+ The passed URL is assumed to begin with ``self.base_url``. If the
+ resulting file path is outside the media directory, then a ValueError
is raised.
"""
- # Remove ``media_url``.
- relative_url = url[len(self.media_url[2]):]
+ relative_url = url[len(self.base_url[2]):]
relative_path = urllib.url2pathname(relative_url)
- return safe_join(self.media_dir, relative_path)
+ return safe_join(self.base_dir, relative_path)
def serve(self, request):
document_root, path = os.path.split(self.file_path(request.path))
@@ -673,10 +673,10 @@ 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
+ * the host is provided as part of the base_url
+ * the request's path isn't under the base path
"""
- return path.startswith(self.media_url[2]) and not self.media_url[1]
+ return path.startswith(self.base_url[2]) and not self.base_url[1]
def run(addr, port, wsgi_handler):
Oops, something went wrong.

0 comments on commit 33d8fcd

Please sign in to comment.