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