11from django .core .management .base import BaseCommand , CommandError
22from optparse import make_option
33import os
4+ import socket
45import sys
6+ import re
7+
8+ naiveip_re = r'^(?:(?P<addr>\d{1,3}(?:\.\d{1,3}){3}|\[[a-fA-F0-9:]+\]):)?(?P<port>\d+)$'
9+ DEFAULT_PORT = "8000"
510
611class Command (BaseCommand ):
712 option_list = BaseCommand .option_list + (
13+ make_option ('--ipv6' , '-6' , action = 'store_true' , dest = 'enable_ipv6' , default = False ,
14+ help = 'Force the use of IPv6 address.' ),
815 make_option ('--noreload' , action = 'store_false' , dest = 'use_reloader' , default = True ,
916 help = 'Tells Django to NOT use the auto-reloader.' ),
1017 make_option ('--adminmedia' , dest = 'admin_media_path' , default = '' ,
@@ -20,21 +27,32 @@ def handle(self, addrport='', *args, **options):
2027 import django
2128 from django .core .servers .basehttp import run , AdminMediaHandler , WSGIServerException
2229 from django .core .handlers .wsgi import WSGIHandler
30+ enable_ipv6 = options .get ('enable_ipv6' )
31+ if enable_ipv6 and not hasattr (socket , 'AF_INET6' ):
32+ raise CommandError ("Your Python does not support IPv6." )
33+
2334 if args :
2435 raise CommandError ('Usage is runserver %s' % self .args )
2536 if not addrport :
2637 addr = ''
27- port = '8000'
38+ port = DEFAULT_PORT
2839 else :
29- try :
30- addr , port = addrport .split (':' )
31- except ValueError :
32- addr , port = '' , addrport
33- if not addr :
34- addr = '127.0.0.1'
35-
40+ m = re .match (naiveip_re , addrport )
41+ if m is None :
42+ raise CommandError ("%r is not a valid port number or address:port pair." % addrport )
43+ addr , port = m .groups ()
44+
3645 if not port .isdigit ():
3746 raise CommandError ("%r is not a valid port number." % port )
47+ if addr :
48+ if addr [0 ] == '[' and addr [- 1 ] == ']' :
49+ enable_ipv6 = True
50+ addr = addr [1 :- 1 ]
51+ elif enable_ipv6 :
52+ raise CommandError ("IPv6 addresses must be surrounded with brackets" )
53+ if not addr :
54+ addr = '127.0.0.1'
55+ addr = (enable_ipv6 and '::1' ) or '127.0.0.1'
3856
3957 use_reloader = options .get ('use_reloader' , True )
4058 admin_media_path = options .get ('admin_media_path' , '' )
@@ -47,7 +65,8 @@ def inner_run():
4765 print "Validating models..."
4866 self .validate (display_num_errors = True )
4967 print "\n Django version %s, using settings %r" % (django .get_version (), settings .SETTINGS_MODULE )
50- print "Development server is running at http://%s:%s/" % (addr , port )
68+ fmt_addr = (enable_ipv6 and '[%s]' % addr ) or addr
69+ print "Development server is running at http://%s:%s/" % (fmt_addr , port )
5170 print "Quit the server with %s." % quit_command
5271
5372 # django.core.management.base forces the locale to en-us. We should
@@ -57,7 +76,7 @@ def inner_run():
5776
5877 try :
5978 handler = AdminMediaHandler (WSGIHandler (), admin_media_path )
60- run (addr , int (port ), handler )
79+ run (addr , int (port ), handler , enable_ipv6 = enable_ipv6 )
6180 except WSGIServerException , e :
6281 # Use helpful error messages instead of ugly tracebacks.
6382 ERRORS = {
0 commit comments