123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- from optparse import make_option
- import os
- import re
- import sys
- import socket
- from django.core.management.base import BaseCommand, CommandError
- from django.core.servers.basehttp import run, WSGIServerException, get_internal_wsgi_application
- from django.utils import autoreload
- naiveip_re = re.compile(r"""^(?:
- (?P<addr>
- (?P<ipv4>\d{1,3}(?:\.\d{1,3}){3}) | # IPv4 address
- (?P<ipv6>\[[a-fA-F0-9:]+\]) | # IPv6 address
- (?P<fqdn>[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*) # FQDN
- ):)?(?P<port>\d+)$""", re.X)
- DEFAULT_PORT = "8000"
- class Command(BaseCommand):
- option_list = BaseCommand.option_list + (
- make_option('--ipv6', '-6', action='store_true', dest='use_ipv6', default=False,
- help='Tells Django to use a IPv6 address.'),
- make_option('--nothreading', action='store_false', dest='use_threading', default=True,
- help='Tells Django to NOT use threading.'),
- make_option('--noreload', action='store_false', dest='use_reloader', default=True,
- help='Tells Django to NOT use the auto-reloader.'),
- )
- help = "Starts a lightweight Web server for development."
- args = '[optional port number, or ipaddr:port]'
- # 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 get_internal_wsgi_application()
- def handle(self, addrport='', *args, **options):
- self.use_ipv6 = options.get('use_ipv6')
- if self.use_ipv6 and not socket.has_ipv6:
- raise CommandError('Your Python does not support IPv6.')
- if args:
- raise CommandError('Usage is runserver %s' % self.args)
- self._raw_ipv6 = False
- if not addrport:
- self.addr = ''
- self.port = DEFAULT_PORT
- else:
- m = re.match(naiveip_re, addrport)
- if m is None:
- raise CommandError('"%s" is not a valid port number '
- 'or address:port pair.' % addrport)
- self.addr, _ipv4, _ipv6, _fqdn, self.port = m.groups()
- if not self.port.isdigit():
- raise CommandError("%r is not a valid port number." % self.port)
- if self.addr:
- if _ipv6:
- self.addr = self.addr[1:-1]
- self.use_ipv6 = True
- self._raw_ipv6 = True
- elif self.use_ipv6 and not _fqdn:
- raise CommandError('"%s" is not a valid IPv6 address.' % self.addr)
- if not self.addr:
- self.addr = self.use_ipv6 and '::1' or '127.0.0.1'
- self._raw_ipv6 = bool(self.use_ipv6)
- self.run(*args, **options)
- def run(self, *args, **options):
- """
- Runs the server, using the autoreloader if needed
- """
- use_reloader = options.get('use_reloader')
- 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
- threading = options.get('use_threading')
- 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._raw_ipv6 and '[%s]' % self.addr or 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 = self.get_handler(*args, **options)
- run(self.addr, int(self.port), handler,
- ipv6=self.use_ipv6, threading=threading)
- 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:
- self.stdout.write("%s\n" % shutdown_message)
- sys.exit(0)
- # Kept for backward compatibility
- BaseRunserverCommand = Command
|