diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py
index 7b7531a..73d180c 100644
--- a/django/conf/global_settings.py
+++ b/django/conf/global_settings.py
@@ -412,6 +412,11 @@ DEFAULT_INDEX_TABLESPACE = ''
 # Default X-Frame-Options header value
 X_FRAME_OPTIONS = 'SAMEORIGIN'
 
+# The import name of the WSGI application. If this is `None` the default
+# 'django.core.handlers.wsgi.application' is used. Otherwise this shall
+# point to an actual WSGI application.
+WSGI_APPLICATION = None
+
 ##############
 # MIDDLEWARE #
 ##############
diff --git a/django/conf/project_template/settings.py b/django/conf/project_template/settings.py
index 3a2243f..59a2d22 100644
--- a/django/conf/project_template/settings.py
+++ b/django/conf/project_template/settings.py
@@ -99,6 +99,9 @@ MIDDLEWARE_CLASSES = (
 
 ROOT_URLCONF = '{{ project_name }}.urls'
 
+# The WSGI application used by Django's runserver etc.
+WSGI_APPLICATION = '{{ project_name }}.wsgi.application'
+
 TEMPLATE_DIRS = (
     # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
     # Always use forward slashes, even on Windows.
diff --git a/django/conf/project_template/wsgi.py b/django/conf/project_template/wsgi.py
new file mode 100644
index 0000000..7e37f60
--- /dev/null
+++ b/django/conf/project_template/wsgi.py
@@ -0,0 +1,25 @@
+"""
+WSGI config for {{ project_name }} project.
+
+This module contains the actual WSGI application to be used by Django's
+development server and the production environment as the global variable
+named ``application`` and is enabled by setting the ``WSGI_APPLICATION``
+setting to '{{ project_name }}.wsgi.application'.
+
+Of course usually you would have an actual Django WSGI application here,
+but it also might make sense to replace the whole Django WSGI application
+with a custom one that later delegates to the Django one (for instance if
+you want to combine a Django application with an application of another
+framework).
+"""
+from django.core.management import setup_settings
+
+settings = setup_settings(__name__)
+
+# The application object is used by the development server
+# as well as a WSGI server configured to use this file.
+from django.core.handlers.wsgi import application
+
+# Apply other WSGI middlewares here.
+# from helloworld.wsgi import HelloWorldApplication
+# application = HelloWorldApplication(application)
diff --git a/django/contrib/staticfiles/handlers.py b/django/contrib/staticfiles/handlers.py
index 962b835..d9f6833 100644
--- a/django/contrib/staticfiles/handlers.py
+++ b/django/contrib/staticfiles/handlers.py
@@ -12,7 +12,9 @@ class StaticFilesHandler(WSGIHandler):
     WSGI middleware that intercepts calls to the static files directory, as
     defined by the STATIC_URL setting, and serves those files.
     """
-    def __init__(self, application, base_dir=None):
+    def __init__(self, application, base_dir=None, enabled=True):
+        # If not enabled this directly proxies to the given application.
+        self.enabled = enabled
         self.application = application
         if base_dir:
             self.base_dir = base_dir
@@ -63,6 +65,6 @@ class StaticFilesHandler(WSGIHandler):
         return super(StaticFilesHandler, self).get_response(request)
 
     def __call__(self, environ, start_response):
-        if not self._should_handle(environ['PATH_INFO']):
-            return self.application(environ, start_response)
-        return super(StaticFilesHandler, self).__call__(environ, start_response)
+        if self.enabled and self._should_handle(environ['PATH_INFO']):
+            return super(StaticFilesHandler, self).__call__(environ, start_response)
+        return self.application(environ, start_response)
diff --git a/django/contrib/staticfiles/management/commands/runserver.py b/django/contrib/staticfiles/management/commands/runserver.py
index c6e56d2..d4e332c 100644
--- a/django/contrib/staticfiles/management/commands/runserver.py
+++ b/django/contrib/staticfiles/management/commands/runserver.py
@@ -21,7 +21,5 @@ class Command(BaseRunserverCommand):
         handler = super(Command, self).get_handler(*args, **options)
         use_static_handler = options.get('use_static_handler', True)
         insecure_serving = options.get('insecure_serving', False)
-        if (settings.DEBUG and use_static_handler or
-                (use_static_handler and insecure_serving)):
-            handler = StaticFilesHandler(handler)
-        return handler
+        enabled = use_static_handler and (settings.DEBUG or insecure_serving)
+        return StaticFilesHandler(handler, enabled=enabled)
diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py
index a6c8044..5364e65 100644
--- a/django/core/handlers/base.py
+++ b/django/core/handlers/base.py
@@ -242,8 +242,8 @@ def get_script_name(environ):
     Returns the equivalent of the HTTP request's SCRIPT_NAME environment
     variable. If Apache mod_rewrite has been used, returns what would have been
     the script name prior to any rewriting (so it's the script name as seen
-    from the client's perspective), unless DJANGO_USE_POST_REWRITE is set (to
-    anything).
+    from the client's perspective), unless the FORCE_SCRIPT_NAME setting is
+    set (to anything).
     """
     from django.conf import settings
     if settings.FORCE_SCRIPT_NAME is not None:
diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py
index 56d2ba6..a4e1aa7 100644
--- a/django/core/handlers/wsgi.py
+++ b/django/core/handlers/wsgi.py
@@ -1,3 +1,63 @@
+"""
+WSGI entrypoints
+
+Overview
+--------
+
+The motivation behind this module is to expose the WSGI application that
+exists in Django to the actual Django user project. The idea is that you
+have a documented way to apply WSGI middlewares that are then being used by
+both the internal WSGI development server as well as any other WSGI server
+in production.
+
+The way it works is that there are a handful of WSGI application objects:
+
+-   django.core.handlers.wsgi.WSGIHandler: this is the implementation of the
+    actual Django WSGI dispatcher and it should be considered an
+    implementation detail. While users are free to subclass and extend it,
+    it's not necessarily supported.
+-   django.core.handlers.wsgi.application: this is the documented WSGI
+    application which is used by default.
+-   django.core.handlers.wsgi.django_application: this is the actual WSGI
+    application that is passed to the servers. It's internally proxying to
+    the configured WSGI application and will most likely be a (decorated)
+    version of the `application`.
+
+The reason why we have multiple applications here is because of the
+ability to apply middlewares.  Basically `application` is the WSGI
+application without any middlewarse applied, `django_application` is a
+proxy to the base application + all applied middlewares.
+
+The middlewares are added according to the WSGI_APPLICATION configuration
+setting which points to a module that imports the `application` as
+`application` and can apply middlewares.
+
+If the WSGI_APPLICATION setting is ``None`` (which is the case for upgraded
+applications from before we had exposed WSGI support) instead of the regular
+application, the `application` is used.
+
+The WSGI_APPLICATION
+--------------------
+
+The WSGI_APPLICATION configuration setting points to an actual WSGI
+application.  By default the project generator will configure that a file
+called `projectname.wsgi` exists and contains a global variable named
+`application`. The contents look like this::
+
+    from django.core.handlers.wsgi import application
+
+This can be used to apply WSGI middlewares::
+
+    from helloworld.wsgi import HelloWorldApplication
+    application = HelloWorldApplication(application)
+
+Of course usually you would have an actual Django WSGI application there, but
+it also might make sense to replace the whole Django WSGI application with
+a custom one that later delegates to the Django one (for instance if you
+want to combine a Django application with an application of another framework).
+
+"""
+from __future__ import with_statement
 import sys
 from threading import Lock
 try:
@@ -7,10 +67,12 @@ except ImportError:
 
 from django import http
 from django.core import signals
+from django.core.exceptions import ImproperlyConfigured
 from django.core.handlers import base
 from django.core.urlresolvers import set_script_prefix
 from django.utils import datastructures
 from django.utils.encoding import force_unicode, iri_to_uri
+from django.utils.importlib import import_module
 from django.utils.log import getLogger
 
 logger = getLogger('django.request')
@@ -190,13 +252,12 @@ class WSGIRequest(http.HttpRequest):
     FILES = property(_get_files)
     REQUEST = property(_get_request)
 
+
 class WSGIHandler(base.BaseHandler):
     initLock = Lock()
     request_class = WSGIRequest
 
     def __call__(self, environ, start_response):
-        from django.conf import settings
-
         # Set up middleware if needed. We couldn't do this earlier, because
         # settings weren't available.
         if self._request_middleware is None:
@@ -242,3 +303,39 @@ class WSGIHandler(base.BaseHandler):
         start_response(status, response_headers)
         return response
 
+application = WSGIHandler()
+
+
+class DjangoWSGIApplication(object):
+    """
+    Implements a proxy to the actual WSGI application as configured
+    by the user in settings.WSGI_APPLICATION which will usually be the
+    `application`, optionally with middlewares applied.
+    """
+    def __init__(self):
+        self._instance = None
+        self._instance_lock = Lock()
+
+    def _load_application(self):
+        from django.conf import settings
+        app_path = getattr(settings, 'WSGI_APPLICATION')
+        if app_path is None:
+            return application
+        try:
+            module_name, attr = app_path.rsplit('.', 1)
+            return getattr(import_module(module_name), attr)
+        except (ImportError, AttributeError), e:
+            raise ImproperlyConfigured("WSGI application '%s' could not "
+                                       "be loaded: %s" % (app_path, e))
+
+    def __call__(self, environ, start_response):
+        # Non-atomic check, avoids taking a lock at each call of this method
+        if self._instance is None:
+            with self._instance_lock:
+                # Atomic check, prevents concurrent initialization of self._instance
+                if self._instance is None
+                    self._instance = self._load_application()
+        return self._instance(environ, start_response)
+
+# the proxy used in deployment
+django_application = DjangoWSGIApplication()
diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py
index 1345eaf..d4b51cc 100644
--- a/django/core/management/__init__.py
+++ b/django/core/management/__init__.py
@@ -392,10 +392,10 @@ def setup_environ(settings_mod, original_settings_path=None):
     # way. For example, if this file (manage.py) lives in a directory
     # "myproject", this code would add "/path/to/myproject" to sys.path.
     if '__init__.py' in settings_mod.__file__:
-        p = os.path.dirname(settings_mod.__file__)
+        path = os.path.dirname(settings_mod.__file__)
     else:
-        p = settings_mod.__file__
-    project_directory, settings_filename = os.path.split(p)
+        path = settings_mod.__file__
+    project_directory, settings_filename = os.path.split(path)
     if project_directory == os.curdir or not project_directory:
         project_directory = os.getcwd()
     project_name = os.path.basename(project_directory)
@@ -425,6 +425,42 @@ def setup_environ(settings_mod, original_settings_path=None):
 
     return project_directory
 
+
+def setup_settings(path):
+    """
+    Configures the settings first by looking at the environment variable
+    DJANGO_SETTINGS_MODULE or if that fail tries to find it with the
+    given module path.
+
+    Example:
+
+    from django.core.management import setup_settings
+
+    setup_settings(__name__)
+    setup_settings('wsgi')
+    setup_settings('mysite.wsgi')
+    """
+    try:
+        # Check if DJANGO_SETTINGS_MODULE is already given
+        settings_module = os.environ['DJANGO_SETTINGS_MODULE']
+        if not settings_module:
+            raise KeyError
+        settings = import_module(settings_module)
+    except KeyError:
+        # Or try importing the settings module two levels up,
+        # so if name is 'mysite.wsgi', it'll try 'mysite.settings'
+        try:
+            settings = import_module('settings', path)
+        except ImportError:
+            # two levels up because name contains the submodule
+            settings = import_module('..settings', path)
+    setup_environ(settings)
+
+    # Return the settings module
+    from django.conf import settings
+    return settings
+
+
 def execute_from_command_line(argv=None):
     """
     A simple method that runs a ManagementUtility.
diff --git a/django/core/management/commands/runserver.py b/django/core/management/commands/runserver.py
index 2e693e7..c84bf30 100644
--- a/django/core/management/commands/runserver.py
+++ b/django/core/management/commands/runserver.py
@@ -5,7 +5,7 @@ import sys
 import socket
 
 from django.core.management.base import BaseCommand, CommandError
-from django.core.handlers.wsgi import WSGIHandler
+from django.core.handlers.wsgi import django_application
 from django.core.servers.basehttp import AdminMediaHandler, run, WSGIServerException
 from django.utils import autoreload
 
@@ -37,7 +37,7 @@ class BaseRunserverCommand(BaseCommand):
         """
         Returns the default WSGI handler for the runner.
         """
-        return WSGIHandler()
+        return django_application
 
     def handle(self, addrport='', *args, **options):
         self.use_ipv6 = options.get('use_ipv6')
diff --git a/django/core/servers/fastcgi.py b/django/core/servers/fastcgi.py
index 9f80d2b..442df44 100644
--- a/django/core/servers/fastcgi.py
+++ b/django/core/servers/fastcgi.py
@@ -139,7 +139,7 @@ def runfastcgi(argset=[], **kwargs):
         return False
 
     # Prep up and go
-    from django.core.handlers.wsgi import WSGIHandler
+    from django.core.handlers.wsgi import django_application
 
     if options["host"] and options["port"] and not options["socket"]:
         wsgi_opts['bindAddress'] = (options["host"], int(options["port"]))
@@ -178,7 +178,7 @@ def runfastcgi(argset=[], **kwargs):
         fp.write("%d\n" % os.getpid())
         fp.close()
 
-    WSGIServer(WSGIHandler(), **wsgi_opts).run()
+    WSGIServer(django_application, **wsgi_opts).run()
 
 if __name__ == '__main__':
     runfastcgi(sys.argv[1:])
diff --git a/docs/howto/deployment/modwsgi.txt b/docs/howto/deployment/modwsgi.txt
index de3a5b6..90d7ba3 100644
--- a/docs/howto/deployment/modwsgi.txt
+++ b/docs/howto/deployment/modwsgi.txt
@@ -24,26 +24,28 @@ the details about how to use mod_wsgi. You'll probably want to start with the
 Basic configuration
 ===================
 
-Once you've got mod_wsgi installed and activated, edit your ``httpd.conf`` file
-and add::
+Once you've got mod_wsgi installed and activated, edit your ``httpd.conf``
+file and add::
 
-    WSGIScriptAlias / /path/to/mysite/apache/django.wsgi
+    WSGIScriptAlias / /path/to/mysite/wsgi.py
 
-The first bit above is the url you want to be serving your application at (``/``
-indicates the root url), and the second is the location of a "WSGI file" -- see
-below -- on your system, usually inside of your project. This tells Apache
-to serve any request below the given URL using the WSGI application defined by that file.
+The first bit above is the url you want to be serving your application at
+(``/`` indicates the root url), and the second is the location of a "WSGI
+file" -- see below -- on your system, usually inside of your project. This
+tells Apache to serve any request below the given URL using the WSGI
+application defined by that file.
 
 Next we'll need to actually create this WSGI application, so create the file
 mentioned in the second part of ``WSGIScriptAlias`` and add::
 
-    import os
     import sys
+    from django.core.management import setup_settings
 
-    os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
+    setup_settings(__name__)
 
-    import django.core.handlers.wsgi
-    application = django.core.handlers.wsgi.WSGIHandler()
+    # The application object is used by the development server
+    # as well as a WSGI server configured to use this file.
+    from django.core.handlers.wsgi import application
 
 If your project is not on your ``PYTHONPATH`` by default you can add::
 
@@ -51,9 +53,9 @@ If your project is not on your ``PYTHONPATH`` by default you can add::
     if path not in sys.path:
         sys.path.append(path)
 
-just below the ``import sys`` line to place your project on the path. Remember to
-replace 'mysite.settings' with your correct settings file, and '/path/to/mysite'
-with your own project's location.
+just below the ``import sys`` line to place your project on the path.
+Remember to replace 'mysite.settings' with your correct settings file,
+and ``'/path/to/mysite'`` with your own project's location.
 
 .. _serving-files:
 
diff --git a/docs/howto/deployment/uwsgi.txt b/docs/howto/deployment/uwsgi.txt
index 11cb51c..d3e631e 100644
--- a/docs/howto/deployment/uwsgi.txt
+++ b/docs/howto/deployment/uwsgi.txt
@@ -112,7 +112,7 @@ Starting the server
 Example command line for a Web server that understand the uWSGI protocol::
 
     uwsgi --chdir=/path/to/your/project
-        --module='django.core.handlers.wsgi:WSGIHandler()' \
+        --module='wsgi:application' \
         --env DJANGO_SETTINGS_MODULE=settings \
         --master --pidfile=/tmp/project-master.pid \
         --socket=127.0.0.1:49152 \      # can also be a file
@@ -128,7 +128,8 @@ Example command line for a Web server that understand the uWSGI protocol::
 Django specific options are:
 
 * ``chdir``: should be the path to your project
-* ``module``: uwsgi module to use
+* ``module``: WSGI module to use, probably the ``wsgi`` module which
+  :djadmin:`startproject` creates.
 * ``pythonpath``: optional path to your project virtualenv
 * ``env``: should contain at least ``DJANGO_SETTINGS_MODULE``
 
