Author: jezdez
Date: 2010-11-13 12:41:55 -0600 (Sat, 13 Nov 2010)
New Revision: 14553

Added:
   django/trunk/django/contrib/staticfiles/management/commands/runserver.py
Modified:
   django/trunk/django/core/management/commands/runserver.py
   django/trunk/docs/man/django-admin.1
   django/trunk/docs/ref/django-admin.txt
Log:
Refactored runserver command and moved code related to staticfiles to a 
subclass that is enabled if staticfiles app is installed.

Added: django/trunk/django/contrib/staticfiles/management/commands/runserver.py
===================================================================
--- django/trunk/django/contrib/staticfiles/management/commands/runserver.py    
                        (rev 0)
+++ django/trunk/django/contrib/staticfiles/management/commands/runserver.py    
2010-11-13 18:41:55 UTC (rev 14553)
@@ -0,0 +1,27 @@
+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

Modified: django/trunk/django/core/management/commands/runserver.py
===================================================================
--- django/trunk/django/core/management/commands/runserver.py   2010-11-13 
18:41:24 UTC (rev 14552)
+++ django/trunk/django/core/management/commands/runserver.py   2010-11-13 
18:41:55 UTC (rev 14553)
@@ -1,20 +1,16 @@
 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,79 +18,98 @@
     # 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', '')
+
+        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
+
         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():
-            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
+        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)
 
-            # 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 = self.get_handler(*args, **options)
+            run(self.addr, int(self.port), handler)
+        except WSGIServerException, e:
+            # Use helpful error messages instead of ugly tracebacks.
+            ERRORS = {
+                13: "You don't have permission to access that port.",
+                98: "That port is already in use.",
+                99: "That IP address can't be assigned-to.",
+            }
             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)
-            except WSGIServerException, e:
-                # Use helpful error messages instead of ugly tracebacks.
-                ERRORS = {
-                    13: "You don't have permission to access that port.",
-                    98: "That port is already in use.",
-                    99: "That IP address can't be assigned-to.",
-                }
-                try:
-                    error_text = ERRORS[e.args[0].args[0]]
-                except (AttributeError, KeyError):
-                    error_text = str(e)
-                sys.stderr.write(self.style.ERROR("Error: %s" % error_text) + 
'\n')
-                # Need to use an OS exit because sys.exit doesn't work in a 
thread
-                os._exit(1)
-            except KeyboardInterrupt:
-                if shutdown_message:
-                    print shutdown_message
-                sys.exit(0)
+                error_text = ERRORS[e.args[0].args[0]]
+            except (AttributeError, KeyError):
+                error_text = str(e)
+            sys.stderr.write(self.style.ERROR("Error: %s" % error_text) + '\n')
+            # Need to use an OS exit because sys.exit doesn't work in a thread
+            os._exit(1)
+        except KeyboardInterrupt:
+            if 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', ''))

Modified: django/trunk/docs/man/django-admin.1
===================================================================
--- django/trunk/docs/man/django-admin.1        2010-11-13 18:41:24 UTC (rev 
14552)
+++ django/trunk/docs/man/django-admin.1        2010-11-13 18:41:55 UTC (rev 
14553)
@@ -164,6 +164,12 @@
 .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

Modified: django/trunk/docs/ref/django-admin.txt
===================================================================
--- django/trunk/docs/ref/django-admin.txt      2010-11-13 18:41:24 UTC (rev 
14552)
+++ django/trunk/docs/ref/django-admin.txt      2010-11-13 18:41:55 UTC (rev 
14553)
@@ -684,7 +684,9 @@
 .. 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 @@
 :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

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-upda...@googlegroups.com.
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to