Commit e9f3899b authored by Jannis Leidel's avatar Jannis Leidel
Browse files

Refactored runserver command and moved code related to staticfiles to a...

Refactored runserver command and moved code related to staticfiles to a subclass that is enabled if staticfiles app is installed.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@14553 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent 1ed62706
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
from optparse import make_option

from django.conf import settings
from django.core.management.commands.runserver import BaseRunserverCommand

from django.contrib.staticfiles.handlers import StaticFilesHandler

class Command(BaseRunserverCommand):
    option_list = BaseRunserverCommand.option_list + (
        make_option('--nostatic', action="store_false", dest='use_static_handler', default=True,
            help='Tells Django to NOT automatically serve static files at STATICFILES_URL.'),
        make_option('--insecure', action="store_true", dest='insecure_serving', default=False,
            help='Allows serving static files even if DEBUG is False.'),
    )
    help = "Starts a lightweight Web server for development, including static files serving."

    def get_handler(self, *args, **options):
        """
        Returns the static files serving handler.
        """
        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
+83 −68
Original line number Diff line number Diff line
from optparse import make_option
import os
import sys
import warnings

from django.core.management.base import BaseCommand, CommandError
from django.core.handlers.wsgi import WSGIHandler
from django.core.servers.basehttp import AdminMediaHandler, run, WSGIServerException
from django.utils import autoreload

class Command(BaseCommand):
class BaseRunserverCommand(BaseCommand):
    option_list = BaseCommand.option_list + (
        make_option('--noreload', action='store_false', dest='use_reloader', default=True,
            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 False.'),
        make_option('--adminmedia', dest='admin_media_path', default='',
            help='Specifies the directory from which to serve admin media.'),
    )
    help = "Starts a lightweight Web server for development."
    args = '[optional port number, or ipaddr:port]'
@@ -22,58 +18,70 @@ class Command(BaseCommand):
    # Validation is called explicitly each time the server is reloaded.
    requires_model_validation = False

    def get_handler(self, *args, **options):
        """
        Returns the default WSGI handler for the runner.
        """
        return WSGIHandler()

    def handle(self, addrport='', *args, **options):
        import django
        from django.core.servers.basehttp import run, AdminMediaHandler, WSGIServerException
        from django.core.handlers.wsgi import WSGIHandler
        from django.contrib.staticfiles.handlers import StaticFilesHandler
        if args:
            raise CommandError('Usage is runserver %s' % self.args)
        if not addrport:
            addr = ''
            port = '8000'
            self.addr = ''
            self.port = '8000'
        else:
            try:
                addr, port = addrport.split(':')
                self.addr, self.port = addrport.split(':')
            except ValueError:
                addr, port = '', addrport
        if not addr:
            addr = '127.0.0.1'
                self.addr, self.port = '', addrport
        if not self.addr:
            self.addr = '127.0.0.1'

        if not port.isdigit():
            raise CommandError("%r is not a valid port number." % port)
        if not self.port.isdigit():
            raise CommandError("%r is not a valid port number." % self.port)

        self.run(*args, **options)

    def run(self, *args, **options):
        """
        Runs the server, using the autoreloader if needed
        """
        use_reloader = options.get('use_reloader', True)
        admin_media_path = options.get('admin_media_path', '')
        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'

        def inner_run():
        if use_reloader:
            autoreload.main(self.inner_run, args, options)
        else:
            self.inner_run(*args, **options)

    def inner_run(self, *args, **options):
        from django.conf import settings
        from django.utils import translation
            print "Validating models..."
            self.validate(display_num_errors=True)
            print "\nDjango version %s, using settings %r" % (django.get_version(), settings.SETTINGS_MODULE)
            print "Development server is running at http://%s:%s/" % (addr, port)
            print "Quit the server with %s." % quit_command

        shutdown_message = options.get('shutdown_message', '')
        quit_command = (sys.platform == 'win32') and 'CTRL-BREAK' or 'CONTROL-C'

        self.stdout.write("Validating models...\n\n")
        self.validate(display_num_errors=True)
        self.stdout.write((
            "Django version %(version)s, using settings %(settings)r\n"
            "Development server is running at http://%(addr)s:%(port)s/\n"
            "Quit the server with %(quit_command)s.\n"
        ) % {
            "version": self.get_version(),
            "settings": settings.SETTINGS_MODULE,
            "addr": self.addr,
            "port": self.port,
            "quit_command": quit_command,
        })
        # django.core.management.base forces the locale to en-us. We should
        # set it up correctly for the first request (particularly important
        # in the "--noreload" case).
        translation.activate(settings.LANGUAGE_CODE)

        try:
                handler = WSGIHandler()
                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)
                handler = AdminMediaHandler(handler, admin_media_path)
                run(addr, int(port), handler)
            handler = self.get_handler(*args, **options)
            run(self.addr, int(self.port), handler)
        except WSGIServerException, e:
            # Use helpful error messages instead of ugly tracebacks.
            ERRORS = {
@@ -90,11 +98,18 @@ class Command(BaseCommand):
            os._exit(1)
        except KeyboardInterrupt:
            if shutdown_message:
                    print shutdown_message
                self.stdout.write("%s\n" % shutdown_message)
            sys.exit(0)

        if use_reloader:
            from django.utils import autoreload
            autoreload.main(inner_run)
        else:
            inner_run()
class Command(BaseRunserverCommand):
    option_list = BaseRunserverCommand.option_list + (
        make_option('--adminmedia', dest='admin_media_path', default='',
            help='Specifies the directory from which to serve admin media.'),
    )

    def get_handler(self, *args, **options):
        """
        Serves admin media like old-school (deprecation pending).
        """
        handler = super(Command, self).get_handler(*args, **options)
        return AdminMediaHandler(handler, options.get('admin_media_path', ''))
+6 −0
Original line number Diff line number Diff line
@@ -164,6 +164,12 @@ Do not prompt the user for input.
.I \-\-noreload
Disable the development server's auto\-reloader.
.TP
.I \-\-nostatic
Disable automatic serving of static files from STATICFILES_URL.
.TP
.I \-\-insecure
Enables serving of static files even if DEBUG is False.
.TP
.I \-\-verbosity=VERBOSITY
Verbosity level: 0=minimal output, 1=normal output, 2=all output.
.TP
+6 −2
Original line number Diff line number Diff line
@@ -684,7 +684,9 @@ Example usage::
.. django-admin-option:: --nostatic

Use the ``--nostatic`` option to disable serving of static files with the
:doc:`staticfiles </ref/contrib/staticfiles>` app entirely.
:doc:`staticfiles </ref/contrib/staticfiles>` app entirely. This option is
only available if the :doc:`staticfiles </ref/contrib/staticfiles>` app is
in your project's :setting:`INSTALLED_APPS` setting.

Example usage::

@@ -696,7 +698,9 @@ 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 acknowledge the fact that it's
**grossly inefficient** and probably **insecure**. This is only intended for
local development, and should **never be used in production**.
local development, should **never be used in production** and is only
available if the :doc:`staticfiles </ref/contrib/staticfiles>` app is
in your project's :setting:`INSTALLED_APPS` setting.

See the :doc:`reference documentation of the app </ref/contrib/staticfiles>`
for more details and learn how to :doc:`manage and deploy static files