Ticket #14693: 14693.3.diff

File 14693.3.diff, 83.1 KB (added by Jannis Leidel, 14 years ago)

Final patch

  • django/conf/global_settings.py

    diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py
    index 3aa333b..7469b13 100644
    a b TEMPLATE_CONTEXT_PROCESSORS = (  
    195195    'django.core.context_processors.debug',
    196196    'django.core.context_processors.i18n',
    197197    'django.core.context_processors.media',
     198    'django.core.context_processors.static',
    198199#    'django.core.context_processors.request',
    199200    'django.contrib.messages.context_processors.messages',
    200     'django.contrib.staticfiles.context_processors.staticfiles',
    201201)
    202202
    203203# Output to use in template system for invalid (e.g. misspelled) variables.
    MEDIA_ROOT = ''  
    263263# Example: "http://media.lawrence.com"
    264264MEDIA_URL = ''
    265265
     266# Absolute path to the directory that holds static files.
     267# Example: "/home/media/media.lawrence.com/static/"
     268STATIC_ROOT = ''
     269
     270# URL that handles the static files served from STATIC_ROOT.
     271# Example: "http://media.lawrence.com/static/"
     272STATIC_URL = None
     273
    266274# List of upload handler classes to be applied in order.
    267275FILE_UPLOAD_HANDLERS = (
    268276    'django.core.files.uploadhandler.MemoryFileUploadHandler',
    FIXTURE_DIRS = ()  
    552560# STATICFILES #
    553561###############
    554562
    555 # Absolute path to the directory that holds media.
    556 # Example: "/home/media/media.lawrence.com/static/"
    557 STATICFILES_ROOT = ''
    558 
    559 # URL that handles the static files served from STATICFILES_ROOT.
    560 # Example: "http://media.lawrence.com/static/"
    561 STATICFILES_URL = '/static/'
    562 
    563563# A list of locations of additional static files
    564564STATICFILES_DIRS = ()
    565565
  • django/conf/project_template/settings.py

    diff --git a/django/conf/project_template/settings.py b/django/conf/project_template/settings.py
    index 1d33dd1..873194c 100644
    a b MEDIA_URL = ''  
    5454
    5555# Absolute path to the directory that holds media.
    5656# Example: "/home/media/media.lawrence.com/static/"
    57 STATICFILES_ROOT = ''
     57STATIC_ROOT = ''
    5858
    59 # URL that handles the static files served from STATICFILES_ROOT.
     59# URL that handles the static files served from STATIC_ROOT.
    6060# Example: "http://static.lawrence.com/", "http://example.com/static/"
    61 STATICFILES_URL = '/static/'
     61STATIC_URL = '/static/'
    6262
    6363# URL prefix for admin media -- CSS, JavaScript and images.
    6464# Make sure to use a trailing slash.
  • django/contrib/admin/templatetags/adminmedia.py

    diff --git a/django/contrib/admin/templatetags/adminmedia.py b/django/contrib/admin/templatetags/adminmedia.py
    index 5429810..3b1c39b 100644
    a b  
    11from django.template import Library
    2 from django.utils.encoding import iri_to_uri
     2from django.templatetags.static import PrefixNode
    33
    44register = Library()
    55
     6@register.simple_tag
    67def admin_media_prefix():
    78    """
    89    Returns the string contained in the setting ADMIN_MEDIA_PREFIX.
    910    """
    10     try:
    11         from django.conf import settings
    12     except ImportError:
    13         return ''
    14     return iri_to_uri(settings.ADMIN_MEDIA_PREFIX)
    15 admin_media_prefix = register.simple_tag(admin_media_prefix)
     11    return PrefixNode.handle_simple("ADMIN_MEDIA_PREFIX")
  • deleted file django/contrib/staticfiles/context_processors.py

    diff --git a/django/contrib/staticfiles/context_processors.py b/django/contrib/staticfiles/context_processors.py
    deleted file mode 100644
    index 3ed0071..0000000
    + -  
    1 from django.conf import settings
    2 
    3 def staticfiles(request):
    4     return {
    5         'STATICFILES_URL': settings.STATICFILES_URL,
    6     }
  • django/contrib/staticfiles/handlers.py

    diff --git a/django/contrib/staticfiles/handlers.py b/django/contrib/staticfiles/handlers.py
    index 20b0496..2b72761 100644
    a b from django.contrib.staticfiles.views import serve  
    1010class StaticFilesHandler(WSGIHandler):
    1111    """
    1212    WSGI middleware that intercepts calls to the static files directory, as
    13     defined by the STATICFILES_URL setting, and serves those files.
     13    defined by the STATIC_URL setting, and serves those files.
    1414    """
    15     def __init__(self, application, media_dir=None):
     15    def __init__(self, application, base_dir=None):
    1616        self.application = application
    17         if media_dir:
    18             self.media_dir = media_dir
     17        if base_dir:
     18            self.base_dir = base_dir
    1919        else:
    20             self.media_dir = self.get_media_dir()
    21         self.media_url = urlparse(self.get_media_url())
    22         if settings.DEBUG:
    23             utils.check_settings()
     20            self.base_dir = self.get_base_dir()
     21        self.base_url = urlparse(self.get_base_url())
    2422        super(StaticFilesHandler, self).__init__()
    2523
    26     def get_media_dir(self):
    27         return settings.STATICFILES_ROOT
     24    def get_base_dir(self):
     25        return settings.STATIC_ROOT
    2826
    29     def get_media_url(self):
    30         return settings.STATICFILES_URL
     27    def get_base_url(self):
     28        if settings.DEBUG:
     29            utils.check_settings()
     30        return settings.STATIC_URL
    3131
    3232    def _should_handle(self, path):
    3333        """
    3434        Checks if the path should be handled. Ignores the path if:
    3535
    36         * the host is provided as part of the media_url
     36        * the host is provided as part of the base_url
    3737        * the request's path isn't under the media path (or equal)
    38         * settings.DEBUG isn't True
    3938        """
    40         return (self.media_url[2] != path and
    41             path.startswith(self.media_url[2]) and not self.media_url[1])
     39        return (self.base_url[2] != path and
     40            path.startswith(self.base_url[2]) and not self.base_url[1])
    4241
    4342    def file_path(self, url):
    4443        """
    4544        Returns the relative path to the media file on disk for the given URL.
    4645
    47         The passed URL is assumed to begin with ``media_url``.  If the
     46        The passed URL is assumed to begin with ``base_url``.  If the
    4847        resultant file path is outside the media directory, then a ValueError
    4948        is raised.
    5049        """
    51         # Remove ``media_url``.
    52         relative_url = url[len(self.media_url[2]):]
     50        relative_url = url[len(self.base_url[2]):]
    5351        return urllib.url2pathname(relative_url)
    5452
    5553    def serve(self, request):
  • django/contrib/staticfiles/management/commands/collectstatic.py

    diff --git a/django/contrib/staticfiles/management/commands/collectstatic.py b/django/contrib/staticfiles/management/commands/collectstatic.py
    index d121223..8882ae2 100644
    a b from django.contrib.staticfiles import finders  
    1212class Command(NoArgsCommand):
    1313    """
    1414    Command that allows to copy or symlink media files from different
    15     locations to the settings.STATICFILES_ROOT.
     15    locations to the settings.STATIC_ROOT.
    1616    """
    1717    option_list = NoArgsCommand.option_list + (
    1818        make_option('--noinput', action='store_false', dest='interactive',
    Type 'yes' to continue, or 'no' to cancel: """)  
    8585            self.stdout.write("\n%s static file%s %s to '%s'%s.\n"
    8686                              % (actual_count, actual_count != 1 and 's' or '',
    8787                                 symlink and 'symlinked' or 'copied',
    88                                  settings.STATICFILES_ROOT,
     88                                 settings.STATIC_ROOT,
    8989                                 unmodified_count and ' (%s unmodified)'
    9090                                 % unmodified_count or ''))
    9191
  • django/contrib/staticfiles/management/commands/runserver.py

    diff --git a/django/contrib/staticfiles/management/commands/runserver.py b/django/contrib/staticfiles/management/commands/runserver.py
    index e138759..f4c2259 100644
    a b from django.contrib.staticfiles.handlers import StaticFilesHandler  
    88class Command(BaseRunserverCommand):
    99    option_list = BaseRunserverCommand.option_list + (
    1010        make_option('--nostatic', action="store_false", dest='use_static_handler', default=True,
    11             help='Tells Django to NOT automatically serve static files at STATICFILES_URL.'),
     11            help='Tells Django to NOT automatically serve static files at STATIC_URL.'),
    1212        make_option('--insecure', action="store_true", dest='insecure_serving', default=False,
    1313            help='Allows serving static files even if DEBUG is False.'),
    1414    )
  • django/contrib/staticfiles/storage.py

    diff --git a/django/contrib/staticfiles/storage.py b/django/contrib/staticfiles/storage.py
    index b4bfea7..eb0eabf 100644
    a b class StaticFilesStorage(FileSystemStorage):  
    1212    Standard file system storage for site media files.
    1313   
    1414    The defaults for ``location`` and ``base_url`` are
    15     ``STATICFILES_ROOT`` and ``STATICFILES_URL``.
     15    ``STATIC_ROOT`` and ``STATIC_URL``.
    1616    """
    1717    def __init__(self, location=None, base_url=None, *args, **kwargs):
    1818        if location is None:
    19             location = settings.STATICFILES_ROOT
     19            location = settings.STATIC_ROOT
    2020        if base_url is None:
    21             base_url = settings.STATICFILES_URL
     21            base_url = settings.STATIC_URL
    2222        if not location:
    2323            raise ImproperlyConfigured("You're using the staticfiles app "
    24                 "without having set the STATICFILES_ROOT setting. Set it to "
     24                "without having set the STATIC_ROOT setting. Set it to "
    2525                "the absolute path of the directory that holds static media.")
    26         if not base_url:
     26        # check for None since we might use a root URL (``/``)
     27        if base_url is None:
    2728            raise ImproperlyConfigured("You're using the staticfiles app "
    28                 "without having set the STATICFILES_URL setting. Set it to "
    29                 "URL that handles the files served from STATICFILES_ROOT.")
     29                "without having set the STATIC_URL setting. Set it to "
     30                "URL that handles the files served from STATIC_ROOT.")
    3031        if settings.DEBUG:
    3132            utils.check_settings()
    3233        super(StaticFilesStorage, self).__init__(location, base_url, *args, **kwargs)
  • deleted file django/contrib/staticfiles/templatetags/staticfiles.py

    diff --git a/django/contrib/staticfiles/templatetags/__init__.py b/django/contrib/staticfiles/templatetags/__init__.py
    deleted file mode 100644
    index e69de29..0000000
    diff --git a/django/contrib/staticfiles/templatetags/staticfiles.py b/django/contrib/staticfiles/templatetags/staticfiles.py
    deleted file mode 100644
    index 6153f5a..0000000
    + -  
    1 from django import template
    2 from django.utils.encoding import iri_to_uri
    3 
    4 register = template.Library()
    5 
    6 class StaticFilesPrefixNode(template.Node):
    7 
    8     def __init__(self, varname=None):
    9         self.varname = varname
    10 
    11     def render(self, context):
    12         try:
    13             from django.conf import settings
    14         except ImportError:
    15             prefix = ''
    16         else:
    17             prefix = iri_to_uri(settings.STATICFILES_URL)
    18         if self.varname is None:
    19             return prefix
    20         context[self.varname] = prefix
    21         return ''
    22 
    23 @register.tag
    24 def get_staticfiles_prefix(parser, token):
    25     """
    26     Populates a template variable with the prefix (settings.STATICFILES_URL).
    27 
    28     Usage::
    29 
    30         {% get_staticfiles_prefix [as varname] %}
    31 
    32     Examples::
    33 
    34         {% get_staticfiles_prefix %}
    35         {% get_staticfiles_prefix as staticfiles_prefix %}
    36 
    37     """
    38     tokens = token.contents.split()
    39     if len(tokens) > 1 and tokens[1] != 'as':
    40         raise template.TemplateSyntaxError(
    41             "First argument in '%s' must be 'as'" % tokens[0])
    42     return StaticFilesPrefixNode(varname=(len(tokens) > 1 and tokens[2] or None))
    43 
  • django/contrib/staticfiles/urls.py

    diff --git a/django/contrib/staticfiles/urls.py b/django/contrib/staticfiles/urls.py
    index 70f04f2..aa4ab45 100644
    a b def staticfiles_urlpatterns(prefix=None):  
    1818    if not settings.DEBUG:
    1919        return []
    2020    if prefix is None:
    21         prefix = settings.STATICFILES_URL
    22     if not prefix:
     21        prefix = settings.STATIC_URL
     22    if not prefix or '://' in prefix:
    2323        raise ImproperlyConfigured(
    24             "The prefix for the 'staticfiles_urlpatterns' helper is empty. "
    25             "Make sure the STATICFILES_URL setting is set correctly.")
    26     if '://' in prefix:
    27         raise ImproperlyConfigured(
    28             "The STATICFILES_URL setting is a full URL, not a path and "
    29             "can't be used with the 'staticfiles_urlpatterns' helper.")
     24            "The prefix for the 'staticfiles_urlpatterns' helper is invalid.")
    3025    if prefix.startswith("/"):
    3126        prefix = prefix[1:]
    3227    return patterns('',
  • django/contrib/staticfiles/utils.py

    diff --git a/django/contrib/staticfiles/utils.py b/django/contrib/staticfiles/utils.py
    index 0071dbd..d307253 100644
    a b def get_files(storage, ignore_patterns=[], location=''):  
    3333
    3434def check_settings():
    3535    """
    36     Checks if the MEDIA_(ROOT|URL) and STATICFILES_(ROOT|URL)
     36    Checks if the MEDIA_(ROOT|URL) and STATIC_(ROOT|URL)
    3737    settings have the same value.
    3838    """
    39     if settings.MEDIA_URL == settings.STATICFILES_URL:
    40         raise ImproperlyConfigured("The MEDIA_URL and STATICFILES_URL "
     39    if settings.MEDIA_URL == settings.STATIC_URL:
     40        raise ImproperlyConfigured("The MEDIA_URL and STATIC_URL "
    4141                                   "settings must have individual values")
    42     if ((settings.MEDIA_ROOT and settings.STATICFILES_ROOT) and
    43             (settings.MEDIA_ROOT == settings.STATICFILES_ROOT)):
    44         raise ImproperlyConfigured("The MEDIA_ROOT and STATICFILES_ROOT "
     42    if ((settings.MEDIA_ROOT and settings.STATIC_ROOT) and
     43            (settings.MEDIA_ROOT == settings.STATIC_ROOT)):
     44        raise ImproperlyConfigured("The MEDIA_ROOT and STATIC_ROOT "
    4545                                   "settings must have individual values")
  • django/core/context_processors.py

    diff --git a/django/core/context_processors.py b/django/core/context_processors.py
    index 7a59728..fa05d42 100644
    a b def i18n(request):  
    6666
    6767    return context_extras
    6868
     69def static(request):
     70    """
     71    Adds static-related context variables to the context.
     72
     73    """
     74    return {'STATIC_URL': settings.STATIC_URL}
     75
    6976def media(request):
    7077    """
    7178    Adds media-related context variables to the context.
  • django/core/servers/basehttp.py

    diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py
    index 9c92a88..9c3e900 100644
    a b import warnings  
    1717from django.core.management.color import color_style
    1818from django.utils.http import http_date
    1919from django.utils._os import safe_join
    20 from django.contrib.staticfiles.handlers import StaticFilesHandler
    21 from django.views import static
     20
     21from django.contrib.staticfiles import handlers, views as static
    2222
    2323__version__ = "0.1"
    2424__all__ = ['WSGIServer','WSGIRequestHandler']
    class WSGIRequestHandler(BaseHTTPRequestHandler):  
    635635        sys.stderr.write(msg)
    636636
    637637
    638 class AdminMediaHandler(StaticFilesHandler):
     638class AdminMediaHandler(handlers.StaticFilesHandler):
    639639    """
    640640    WSGI middleware that intercepts calls to the admin media directory, as
    641641    defined by the ADMIN_MEDIA_PREFIX setting, and serves those images.
    642642    Use this ONLY LOCALLY, for development! This hasn't been tested for
    643643    security and is not super efficient.
    644     """
    645644
    646     def get_media_dir(self):
     645    This is pending for deprecation since 1.3.
     646    """
     647    def get_base_dir(self):
    647648        import django
    648649        return os.path.join(django.__path__[0], 'contrib', 'admin', 'media')
    649650
    650     def get_media_url(self):
     651    def get_base_url(self):
    651652        from django.conf import settings
    652653        return settings.ADMIN_MEDIA_PREFIX
    653654
    class AdminMediaHandler(StaticFilesHandler):  
    655656        """
    656657        Returns the path to the media file on disk for the given URL.
    657658
    658         The passed URL is assumed to begin with ``media_url``.  If the
    659         resultant file path is outside the media directory, then a ValueError
     659        The passed URL is assumed to begin with ``self.base_url``.  If the
     660        resulting file path is outside the media directory, then a ValueError
    660661        is raised.
    661662        """
    662         # Remove ``media_url``.
    663         relative_url = url[len(self.media_url[2]):]
     663        relative_url = url[len(self.base_url[2]):]
    664664        relative_path = urllib.url2pathname(relative_url)
    665         return safe_join(self.media_dir, relative_path)
     665        return safe_join(self.base_dir, relative_path)
    666666
    667667    def serve(self, request):
    668668        document_root, path = os.path.split(self.file_path(request.path))
    class AdminMediaHandler(StaticFilesHandler):  
    673673        """
    674674        Checks if the path should be handled. Ignores the path if:
    675675
    676         * the host is provided as part of the media_url
    677         * the request's path isn't under the media path
     676        * the host is provided as part of the base_url
     677        * the request's path isn't under the base path
    678678        """
    679         return path.startswith(self.media_url[2]) and not self.media_url[1]
     679        return path.startswith(self.base_url[2]) and not self.base_url[1]
    680680
    681681
    682682def run(addr, port, wsgi_handler):
  • django/forms/widgets.py

    diff --git a/django/forms/widgets.py b/django/forms/widgets.py
    index cb12586..8eb5fef 100644
    a b  
    11"""
    22HTML Widget classes
    33"""
     4import datetime
     5from itertools import chain
     6import time
     7from urlparse import urljoin
     8from util import flatatt
    49
    510import django.utils.copycompat as copy
    6 from itertools import chain
    711from django.conf import settings
    812from django.utils.datastructures import MultiValueDict, MergeDict
    913from django.utils.html import escape, conditional_escape
    from django.utils.translation import ugettext, ugettext_lazy  
    1115from django.utils.encoding import StrAndUnicode, force_unicode
    1216from django.utils.safestring import mark_safe
    1317from django.utils import datetime_safe, formats
    14 import time
    15 import datetime
    16 from util import flatatt
    17 from urlparse import urljoin
    1818
    1919__all__ = (
    2020    'Media', 'MediaDefiningClass', 'Widget', 'TextInput', 'PasswordInput',
    class Media(StrAndUnicode):  
    6363                    for path in self._css[medium]]
    6464                for medium in media])
    6565
    66     def absolute_path(self, path):
     66    def absolute_path(self, path, prefix=None):
    6767        if path.startswith(u'http://') or path.startswith(u'https://') or path.startswith(u'/'):
    6868            return path
    69         return urljoin(settings.MEDIA_URL,path)
     69        if prefix is None:
     70            if settings.STATIC_URL is None:
     71                 # backwards compatibility
     72                prefix = settings.MEDIA_URL
     73            else:
     74                prefix = settings.STATIC_URL
     75        return urljoin(prefix, path)
    7076
    7177    def __getitem__(self, name):
    7278        "Returns a Media object that only contains media of the given type"
  • new file django/templatetags/static.py

    diff --git a/django/templatetags/static.py b/django/templatetags/static.py
    new file mode 100644
    index 0000000..97d6571
    - +  
     1from django import template
     2from django.utils.encoding import iri_to_uri
     3
     4register = template.Library()
     5
     6class PrefixNode(template.Node):
     7
     8    def __repr__(self):
     9        return "<PrefixNode for %r>" % self.name
     10
     11    def __init__(self, varname=None, name=None):
     12        if name is None:
     13            raise template.TemplateSyntaxError(
     14                "Prefix nodes must be given a name to return.")
     15        self.varname = varname
     16        self.name = name
     17
     18    @classmethod
     19    def handle_token(cls, parser, token, name):
     20        """
     21        Class method to parse prefix node and return a Node.
     22        """
     23        tokens = token.contents.split()
     24        if len(tokens) > 1 and tokens[1] != 'as':
     25            raise template.TemplateSyntaxError(
     26                "First argument in '%s' must be 'as'" % tokens[0])
     27        if len(tokens) > 1:
     28            varname = tokens[2]
     29        else:
     30            varname = None
     31        return cls(varname, name)
     32
     33    @classmethod
     34    def handle_simple(cls, name):
     35        try:
     36            from django.conf import settings
     37        except ImportError:
     38            prefix = ''
     39        else:
     40            prefix = iri_to_uri(getattr(settings, name, ''))
     41        return prefix
     42
     43    def render(self, context):
     44        prefix = self.handle_simple(self.name)
     45        if self.varname is None:
     46            return prefix
     47        context[self.varname] = prefix
     48        return ''
     49
     50@register.tag
     51def get_static_prefix(parser, token):
     52    """
     53    Populates a template variable with the static prefix,
     54    ``settings.STATIC_URL``.
     55
     56    Usage::
     57
     58        {% get_static_prefix [as varname] %}
     59
     60    Examples::
     61
     62        {% get_static_prefix %}
     63        {% get_static_prefix as static_prefix %}
     64
     65    """
     66    return PrefixNode.handle_token(parser, token, "STATIC_URL")
     67
     68@register.tag
     69def get_media_prefix(parser, token):
     70    """
     71    Populates a template variable with the static prefix,
     72    ``settings.MEDIA_URL``.
     73
     74    Usage::
     75
     76        {% get_media_prefix [as varname] %}
     77
     78    Examples::
     79
     80        {% get_media_prefix %}
     81        {% get_media_prefix as media_prefix %}
     82
     83    """
     84    return PrefixNode.handle_token(parser, token, "MEDIA_URL")
  • django/views/static.py

    diff --git a/django/views/static.py b/django/views/static.py
    index a4a4c8d..2ce886f 100644
    a b from django.http import Http404, HttpResponse, HttpResponseRedirect, HttpRespons  
    1717from django.template import Template, Context, TemplateDoesNotExist
    1818from django.utils.http import http_date
    1919
    20 from django.contrib.staticfiles.views import \
    21     directory_index, was_modified_since, serve as staticfiles_serve
     20from django.contrib.staticfiles.views import (directory_index,
     21    was_modified_since, serve as staticfiles_serve)
    2222
    2323
    2424def serve(request, path, document_root=None, show_indexes=False, insecure=False):
  • docs/howto/static-files.txt

    diff --git a/docs/howto/static-files.txt b/docs/howto/static-files.txt
    index 37f1fc3..e27cb99 100644
    a b Here's the basic usage in a nutshell:  
    5050       First, you'll need to make sure that ``django.contrib.staticfiles`` is in
    5151       your :setting:`INSTALLED_APPS`.
    5252
    53        Next, you'll need to edit :setting:`STATICFILES_ROOT` to point to where
     53       Next, you'll need to edit :setting:`STATIC_ROOT` to point to where
    5454       you'd like your static media stored. For example::
    5555
    56             STATICFILES_ROOT = "/home/jacob/projects/mysite.com/static_media"
     56            STATIC_ROOT = "/home/jacob/projects/mysite.com/static_media"
    5757
    58        You may also want to set the :setting:`STATICFILES_URL` setting at this
     58       You may also want to set the :setting:`STATIC_URL` setting at this
    5959       time, though the default value (of ``/static/``) is perfect for local
    6060       development.
    6161
    Here's the basic usage in a nutshell:  
    6969            ./manage.py collectstatic
    7070
    7171       This'll churn through your static file storage and move them into the
    72        directory given by :setting:`STATICFILES_ROOT`. (This is not necessary
     72       directory given by :setting:`STATIC_ROOT`. (This is not necessary
    7373       in local development if you are using :djadmin:`runserver` or adding
    7474       ``staticfiles_urlpatterns`` to your URLconf; see below).
    7575
    Here's the basic usage in a nutshell:  
    7878       If you're using the built-in development server (the
    7979       :djadmin:`runserver` management command) and have the :setting:`DEBUG`
    8080       setting set to ``True``, your staticfiles will automatically be served
    81        from :setting:`STATICFILES_URL` in development.
     81       from :setting:`STATIC_URL` in development.
    8282
    8383       If you are using some other server for local development, you can
    8484       quickly serve static media locally by adding::
    Here's the basic usage in a nutshell:  
    9898
    9999          .. code-block:: html+django
    100100
    101                <img src="{{ STATICFILES_URL }}images/hi.jpg />
     101               <img src="{{ STATIC_URL }}images/hi.jpg />
    102102
    103103       See :ref:`staticfiles-in-templates` for more details, including an
    104104       alternate method (using a template tag).
    the framework see :doc:`the staticfiles reference </ref/contrib/staticfiles>`.  
    115115   app is to make it easier to keep static files separate from user-uploaded
    116116   files. For this reason, you will probably want to make your
    117117   :setting:`MEDIA_ROOT` and :setting:`MEDIA_URL` different from your
    118    :setting:`STATICFILES_ROOT` and :setting:`STATICFILES_URL`. You will need to
     118   :setting:`STATIC_ROOT` and :setting:`STATIC_URL`. You will need to
    119119   arrange for serving of files in :setting:`MEDIA_ROOT` yourself;
    120120   ``staticfiles`` does not deal with user-uploaded media at all.
    121121
    development, and it makes it *very* hard to change where you've deployed your  
    136136media. If, for example, you wanted to switch to using a content delivery network
    137137(CDN), then you'd need to change more or less every single template.
    138138
    139 A far better way is to use the value of the :setting:`STATICFILES_URL` setting
     139A far better way is to use the value of the :setting:`STATIC_URL` setting
    140140directly in your templates. This means that a switch of media servers only
    141141requires changing that single value. Much better!
    142142
    With a context processor  
    147147------------------------
    148148
    149149The included context processor is the easy way. Simply make sure
    150 ``'django.contrib.staticfiles.context_processors.staticfiles'`` is in your
     150``'django.core.context_processors.static'`` is in your
    151151:setting:`TEMPLATE_CONTEXT_PROCESSORS`. It's there by default, and if you're
    152152editing that setting by hand it should look something like::
    153153
    editing that setting by hand it should look something like::  
    155155        'django.core.context_processors.debug',
    156156        'django.core.context_processors.i18n',
    157157        'django.core.context_processors.media',
     158        'django.core.context_processors.static',
    158159        'django.contrib.auth.context_processors.auth',
    159160        'django.contrib.messages.context_processors.messages',
    160         'django.contrib.staticfiles.context_processors.staticfiles',
    161161    )
    162162
    163 Once that's done, you can refer to :setting:`STATICFILES_URL` in your templates:
     163Once that's done, you can refer to :setting:`STATIC_URL` in your templates:
    164164
    165165.. code-block:: html+django
    166166
    167      <img src="{{ STATICFILES_URL }}images/hi.jpg />
     167     <img src="{{ STATIC_URL }}images/hi.jpg />
    168168
    169 If ``{{ STATICFILES_URL }}`` isn't working in your template, you're probably not
     169If ``{{ STATIC_URL }}`` isn't working in your template, you're probably not
    170170using :class:`~django.template.RequestContext` when rendering the template.
    171171
    172172As a brief refresher, context processors add variables into the contexts of
    To see how that works, and to read more details, check out  
    180180With a template tag
    181181-------------------
    182182
    183 The second option is the :ttag:`get_staticfiles_prefix` template tag. You can
     183The second option is the :ttag:`get_static_prefix` template tag. You can
    184184use this if you're not using :class:`~django.template.RequestContext`, or if you
    185 need more control over exactly where and how :setting:`STATICFILES_URL` is
     185need more control over exactly where and how :setting:`STATIC_URL` is
    186186injected into the template. Here's an example:
    187187
    188188.. code-block:: html+django
    189189
    190     {% load staticfiles %}
    191     <img src="{% get_staticfiles_prefix %}images/hi.jpg" />
     190    {% load static %}
     191    <img src="{% get_static_prefix %}images/hi.jpg" />
    192192
    193193There's also a second form you can use to avoid extra processing if you need the
    194194value multiple times:
    195195
    196196.. code-block:: html+django
    197197
    198     {% load staticfiles %}
    199     {% get_staticfiles_prefix as STATIC_PREFIX %}
     198    {% load static %}
     199    {% get_static_prefix as STATIC_PREFIX %}
    200200
    201201    <img src="{{ STATIC_PREFIX }}images/hi.jpg" />
    202202    <img src="{{ STATIC_PREFIX }}images/hi2.jpg" />
    Thus, the ``staticfiles`` app ships with a quick and dirty helper view that you  
    213213can use to serve files locally in development.
    214214
    215215This view is automatically enabled and will serve your static files at
    216 :setting:`STATICFILES_URL` when you use the built-in :djadmin:`runserver`.
     216:setting:`STATIC_URL` when you use the built-in :djadmin:`runserver`.
    217217
    218218To enable this view if you are using some other server for local development,
    219219you'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::  
    225225
    226226    urlpatterns += staticfiles_urlpatterns()
    227227
    228 This will inspect your :setting:`STATICFILES_URL` and
    229 :setting:`STATICFILES_ROOT` settings and wire up the view to serve static media
     228This will inspect your :setting:`STATIC_URL` and
     229:setting:`STATIC_ROOT` settings and wire up the view to serve static media
    230230accordingly. Don't forget to set the :setting:`STATICFILES_DIRS` setting
    231231appropriately to let ``django.contrib.staticfiles`` know where to look for
    232 files.
     232(additional) files.
    233233
    234234.. warning::
    235235
    files.  
    239239    **insecure**. This is only intended for local development, and should
    240240    **never be used in production**.
    241241
     242    Additionally, your :setting:`STATIC_URL` setting can't be either empty
     243    or a full URL such as ``http://static.example.com/``.
     244
    242245For a few more details, including an alternate method of enabling this view,
    243246see :ref:`staticfiles-development-view`.
    244247
    Serving static files in production  
    249252
    250253The basic outline of putting static files into production is simple: run the
    251254:djadmin:`collectstatic` command when static media changes, then arrange for the
    252 collected media directory (:setting:`STATICFILES_ROOT`) to be moved to the media
     255collected media directory (:setting:`STATIC_ROOT`) to be moved to the media
    253256server and served.
    254257
    255258Of course, as with all deployment tasks, the devil's in the details. Every
    app, the basic outline gets modified to look something like:  
    264267
    265268    * Push your code up to the deployment server.
    266269    * On the server, run :djadmin:`collectstatic` to move all the media into
    267       :setting:`STATICFILES_ROOT`.
    268     * Point your web server at :setting:`STATICFILES_ROOT`. For example, here's
     270      :setting:`STATIC_ROOT`.
     271    * Point your web server at :setting:`STATIC_ROOT`. For example, here's
    269272      :ref:`how to do this under Apache and mod_wsgi <serving-media-files>`.
    270273
    271274You'll probably want to automate this process, especially if you've got multiple
    Since your media server won't be running Django, you'll need to modify the  
    322325deployment strategy to look something like:
    323326
    324327    * When your media changes, run :djadmin:`collectstatic` locally.
    325     * Push your local :setting:`STATICFILES_ROOT` up to the media server
     328    * Push your local :setting:`STATIC_ROOT` up to the media server
    326329      into the directory that's being served. ``rsync`` is a good
    327330      choice for this step since it only needs to transfer the
    328331      bits of static media that have changed.
    you'll need to make a few changes:  
    403406    * The management commands ``build_static`` and ``resolve_static`` are now
    404407      called :djadmin:`collectstatic` and :djadmin:`findstatic`.
    405408
    406     * The settings ``STATIC_URL`` and ``STATIC_ROOT`` were renamed to
    407       :setting:`STATICFILES_URL` and :setting:`STATICFILES_ROOT`.
    408 
    409409    * The settings ``STATICFILES_PREPEND_LABEL_APPS``,
    410410      ``STATICFILES_MEDIA_DIRNAMES`` and ``STATICFILES_EXCLUDED_APPS`` were
    411411      removed.
  • docs/man/django-admin.1

    diff --git a/docs/man/django-admin.1 b/docs/man/django-admin.1
    index 2197af6..f9b530a 100644
    a b Do not prompt the user for input.  
    165165Disable the development server's auto\-reloader.
    166166.TP
    167167.I \-\-nostatic
    168 Disable automatic serving of static files from STATICFILES_URL.
     168Disable automatic serving of static files from STATIC_URL.
    169169.TP
    170170.I \-\-insecure
    171171Enables serving of static files even if DEBUG is False.
  • docs/ref/contrib/staticfiles.txt

    diff --git a/docs/ref/contrib/staticfiles.txt b/docs/ref/contrib/staticfiles.txt
    index f82fd79..2cd2282 100644
    a b Settings  
    2323
    2424.. highlight:: python
    2525
    26 The following settings control the behavior of the staticfiles app. Only
    27 :setting:`STATICFILES_ROOT` is required, but you'll probably also need to
    28 configure :setting:`STATICFILES_URL` as well.
    29 
    30 .. setting:: STATICFILES_ROOT
    31 
    32 STATICFILES_ROOT
    33 ----------------
    34 
    35 Default: ``''`` (Empty string)
    36 
    37 The absolute path to the directory that the :djadmin:`collectstatic` management
    38 command will collect static files into, for serving from
    39 :setting:`STATICFILES_URL`::
    40 
    41    STATICFILES_ROOT = "/home/example.com/static/"
    42 
    43 This is a **required setting** unless you've overridden
    44 :setting:`STATICFILES_STORAGE` and are using a custom storage backend.
    45 
    46 This is not a place to store your static files permanently under version
    47 control; you should do that in directories that will be found by your
    48 :setting:`STATICFILES_FINDERS` (by default, per-app ``static/`` subdirectories,
    49 and any directories you include in :setting:`STATICFILES_DIRS`). Files from
    50 those locations will be collected into :setting:`STATICFILES_ROOT`.
    51 
    52 .. setting:: STATICFILES_URL
    53 
    54 STATICFILES_URL
    55 ---------------
    56 
    57 Default: ``'/static/'``
    58 
    59 The URL that handles the files served from :setting:`STATICFILES_ROOT`, e.g.::
    60 
    61     STATICFILES_URL = '/site_media/static/'
    62 
    63 ... or perhaps::
    64 
    65     STATICFILES_URL = 'http://static.example.com/'
     26.. note::
    6627
    67 This should **always** have a trailing slash.
     28    The following settings control the behavior of the staticfiles app.
     29    Configuring the global settings :setting:`STATIC_ROOT` and
     30    :setting:`STATIC_URL` is **required**.
    6831
    6932.. setting:: STATICFILES_DIRS
    7033
    tuples, e.g.::  
    9861
    9962With this configuration, the :djadmin:`collectstatic` management command would
    10063for example collect the stats files in a ``'downloads'`` directory. So
    101 assuming you have :setting:`STATICFILES_URL` set ``'/static/'``, this would
     64assuming you have :setting:`STATIC_URL` set ``'/static/'``, this would
    10265allow you to refer to the file ``'/opt/webfiles/stats/polls_20101022.tar.gz'``
    10366with ``'/static/downloads/polls_20101022.tar.gz'`` in your templates.
    10467
    Management Commands  
    153116
    154117.. highlight:: console
    155118
    156 ``django.contrib.staticfiles`` exposes two management commands.
     119``django.contrib.staticfiles`` exposes three management commands.
    157120
    158121collectstatic
    159122-------------
    160123
    161124.. django-admin:: collectstatic
    162125
    163 Collects the static files into :setting:`STATICFILES_ROOT`.
     126Collects the static files into :setting:`STATIC_ROOT`.
    164127
    165128Duplicate file names are by default resolved in a similar way to how template
    166129resolution works: the file that is first found in one of the specified
    for each relative path, use the ``--first`` option::  
    218181This is a debugging aid; it'll show you exactly which static file will be
    219182collected for a given path.
    220183
     184runserver
     185---------
     186
     187Overrides the core :djadmin:`runserver` command if the ``staticfiles`` app
     188is :setting:`installed<INSTALLED_APPS>` and adds automatic serving of static
     189files and the following new options.
     190
     191.. django-admin-option:: --nostatic
     192
     193Use the ``--nostatic`` option to disable serving of static files with the
     194:doc:`staticfiles </ref/contrib/staticfiles>` app entirely. This option is
     195only available if the :doc:`staticfiles </ref/contrib/staticfiles>` app is
     196in your project's :setting:`INSTALLED_APPS` setting.
     197
     198Example usage::
     199
     200    django-admin.py runserver --nostatic
     201
     202.. django-admin-option:: --insecure
     203
     204Use the ``--insecure`` option to force serving of static files with the
     205:doc:`staticfiles </ref/contrib/staticfiles>` app even if the :setting:`DEBUG`
     206setting is ``False``. By using this you acknowledge the fact that it's
     207**grossly inefficient** and probably **insecure**. This is only intended for
     208local development, should **never be used in production** and is only
     209available if the :doc:`staticfiles </ref/contrib/staticfiles>` app is
     210in your project's :setting:`INSTALLED_APPS` setting.
     211
     212Example usage::
     213
     214    django-admin.py runserver --insecure
     215
    221216.. currentmodule:: None
    222217
    223218Other Helpers
    224219=============
    225220
    226 The ``staticfiles`` context processor
    227 -------------------------------------
     221The ``static`` context processor
     222--------------------------------
    228223
    229 .. function:: django.contrib.staticfiles.context_processors.staticfiles
     224.. function:: django.core.context_processors.static
    230225
    231 This context processor adds the :setting:`STATICFILES_URL` into each template
    232 context as the variable ``{{ STATICFILES_URL }}``. To use it, make sure that
    233 ``'django.contrib.staticfiles.context_processors.staticfiles'`` appears
    234 somewhere in your :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting.
     226This context processor adds the :setting:`STATIC_URL` into each template
     227context as the variable ``{{ STATIC_URL }}``. To use it, make sure that
     228``'django.core.context_processors.static'`` appears somewhere in your
     229:setting:`TEMPLATE_CONTEXT_PROCESSORS` setting.
    235230
    236231Remember, only templates rendered with :class:`~django.template.RequestContext`
    237232will have acces to the data provided by this (and any) context processor.
    238233
    239 .. templatetag:: get_staticfiles_prefix
     234.. templatetag:: get_static_prefix
    240235
    241 The ``get_staticfiles_prefix`` templatetag
    242 ==========================================
     236The ``get_static_prefix`` templatetag
     237=====================================
    243238
    244239.. highlight:: html+django
    245240
    246241If you're not using :class:`~django.template.RequestContext`, or if you need
    247 more control over exactly where and how :setting:`STATICFILES_URL` is injected
    248 into the template, you can use the :ttag:`get_staticfiles_prefix` template tag
     242more control over exactly where and how :setting:`STATIC_URL` is injected
     243into the template, you can use the :ttag:`get_static_prefix` template tag
    249244instead::
    250245
    251     {% load staticfiles %}
    252     <img src="{% get_staticfiles_prefix %}images/hi.jpg" />
     246    {% load static %}
     247    <img src="{% get_static_prefix %}images/hi.jpg" />
    253248
    254249There's also a second form you can use to avoid extra processing if you need
    255250the value multiple times::
    256251
    257     {% load staticfiles %}
    258     {% get_staticfiles_prefix as STATIC_PREFIX %}
     252    {% load static %}
     253    {% get_static_prefix as STATIC_PREFIX %}
    259254
    260255    <img src="{{ STATIC_PREFIX }}images/hi.jpg" />
    261256    <img src="{{ STATIC_PREFIX }}images/hi2.jpg" />
    primary URL configuration::  
    292287       )
    293288
    294289Note, the begin of the pattern (``r'^static/'``) should be your
    295 :setting:`STATICFILES_URL` setting.
     290:setting:`STATIC_URL` setting.
    296291
    297292Since this is a bit finicky, there's also a helper function that'll do this for you:
    298293
    already defined pattern list. Use it like this::  
    307302
    308303   urlpatterns += staticfiles_urlpatterns()
    309304
     305.. warning::
     306
     307    This helper function will only work if :setting:`DEBUG` is ``True``
     308    and your :setting:`STATIC_URL` setting is neither empty nor a full
     309    URL such as ``http://static.example.com/``.
  • docs/ref/django-admin.txt

    diff --git a/docs/ref/django-admin.txt b/docs/ref/django-admin.txt
    index 43e55ac..ea49e23 100644
    a b Example usage::  
    681681
    682682    django-admin.py runserver --noreload
    683683
    684 .. django-admin-option:: --nostatic
    685 
    686 Use the ``--nostatic`` option to disable serving of static files with the
    687 :doc:`staticfiles </ref/contrib/staticfiles>` app entirely. This option is
    688 only available if the :doc:`staticfiles </ref/contrib/staticfiles>` app is
    689 in your project's :setting:`INSTALLED_APPS` setting.
    690 
    691 Example usage::
    692 
    693     django-admin.py runserver --nostatic
    694 
    695 .. django-admin-option:: --insecure
    696 
    697 Use the ``--insecure`` option to force serving of static files with the
    698 :doc:`staticfiles </ref/contrib/staticfiles>` app even if the :setting:`DEBUG`
    699 setting is ``False``. By using this you acknowledge the fact that it's
    700 **grossly inefficient** and probably **insecure**. This is only intended for
    701 local development, should **never be used in production** and is only
    702 available if the :doc:`staticfiles </ref/contrib/staticfiles>` app is
    703 in your project's :setting:`INSTALLED_APPS` setting.
    704 
    705 See the :doc:`reference documentation of the app </ref/contrib/staticfiles>`
    706 for more details and learn how to :doc:`manage and deploy static files
    707 </howto/static-files>` correctly.
    708 
    709 Example usage::
    710 
    711     django-admin.py runserver --insecure
    712 
    713684Examples of using different ports and addresses
    714685~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    715686
  • docs/ref/settings.txt

    diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt
    index 95e6861..7f4157c 100644
    a b Default: ``'/static/admin/'``  
    5353
    5454The URL prefix for admin media -- CSS, JavaScript and images used by the Django
    5555administrative interface. Make sure to use a trailing slash, and to have this be
    56 different from the :setting:``MEDIA_URL`` setting (since the same URL cannot be
     56different from the :setting:`MEDIA_URL` setting (since the same URL cannot be
    5757mapped onto two different sets of files). For integration with :doc:`staticfiles
    5858</ref/contrib/staticfiles>`, this should be the same as
    59 :setting:`STATICFILES_URL` followed by ``'admin/'``.
     59:setting:`STATIC_URL` followed by ``'admin/'``.
    6060
    6161.. setting:: ADMINS
    6262
    Default: ``''`` (Empty string)  
    11221122URL that handles the media served from :setting:`MEDIA_ROOT`, used
    11231123for :doc:`managing stored files </topics/files>`.
    11241124
    1125 Example: ``"http://media.lawrence.com"``
     1125Example: ``"http://media.lawrence.com/"``
    11261126
    11271127Note that this should have a trailing slash if it has a path component.
    11281128
    1129  * Good: ``"http://www.example.com/static/"``
    1130  * Bad: ``"http://www.example.com/static"``
     1129 * Good: ``"http://www.example.com/media/"``
     1130 * Bad: ``"http://www.example.com/media"``
    11311131
    11321132MESSAGE_LEVEL
    11331133-------------
    See :doc:`/ref/contrib/sites`.  
    14861486
    14871487.. _site framework docs: ../sites/
    14881488
     1489.. setting:: STATIC_ROOT
     1490
     1491STATIC_ROOT
     1492-----------
     1493
     1494Default: ``''`` (Empty string)
     1495
     1496The absolute path to the directory that contains static content.
     1497
     1498Example: ``"/home/example.com/static/"``
     1499
     1500When using the :djadmin:`collectstatic` management command of the optional,
     1501:doc:`staticfiles</ref/contrib/staticfiles>` app this will be used to collect
     1502static files into and served from :setting:`STATIC_URL`.
     1503
     1504In that case this is a **required setting**, unless you've overridden
     1505:setting:`STATICFILES_STORAGE` and are using a custom storage backend.
     1506
     1507This is not a place to store your static files permanently under version
     1508control; you should do that in directories that will be found by your
     1509:setting:`STATICFILES_FINDERS` (by default, per-app ``static/`` subdirectories,
     1510and any directories you include in :setting:`STATICFILES_DIRS`). Files from
     1511those locations will be collected into :setting:`STATIC_ROOT`.
     1512
     1513See :doc:`/ref/contrib/staticfiles` and :setting:`STATIC_URL`.
     1514
     1515.. setting:: STATIC_URL
     1516
     1517STATIC_URL
     1518----------
     1519
     1520Default: ``None``
     1521
     1522URL that handles the files served from :setting:`STATIC_ROOT`.
     1523
     1524Example: ``"/site_media/static/"`` or ``"http://static.example.com/"``
     1525
     1526If not ``None``, this will be used as the base path for
     1527:ref:`media definitions<form-media-paths>` and the
     1528:doc:`staticfiles app</ref/contrib/staticfiles>`.
     1529
     1530See :setting:`STATIC_ROOT`.
     1531
    14891532.. setting:: TEMPLATE_CONTEXT_PROCESSORS
    14901533
    14911534TEMPLATE_CONTEXT_PROCESSORS
    Default::  
    14961539    ("django.contrib.auth.context_processors.auth",
    14971540    "django.core.context_processors.debug",
    14981541    "django.core.context_processors.i18n",
    1499     "django.contrib.staticfiles.context_processors.staticfiles",
     1542    "django.core.context_processors.media",
     1543    "django.core.context_processors.static",
    15001544    "django.contrib.messages.context_processors.messages")
    15011545
    15021546A tuple of callables that are used to populate the context in ``RequestContext``.
    of items to be merged into the context.  
    15131557    ``django.core.context_processors.auth`` to
    15141558    ``django.contrib.auth.context_processors.auth``.
    15151559
     1560.. versionadded:: 1.3
     1561    The ``django.core.context_processors.static`` context processor
     1562    was added in this release.
     1563
    15161564.. setting:: TEMPLATE_DEBUG
    15171565
    15181566TEMPLATE_DEBUG
  • docs/ref/templates/api.txt

    diff --git a/docs/ref/templates/api.txt b/docs/ref/templates/api.txt
    index aa4951e..e02debe 100644
    a b and return a dictionary of items to be merged into the context. By default,  
    312312    "django.core.context_processors.debug",
    313313    "django.core.context_processors.i18n",
    314314    "django.core.context_processors.media",
    315     "django.contrib.messages.context_processors.messages",
    316     "django.contrib.staticfiles.context_processors.staticfiles")
     315    "django.core.context_processors.static",
     316    "django.contrib.messages.context_processors.messages")
    317317
    318318.. versionadded:: 1.2
    319319   In addition to these, ``RequestContext`` always uses
    If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every  
    435435``RequestContext`` will contain a variable ``MEDIA_URL``, providing the
    436436value of the :setting:`MEDIA_URL` setting.
    437437
     438django.core.context_processors.static
     439~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     440
     441.. versionadded:: 1.3
     442
     443If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every
     444``RequestContext`` will contain a variable ``STATIC_URL``, providing the
     445value of the :setting:`STATIC_URL` setting.
     446
    438447django.core.context_processors.csrf
    439448~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    440449
  • docs/releases/1.3-alpha-2.txt

    diff --git a/docs/releases/1.3-alpha-2.txt b/docs/releases/1.3-alpha-2.txt
    index 8a9bdca..c8671a6 100644
    a b prior to the final 1.3 release.  
    1313As such, this release is *not* intended for production use, and any such use
    1414is discouraged.
    1515
    16 .. _new features: `What's new in Django 1.3 alpha 2`_
    17 
    18 .. _backwards incompatible changes: backwards-incompatible-changes-1.3-alpha-2_
    19 
    2016What's new in Django 1.3 alpha 2
    2117================================
    2218
    See the :doc:`reference documentation of the app </ref/contrib/staticfiles>`  
    4339for more details or learn how to :doc:`manage static files
    4440</howto/static-files>`.
    4541
     42Backwards-incompatible changes in 1.3 alpha 2
     43=============================================
     44
     45Introduction of STATIC_URL and STATIC_ROOT settings
     46~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     47
     48The newly introduced :doc:`/ref/contrib/staticfiles` app extends Django's
     49abilities to handle static app and project files, required the additon of
     50settings to refer to those files in templates and code, especially in
     51contrast to the :setting:`MEDIA_URL` and :setting:`MEDIA_ROOT` settings that
     52refer to user-uploaded files.
     53
     54Prior to 1.3 alpha 2 these settings were called ``STATICFILES_URL`` and
     55``STATICFILES_ROOT`` to follow the naming scheme for app centric settings.
     56Based on feedback from the community it became apparent that those settings
     57created confusion, especially given the fact handling static files is also
     58desired outside the use of the optional ``staticfiles`` app.
     59
     60As a result, we take the followig steps to rectify the issue:
     61
     62  * Two new global settings that will be used by -- **but are not limited
     63    to** -- the :doc:`staticfiles</ref/contrib/staticfiles>` app:
     64
     65    * :setting:`STATIC_ROOT` (formally ``STATICFILES_ROOT``)
     66
     67    * :setting:`STATIC_URL` (formally ``STATICFILES_URL``)
     68
     69  * Moving the
     70    ``django.contrib.staticfiles.templatetags.staticfiles.get_staticfiles_prefix``
     71    template tag to the core (``django.templatetags.static``) and renaming
     72    it to :ttag:`get_static_prefix`.
     73
     74  * Moving the context processor
     75    ``django.contrib.staticfiles.context_processors.staticfiles`` to the
     76    core (``django.core.context_processors.static``) and renaming it to
     77    :func:`~django.core.context_processors.static`.
     78
     79  * :ref:`form-media-paths` will use :setting:`STATIC_URL` as the prefix
     80    **if the value is not None**, and falls back to the previously used
     81    :setting:`MEDIA_URL`.
     82
    4683The Django 1.3 roadmap
    4784======================
    4885
  • docs/releases/1.3.txt

    diff --git a/docs/releases/1.3.txt b/docs/releases/1.3.txt
    index 553fcc5..20c98f2 100644
    a b In previous versions of Django, it was common to place static assets in  
    5959app is to make it easier to keep static files separate from user-uploaded
    6060files. For this reason, you will probably want to make your
    6161:setting:`MEDIA_ROOT` and :setting:`MEDIA_URL` different from your
    62 :setting:`STATICFILES_ROOT` and :setting:`STATICFILES_URL`. You will need to
     62:setting:`STATIC_ROOT` and :setting:`STATIC_URL`. You will need to
    6363arrange for serving of files in :setting:`MEDIA_ROOT` yourself;
    6464``staticfiles`` does not deal with user-uploaded media at all.
    6565
  • docs/topics/forms/media.txt

    diff --git a/docs/topics/forms/media.txt b/docs/topics/forms/media.txt
    index 548095d..b0f3c86 100644
    a b also be defined in a dynamic fashion::  
    190190See the section on `Media objects`_ for more details on how to construct
    191191return values for dynamic media properties.
    192192
     193.. _form-media-paths:
     194
    193195Paths in media definitions
    194196--------------------------
    195197
     198.. versionchanged:: 1.3
     199
    196200Paths used to specify media can be either relative or absolute. If a path
    197201starts with '/', 'http://' or 'https://', it will be interpreted as an absolute
    198202path, and left as-is. All other paths will be prepended with the value of
    199 ``settings.MEDIA_URL``. For example, if the MEDIA_URL for your site was
    200 ``http://media.example.com/``::
     203the appropriate prefix.
     204
     205As part of the introduction of the
     206:doc:`staticfiles app </ref/contrib/staticfiles>` two new settings were added
     207to refer to "static content" (images, CSS, Javascript, etc.) that are needed
     208to render a complete web page: :setting:`STATIC_URL` and :setting:`STATIC_ROOT`.
     209
     210To find the appropriate prefix to use, Django will check if the
     211:setting:`STATIC_URL` setting is not ``None`` and automatically fall back
     212to using :setting:`MEDIA_URL`. For example, if the :setting:`MEDIA_URL` for
     213your site was ``'http://uploads.example.com/'`` and :setting:`STATIC_URL`
     214was ``None``::
     215
     216    >>> class CalendarWidget(forms.TextInput):
     217            class Media:
     218                css = {
     219                    'all': ('/css/pretty.css',),
     220                }
     221                js = ('animations.js', 'http://othersite.com/actions.js')
    201222
    202     class CalendarWidget(forms.TextInput):
    203         class Media:
    204             css = {
    205                 'all': ('/css/pretty.css',),
    206             }
    207             js = ('animations.js', 'http://othersite.com/actions.js')
     223    >>> w = CalendarWidget()
     224    >>> print w.media
     225    <link href="/css/pretty.css" type="text/css" media="all" rel="stylesheet" />
     226    <script type="text/javascript" src="http://uploads.example.com/animations.js"></script>
     227    <script type="text/javascript" src="http://othersite.com/actions.js"></script>
     228
     229But if :setting:`STATIC_URL` is ``'http://static.example.com/'``::
    208230
    209231    >>> w = CalendarWidget()
    210232    >>> print w.media
    211233    <link href="/css/pretty.css" type="text/css" media="all" rel="stylesheet" />
    212     <script type="text/javascript" src="http://media.example.com/animations.js"></script>
     234    <script type="text/javascript" src="http://static.example.com/animations.js"></script>
    213235    <script type="text/javascript" src="http://othersite.com/actions.js"></script>
    214236
     237
    215238Media objects
    216239-------------
    217240
  • tests/regressiontests/forms/tests/media.py

    diff --git a/tests/regressiontests/forms/tests/media.py b/tests/regressiontests/forms/tests/media.py
    index 9a552a3..fd30029 100644
    a b class FormsMediaTestCase(TestCase):  
    458458<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" />
    459459<link href="/path/to/css3" type="text/css" media="all" rel="stylesheet" />
    460460<link href="/some/form/css" type="text/css" media="all" rel="stylesheet" />""")
     461
     462
     463class StaticFormsMediaTestCase(TestCase):
     464    # Tests for the media handling on widgets and forms
     465    def setUp(self):
     466        super(StaticFormsMediaTestCase, self).setUp()
     467        self.original_media_url = settings.MEDIA_URL
     468        self.original_static_url = settings.STATIC_URL
     469        settings.MEDIA_URL = 'http://media.example.com/static/'
     470        settings.STATIC_URL = 'http://media.example.com/static/'
     471
     472    def tearDown(self):
     473        settings.MEDIA_URL = self.original_media_url
     474        settings.STATIC_URL = self.original_static_url
     475        super(StaticFormsMediaTestCase, self).tearDown()
     476
     477    def test_construction(self):
     478        # Check construction of media objects
     479        m = Media(css={'all': ('path/to/css1','/path/to/css2')}, js=('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3'))
     480        self.assertEqual(str(m), """<link href="http://media.example.com/static/path/to/css1" type="text/css" media="all" rel="stylesheet" />
     481<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" />
     482<script type="text/javascript" src="/path/to/js1"></script>
     483<script type="text/javascript" src="http://media.other.com/path/to/js2"></script>
     484<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script>""")
     485
     486        class Foo:
     487            css = {
     488               'all': ('path/to/css1','/path/to/css2')
     489            }
     490            js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3')
     491
     492        m3 = Media(Foo)
     493        self.assertEqual(str(m3), """<link href="http://media.example.com/static/path/to/css1" type="text/css" media="all" rel="stylesheet" />
     494<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" />
     495<script type="text/javascript" src="/path/to/js1"></script>
     496<script type="text/javascript" src="http://media.other.com/path/to/js2"></script>
     497<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script>""")
     498
     499        # A widget can exist without a media definition
     500        class MyWidget(TextInput):
     501            pass
     502
     503        w = MyWidget()
     504        self.assertEqual(str(w.media), '')
     505
     506    def test_media_dsl(self):
     507        ###############################################################
     508        # DSL Class-based media definitions
     509        ###############################################################
     510
     511        # A widget can define media if it needs to.
     512        # Any absolute path will be preserved; relative paths are combined
     513        # with the value of settings.MEDIA_URL
     514        class MyWidget1(TextInput):
     515            class Media:
     516                css = {
     517                   'all': ('path/to/css1','/path/to/css2')
     518                }
     519                js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3')
     520
     521        w1 = MyWidget1()
     522        self.assertEqual(str(w1.media), """<link href="http://media.example.com/static/path/to/css1" type="text/css" media="all" rel="stylesheet" />
     523<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" />
     524<script type="text/javascript" src="/path/to/js1"></script>
     525<script type="text/javascript" src="http://media.other.com/path/to/js2"></script>
     526<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script>""")
     527
     528        # Media objects can be interrogated by media type
     529        self.assertEqual(str(w1.media['css']), """<link href="http://media.example.com/static/path/to/css1" type="text/css" media="all" rel="stylesheet" />
     530<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" />""")
     531
     532        self.assertEqual(str(w1.media['js']), """<script type="text/javascript" src="/path/to/js1"></script>
     533<script type="text/javascript" src="http://media.other.com/path/to/js2"></script>
     534<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script>""")
     535
     536    def test_combine_media(self):
     537        # Media objects can be combined. Any given media resource will appear only
     538        # once. Duplicated media definitions are ignored.
     539        class MyWidget1(TextInput):
     540            class Media:
     541                css = {
     542                   'all': ('path/to/css1','/path/to/css2')
     543                }
     544                js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3')
     545
     546        class MyWidget2(TextInput):
     547            class Media:
     548                css = {
     549                   'all': ('/path/to/css2','/path/to/css3')
     550                }
     551                js = ('/path/to/js1','/path/to/js4')
     552
     553        class MyWidget3(TextInput):
     554            class Media:
     555                css = {
     556                   'all': ('/path/to/css3','path/to/css1')
     557                }
     558                js = ('/path/to/js1','/path/to/js4')
     559
     560        w1 = MyWidget1()
     561        w2 = MyWidget2()
     562        w3 = MyWidget3()
     563        self.assertEqual(str(w1.media + w2.media + w3.media), """<link href="http://media.example.com/static/path/to/css1" type="text/css" media="all" rel="stylesheet" />
     564<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" />
     565<link href="/path/to/css3" type="text/css" media="all" rel="stylesheet" />
     566<script type="text/javascript" src="/path/to/js1"></script>
     567<script type="text/javascript" src="http://media.other.com/path/to/js2"></script>
     568<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script>
     569<script type="text/javascript" src="/path/to/js4"></script>""")
     570
     571        # Check that media addition hasn't affected the original objects
     572        self.assertEqual(str(w1.media), """<link href="http://media.example.com/static/path/to/css1" type="text/css" media="all" rel="stylesheet" />
     573<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" />
     574<script type="text/javascript" src="/path/to/js1"></script>
     575<script type="text/javascript" src="http://media.other.com/path/to/js2"></script>
     576<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script>""")
     577
     578        # Regression check for #12879: specifying the same CSS or JS file
     579        # multiple times in a single Media instance should result in that file
     580        # only being included once.
     581        class MyWidget4(TextInput):
     582            class Media:
     583                css = {'all': ('/path/to/css1', '/path/to/css1')}
     584                js = ('/path/to/js1', '/path/to/js1')
     585
     586        w4 = MyWidget4()
     587        self.assertEqual(str(w4.media), """<link href="/path/to/css1" type="text/css" media="all" rel="stylesheet" />
     588<script type="text/javascript" src="/path/to/js1"></script>""")
     589
     590    def test_media_property(self):
     591        ###############################################################
     592        # Property-based media definitions
     593        ###############################################################
     594
     595        # Widget media can be defined as a property
     596        class MyWidget4(TextInput):
     597            def _media(self):
     598                return Media(css={'all': ('/some/path',)}, js = ('/some/js',))
     599            media = property(_media)
     600
     601        w4 = MyWidget4()
     602        self.assertEqual(str(w4.media), """<link href="/some/path" type="text/css" media="all" rel="stylesheet" />
     603<script type="text/javascript" src="/some/js"></script>""")
     604
     605        # Media properties can reference the media of their parents
     606        class MyWidget5(MyWidget4):
     607            def _media(self):
     608                return super(MyWidget5, self).media + Media(css={'all': ('/other/path',)}, js = ('/other/js',))
     609            media = property(_media)
     610
     611        w5 = MyWidget5()
     612        self.assertEqual(str(w5.media), """<link href="/some/path" type="text/css" media="all" rel="stylesheet" />
     613<link href="/other/path" type="text/css" media="all" rel="stylesheet" />
     614<script type="text/javascript" src="/some/js"></script>
     615<script type="text/javascript" src="/other/js"></script>""")
     616
     617    def test_media_property_parent_references(self):
     618        # Media properties can reference the media of their parents,
     619        # even if the parent media was defined using a class
     620        class MyWidget1(TextInput):
     621            class Media:
     622                css = {
     623                   'all': ('path/to/css1','/path/to/css2')
     624                }
     625                js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3')
     626
     627        class MyWidget6(MyWidget1):
     628            def _media(self):
     629                return super(MyWidget6, self).media + Media(css={'all': ('/other/path',)}, js = ('/other/js',))
     630            media = property(_media)
     631
     632        w6 = MyWidget6()
     633        self.assertEqual(str(w6.media), """<link href="http://media.example.com/static/path/to/css1" type="text/css" media="all" rel="stylesheet" />
     634<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" />
     635<link href="/other/path" type="text/css" media="all" rel="stylesheet" />
     636<script type="text/javascript" src="/path/to/js1"></script>
     637<script type="text/javascript" src="http://media.other.com/path/to/js2"></script>
     638<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script>
     639<script type="text/javascript" src="/other/js"></script>""")
     640
     641    def test_media_inheritance(self):
     642        ###############################################################
     643        # Inheritance of media
     644        ###############################################################
     645
     646        # If a widget extends another but provides no media definition, it inherits the parent widget's media
     647        class MyWidget1(TextInput):
     648            class Media:
     649                css = {
     650                   'all': ('path/to/css1','/path/to/css2')
     651                }
     652                js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3')
     653
     654        class MyWidget7(MyWidget1):
     655            pass
     656
     657        w7 = MyWidget7()
     658        self.assertEqual(str(w7.media), """<link href="http://media.example.com/static/path/to/css1" type="text/css" media="all" rel="stylesheet" />
     659<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" />
     660<script type="text/javascript" src="/path/to/js1"></script>
     661<script type="text/javascript" src="http://media.other.com/path/to/js2"></script>
     662<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script>""")
     663
     664        # If a widget extends another but defines media, it extends the parent widget's media by default
     665        class MyWidget8(MyWidget1):
     666            class Media:
     667                css = {
     668                   'all': ('/path/to/css3','path/to/css1')
     669                }
     670                js = ('/path/to/js1','/path/to/js4')
     671
     672        w8 = MyWidget8()
     673        self.assertEqual(str(w8.media), """<link href="http://media.example.com/static/path/to/css1" type="text/css" media="all" rel="stylesheet" />
     674<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" />
     675<link href="/path/to/css3" type="text/css" media="all" rel="stylesheet" />
     676<script type="text/javascript" src="/path/to/js1"></script>
     677<script type="text/javascript" src="http://media.other.com/path/to/js2"></script>
     678<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script>
     679<script type="text/javascript" src="/path/to/js4"></script>""")
     680
     681    def test_media_inheritance_from_property(self):
     682        # If a widget extends another but defines media, it extends the parents widget's media,
     683        # even if the parent defined media using a property.
     684        class MyWidget1(TextInput):
     685            class Media:
     686                css = {
     687                   'all': ('path/to/css1','/path/to/css2')
     688                }
     689                js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3')
     690
     691        class MyWidget4(TextInput):
     692            def _media(self):
     693                return Media(css={'all': ('/some/path',)}, js = ('/some/js',))
     694            media = property(_media)
     695
     696        class MyWidget9(MyWidget4):
     697            class Media:
     698                css = {
     699                    'all': ('/other/path',)
     700                }
     701                js = ('/other/js',)
     702
     703        w9 = MyWidget9()
     704        self.assertEqual(str(w9.media), """<link href="/some/path" type="text/css" media="all" rel="stylesheet" />
     705<link href="/other/path" type="text/css" media="all" rel="stylesheet" />
     706<script type="text/javascript" src="/some/js"></script>
     707<script type="text/javascript" src="/other/js"></script>""")
     708
     709        # A widget can disable media inheritance by specifying 'extend=False'
     710        class MyWidget10(MyWidget1):
     711            class Media:
     712                extend = False
     713                css = {
     714                   'all': ('/path/to/css3','path/to/css1')
     715                }
     716                js = ('/path/to/js1','/path/to/js4')
     717
     718        w10 = MyWidget10()
     719        self.assertEqual(str(w10.media), """<link href="/path/to/css3" type="text/css" media="all" rel="stylesheet" />
     720<link href="http://media.example.com/static/path/to/css1" type="text/css" media="all" rel="stylesheet" />
     721<script type="text/javascript" src="/path/to/js1"></script>
     722<script type="text/javascript" src="/path/to/js4"></script>""")
     723
     724    def test_media_inheritance_extends(self):
     725        # A widget can explicitly enable full media inheritance by specifying 'extend=True'
     726        class MyWidget1(TextInput):
     727            class Media:
     728                css = {
     729                   'all': ('path/to/css1','/path/to/css2')
     730                }
     731                js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3')
     732
     733        class MyWidget11(MyWidget1):
     734            class Media:
     735                extend = True
     736                css = {
     737                   'all': ('/path/to/css3','path/to/css1')
     738                }
     739                js = ('/path/to/js1','/path/to/js4')
     740
     741        w11 = MyWidget11()
     742        self.assertEqual(str(w11.media), """<link href="http://media.example.com/static/path/to/css1" type="text/css" media="all" rel="stylesheet" />
     743<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" />
     744<link href="/path/to/css3" type="text/css" media="all" rel="stylesheet" />
     745<script type="text/javascript" src="/path/to/js1"></script>
     746<script type="text/javascript" src="http://media.other.com/path/to/js2"></script>
     747<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script>
     748<script type="text/javascript" src="/path/to/js4"></script>""")
     749
     750    def test_media_inheritance_single_type(self):
     751        # A widget can enable inheritance of one media type by specifying extend as a tuple
     752        class MyWidget1(TextInput):
     753            class Media:
     754                css = {
     755                   'all': ('path/to/css1','/path/to/css2')
     756                }
     757                js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3')
     758
     759        class MyWidget12(MyWidget1):
     760            class Media:
     761                extend = ('css',)
     762                css = {
     763                   'all': ('/path/to/css3','path/to/css1')
     764                }
     765                js = ('/path/to/js1','/path/to/js4')
     766
     767        w12 = MyWidget12()
     768        self.assertEqual(str(w12.media), """<link href="http://media.example.com/static/path/to/css1" type="text/css" media="all" rel="stylesheet" />
     769<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" />
     770<link href="/path/to/css3" type="text/css" media="all" rel="stylesheet" />
     771<script type="text/javascript" src="/path/to/js1"></script>
     772<script type="text/javascript" src="/path/to/js4"></script>""")
     773
     774    def test_multi_media(self):
     775        ###############################################################
     776        # Multi-media handling for CSS
     777        ###############################################################
     778
     779        # A widget can define CSS media for multiple output media types
     780        class MultimediaWidget(TextInput):
     781            class Media:
     782                css = {
     783                   'screen, print': ('/file1','/file2'),
     784                   'screen': ('/file3',),
     785                   'print': ('/file4',)
     786                }
     787                js = ('/path/to/js1','/path/to/js4')
     788
     789        multimedia = MultimediaWidget()
     790        self.assertEqual(str(multimedia.media), """<link href="/file4" type="text/css" media="print" rel="stylesheet" />
     791<link href="/file3" type="text/css" media="screen" rel="stylesheet" />
     792<link href="/file1" type="text/css" media="screen, print" rel="stylesheet" />
     793<link href="/file2" type="text/css" media="screen, print" rel="stylesheet" />
     794<script type="text/javascript" src="/path/to/js1"></script>
     795<script type="text/javascript" src="/path/to/js4"></script>""")
     796
     797    def test_multi_widget(self):
     798        ###############################################################
     799        # Multiwidget media handling
     800        ###############################################################
     801
     802        class MyWidget1(TextInput):
     803            class Media:
     804                css = {
     805                   'all': ('path/to/css1','/path/to/css2')
     806                }
     807                js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3')
     808
     809        class MyWidget2(TextInput):
     810            class Media:
     811                css = {
     812                   'all': ('/path/to/css2','/path/to/css3')
     813                }
     814                js = ('/path/to/js1','/path/to/js4')
     815
     816        class MyWidget3(TextInput):
     817            class Media:
     818                css = {
     819                   'all': ('/path/to/css3','path/to/css1')
     820                }
     821                js = ('/path/to/js1','/path/to/js4')
     822
     823        # MultiWidgets have a default media definition that gets all the
     824        # media from the component widgets
     825        class MyMultiWidget(MultiWidget):
     826            def __init__(self, attrs=None):
     827                widgets = [MyWidget1, MyWidget2, MyWidget3]
     828                super(MyMultiWidget, self).__init__(widgets, attrs)
     829
     830        mymulti = MyMultiWidget()
     831        self.assertEqual(str(mymulti.media), """<link href="http://media.example.com/static/path/to/css1" type="text/css" media="all" rel="stylesheet" />
     832<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" />
     833<link href="/path/to/css3" type="text/css" media="all" rel="stylesheet" />
     834<script type="text/javascript" src="/path/to/js1"></script>
     835<script type="text/javascript" src="http://media.other.com/path/to/js2"></script>
     836<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script>
     837<script type="text/javascript" src="/path/to/js4"></script>""")
     838
     839    def test_form_media(self):
     840        ###############################################################
     841        # Media processing for forms
     842        ###############################################################
     843
     844        class MyWidget1(TextInput):
     845            class Media:
     846                css = {
     847                   'all': ('path/to/css1','/path/to/css2')
     848                }
     849                js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3')
     850
     851        class MyWidget2(TextInput):
     852            class Media:
     853                css = {
     854                   'all': ('/path/to/css2','/path/to/css3')
     855                }
     856                js = ('/path/to/js1','/path/to/js4')
     857
     858        class MyWidget3(TextInput):
     859            class Media:
     860                css = {
     861                   'all': ('/path/to/css3','path/to/css1')
     862                }
     863                js = ('/path/to/js1','/path/to/js4')
     864
     865        # You can ask a form for the media required by its widgets.
     866        class MyForm(Form):
     867            field1 = CharField(max_length=20, widget=MyWidget1())
     868            field2 = CharField(max_length=20, widget=MyWidget2())
     869        f1 = MyForm()
     870        self.assertEqual(str(f1.media), """<link href="http://media.example.com/static/path/to/css1" type="text/css" media="all" rel="stylesheet" />
     871<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" />
     872<link href="/path/to/css3" type="text/css" media="all" rel="stylesheet" />
     873<script type="text/javascript" src="/path/to/js1"></script>
     874<script type="text/javascript" src="http://media.other.com/path/to/js2"></script>
     875<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script>
     876<script type="text/javascript" src="/path/to/js4"></script>""")
     877
     878        # Form media can be combined to produce a single media definition.
     879        class AnotherForm(Form):
     880            field3 = CharField(max_length=20, widget=MyWidget3())
     881        f2 = AnotherForm()
     882        self.assertEqual(str(f1.media + f2.media), """<link href="http://media.example.com/static/path/to/css1" type="text/css" media="all" rel="stylesheet" />
     883<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" />
     884<link href="/path/to/css3" type="text/css" media="all" rel="stylesheet" />
     885<script type="text/javascript" src="/path/to/js1"></script>
     886<script type="text/javascript" src="http://media.other.com/path/to/js2"></script>
     887<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script>
     888<script type="text/javascript" src="/path/to/js4"></script>""")
     889
     890        # Forms can also define media, following the same rules as widgets.
     891        class FormWithMedia(Form):
     892            field1 = CharField(max_length=20, widget=MyWidget1())
     893            field2 = CharField(max_length=20, widget=MyWidget2())
     894            class Media:
     895                js = ('/some/form/javascript',)
     896                css = {
     897                    'all': ('/some/form/css',)
     898                }
     899        f3 = FormWithMedia()
     900        self.assertEqual(str(f3.media), """<link href="http://media.example.com/static/path/to/css1" type="text/css" media="all" rel="stylesheet" />
     901<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" />
     902<link href="/path/to/css3" type="text/css" media="all" rel="stylesheet" />
     903<link href="/some/form/css" type="text/css" media="all" rel="stylesheet" />
     904<script type="text/javascript" src="/path/to/js1"></script>
     905<script type="text/javascript" src="http://media.other.com/path/to/js2"></script>
     906<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script>
     907<script type="text/javascript" src="/path/to/js4"></script>
     908<script type="text/javascript" src="/some/form/javascript"></script>""")
     909
     910        # Media works in templates
     911        from django.template import Template, Context
     912        self.assertEqual(Template("{{ form.media.js }}{{ form.media.css }}").render(Context({'form': f3})), """<script type="text/javascript" src="/path/to/js1"></script>
     913<script type="text/javascript" src="http://media.other.com/path/to/js2"></script>
     914<script type="text/javascript" src="https://secure.other.com/path/to/js3"></script>
     915<script type="text/javascript" src="/path/to/js4"></script>
     916<script type="text/javascript" src="/some/form/javascript"></script><link href="http://media.example.com/static/path/to/css1" type="text/css" media="all" rel="stylesheet" />
     917<link href="/path/to/css2" type="text/css" media="all" rel="stylesheet" />
     918<link href="/path/to/css3" type="text/css" media="all" rel="stylesheet" />
     919<link href="/some/form/css" type="text/css" media="all" rel="stylesheet" />""")
     920
  • tests/regressiontests/staticfiles_tests/tests.py

    diff --git a/tests/regressiontests/staticfiles_tests/tests.py b/tests/regressiontests/staticfiles_tests/tests.py
    index 0a6c060..6cd581f 100644
    a b class StaticFilesTestCase(TestCase):  
    2323    Test case with a couple utility assertions.
    2424    """
    2525    def setUp(self):
    26         self.old_staticfiles_url = settings.STATICFILES_URL
    27         self.old_staticfiles_root = settings.STATICFILES_ROOT
     26        self.old_static_url = settings.STATIC_URL
     27        self.old_static_root = settings.STATIC_ROOT
    2828        self.old_staticfiles_dirs = settings.STATICFILES_DIRS
    2929        self.old_staticfiles_finders = settings.STATICFILES_FINDERS
    3030        self.old_media_root = settings.MEDIA_ROOT
    class StaticFilesTestCase(TestCase):  
    4040        settings.DEBUG = True
    4141        settings.MEDIA_ROOT =  os.path.join(site_media, 'media')
    4242        settings.MEDIA_URL = '/media/'
    43         settings.STATICFILES_ROOT = os.path.join(site_media, 'static')
    44         settings.STATICFILES_URL = '/static/'
     43        settings.STATIC_ROOT = os.path.join(site_media, 'static')
     44        settings.STATIC_URL = '/static/'
    4545        settings.ADMIN_MEDIA_PREFIX = '/static/admin/'
    4646        settings.STATICFILES_DIRS = (
    4747            os.path.join(TEST_ROOT, 'project', 'documents'),
    class StaticFilesTestCase(TestCase):  
    5252            'django.contrib.staticfiles.finders.DefaultStorageFinder',
    5353        )
    5454        settings.INSTALLED_APPS = [
     55            "django.contrib.staticfiles",
    5556            "regressiontests.staticfiles_tests",
    5657        ]
    5758
    class StaticFilesTestCase(TestCase):  
    6566        settings.MEDIA_ROOT = self.old_media_root
    6667        settings.MEDIA_URL = self.old_media_url
    6768        settings.ADMIN_MEDIA_PREFIX = self.old_admin_media_prefix
    68         settings.STATICFILES_ROOT = self.old_staticfiles_root
    69         settings.STATICFILES_URL = self.old_staticfiles_url
     69        settings.STATIC_ROOT = self.old_static_root
     70        settings.STATIC_URL = self.old_static_url
    7071        settings.STATICFILES_DIRS = self.old_staticfiles_dirs
    7172        settings.STATICFILES_FINDERS = self.old_staticfiles_finders
    7273        settings.INSTALLED_APPS = self.old_installed_apps
    class BuildStaticTestCase(StaticFilesTestCase):  
    9192    def setUp(self):
    9293        super(BuildStaticTestCase, self).setUp()
    9394        self.old_staticfiles_storage = settings.STATICFILES_STORAGE
    94         self.old_root = settings.STATICFILES_ROOT
    95         settings.STATICFILES_ROOT = tempfile.mkdtemp()
     95        self.old_root = settings.STATIC_ROOT
     96        settings.STATIC_ROOT = tempfile.mkdtemp()
    9697        self.run_collectstatic()
    9798
    9899    def tearDown(self):
    99         shutil.rmtree(settings.STATICFILES_ROOT)
    100         settings.STATICFILES_ROOT = self.old_root
     100        shutil.rmtree(settings.STATIC_ROOT)
     101        settings.STATIC_ROOT = self.old_root
    101102        super(BuildStaticTestCase, self).tearDown()
    102103
    103104    def run_collectstatic(self, **kwargs):
    class BuildStaticTestCase(StaticFilesTestCase):  
    106107
    107108    def _get_file(self, filepath):
    108109        assert filepath, 'filepath is empty.'
    109         filepath = os.path.join(settings.STATICFILES_ROOT, filepath)
     110        filepath = os.path.join(settings.STATIC_ROOT, filepath)
    110111        f = open(filepath)
    111112        try:
    112113            return f.read()
    class TestBuildStaticDryRun(BuildStaticTestCase):  
    231232        """
    232233        With --dry-run, no files created in destination dir.
    233234        """
    234         self.assertEquals(os.listdir(settings.STATICFILES_ROOT), [])
     235        self.assertEquals(os.listdir(settings.STATIC_ROOT), [])
    235236
    236237
    237238if sys.platform != 'win32':
    if sys.platform != 'win32':  
    251252            With ``--link``, symbolic links are created.
    252253
    253254            """
    254             self.failUnless(os.path.islink(os.path.join(settings.STATICFILES_ROOT, 'test.txt')))
     255            self.failUnless(os.path.islink(os.path.join(settings.STATIC_ROOT, 'test.txt')))
    255256
    256257
    257258class TestServeStatic(StaticFilesTestCase):
    class TestServeStatic(StaticFilesTestCase):  
    262263
    263264    def _response(self, filepath):
    264265        return self.client.get(
    265             posixpath.join(settings.STATICFILES_URL, filepath))
     266            posixpath.join(settings.STATIC_URL, filepath))
    266267
    267268    def assertFileContains(self, filepath, text):
    268269        self.assertContains(self._response(filepath), text)
    class TestMiscFinder(TestCase):  
    372373            finders.get_finder, "django.contrib.staticfiles.finders.FooBarFinder")
    373374        self.assertRaises(ImproperlyConfigured,
    374375            finders.get_finder, "foo.bar.FooBarFinder")
    375 
    376 
    377 class TemplateTagTest(TestCase):
    378     def test_get_staticfiles_prefix(self):
    379         """
    380         Test the get_staticfiles_prefix helper return the STATICFILES_URL setting.
    381         """
    382         self.assertEquals(Template(
    383             "{% load staticfiles %}"
    384             "{% get_staticfiles_prefix %}"
    385         ).render(Context()), settings.STATICFILES_URL)
    386 
    387     def test_get_staticfiles_prefix_with_as(self):
    388         """
    389         Test the get_staticfiles_prefix helper return the STATICFILES_URL setting.
    390         """
    391         self.assertEquals(Template(
    392             "{% load staticfiles %}"
    393             "{% get_staticfiles_prefix as staticfiles_prefix %}"
    394             "{{ staticfiles_prefix }}"
    395         ).render(Context()), settings.STATICFILES_URL)
  • tests/regressiontests/templates/tests.py

    diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
    index 29171eb..ea93beb 100644
    a b class UTF8Class:  
    114114        return u'ŠĐĆŽćžšđ'.encode('utf-8')
    115115
    116116class Templates(unittest.TestCase):
     117    def setUp(self):
     118        self.old_static_url = settings.STATIC_URL
     119        self.old_media_url = settings.MEDIA_URL
     120        settings.STATIC_URL = u"/static/"
     121        settings.MEDIA_URL = u"/media/"
     122
     123    def tearDown(self):
     124        settings.STATIC_URL = self.old_static_url
     125        settings.MEDIA_URL = self.old_media_url
     126
    117127    def test_loaders_security(self):
    118128        ad_loader = app_directories.Loader()
    119129        fs_loader = filesystem.Loader()
    class Templates(unittest.TestCase):  
    13281338            'autoescape-filtertag01': ("{{ first }}{% filter safe %}{{ first }} x<y{% endfilter %}", {"first": "<a>"}, template.TemplateSyntaxError),
    13291339
    13301340            # ifqeual compares unescaped vales.
    1331             'autoescape-ifequal01': ('{% ifequal var "this & that" %}yes{% endifequal %}', { "var": "this & that" }, "yes" ),
     1341            'autoescape-ifequal01': ('{% ifequal var "this & that" %}yes{% endifequal %}', { "var": "this & that" }, "yes"),
    13321342
    13331343            # Arguments to filters are 'safe' and manipulate their input unescaped.
    13341344            'autoescape-filters01': ('{{ var|cut:"&" }}', { "var": "this & that" }, "this  that" ),
    1335             'autoescape-filters02': ('{{ var|join:" & \" }}', { "var": ("Tom", "Dick", "Harry") }, "Tom & Dick & Harry" ),
     1345            'autoescape-filters02': ('{{ var|join:" & \" }}', { "var": ("Tom", "Dick", "Harry") }, "Tom & Dick & Harry"),
    13361346
    13371347            # Literal strings are safe.
    1338             'autoescape-literals01': ('{{ "this & that" }}',{}, "this & that" ),
     1348            'autoescape-literals01': ('{{ "this & that" }}',{}, "this & that"),
    13391349
    13401350            # Iterating over strings outputs safe characters.
    1341             'autoescape-stringiterations01': ('{% for l in var %}{{ l }},{% endfor %}', {'var': 'K&R'}, "K,&amp;,R," ),
     1351            'autoescape-stringiterations01': ('{% for l in var %}{{ l }},{% endfor %}', {'var': 'K&R'}, "K,&amp;,R,"),
    13421352
    13431353            # Escape requirement survives lookup.
    1344             'autoescape-lookup01': ('{{ var.key }}', { "var": {"key": "this & that" }}, "this &amp; that" ),
     1354            'autoescape-lookup01': ('{{ var.key }}', { "var": {"key": "this & that" }}, "this &amp; that"),
    13451355
     1356            # Static template tags
     1357            'static-prefixtag01': ('{% load static %}{% get_static_prefix %}', {}, settings.STATIC_URL),
     1358            'static-prefixtag02': ('{% load static %}{% get_static_prefix as static_prefix %}{{ static_prefix }}', {}, settings.STATIC_URL),
     1359            'static-prefixtag03': ('{% load static %}{% get_media_prefix %}', {}, settings.MEDIA_URL),
     1360            'static-prefixtag04': ('{% load static %}{% get_media_prefix as media_prefix %}{{ media_prefix }}', {}, settings.MEDIA_URL),
    13461361        }
    13471362
    1348 
    13491363class TemplateTagLoading(unittest.TestCase):
    13501364
    13511365    def setUp(self):
Back to Top