Added auto-reload to standalone server! Fixes #113. Thanks very much to Jason Huggins for the patch.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@266 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
c21f6ecee2
commit
9566a61a22
|
@ -419,10 +419,11 @@ def runserver(port):
|
||||||
"Starts a lightweight Web server for development."
|
"Starts a lightweight Web server for development."
|
||||||
from django.core.servers.basehttp import run, WSGIServerException
|
from django.core.servers.basehttp import run, WSGIServerException
|
||||||
from django.core.handlers.wsgi import AdminMediaHandler, WSGIHandler
|
from django.core.handlers.wsgi import AdminMediaHandler, WSGIHandler
|
||||||
from django.conf.settings import SETTINGS_MODULE
|
|
||||||
if not port.isdigit():
|
if not port.isdigit():
|
||||||
sys.stderr.write("Error: %r is not a valid port number.\n" % port)
|
sys.stderr.write("Error: %r is not a valid port number.\n" % port)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
def inner_run():
|
||||||
|
from django.conf.settings import SETTINGS_MODULE
|
||||||
print "Starting server on port %s with settings module %r." % (port, SETTINGS_MODULE)
|
print "Starting server on port %s with settings module %r." % (port, SETTINGS_MODULE)
|
||||||
print "Go to http://127.0.0.1:%s/ for Django." % port
|
print "Go to http://127.0.0.1:%s/ for Django." % port
|
||||||
print "Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows)."
|
print "Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows)."
|
||||||
|
@ -442,4 +443,6 @@ def runserver(port):
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
from django.utils import autoreload
|
||||||
|
autoreload.main(inner_run)
|
||||||
runserver.args = '[optional port number]'
|
runserver.args = '[optional port number]'
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
# Autoreloading launcher.
|
||||||
|
# Borrowed from Peter Hunt and the CherryPy project (http://www.cherrypy.org).
|
||||||
|
# Some taken from Ian Bicking's Paste (http://pythonpaste.org/).
|
||||||
|
|
||||||
|
import os, sys, thread, time
|
||||||
|
|
||||||
|
RUN_RELOADER = True
|
||||||
|
reloadFiles = []
|
||||||
|
|
||||||
|
def reloader_thread():
|
||||||
|
mtimes = {}
|
||||||
|
while RUN_RELOADER:
|
||||||
|
for filename in filter(lambda v: v, map(lambda m: getattr(m, "__file__", None), sys.modules.values())) + reloadFiles:
|
||||||
|
if filename.endswith(".pyc"):
|
||||||
|
filename = filename[:-1]
|
||||||
|
mtime = os.stat(filename).st_mtime
|
||||||
|
if filename not in mtimes:
|
||||||
|
mtimes[filename] = mtime
|
||||||
|
continue
|
||||||
|
if mtime > mtimes[filename]:
|
||||||
|
sys.exit(3) # force reload
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
def restart_with_reloader():
|
||||||
|
while True:
|
||||||
|
args = [sys.executable] + sys.argv
|
||||||
|
if sys.platform == "win32":
|
||||||
|
args = ['"%s"' % arg for arg in args]
|
||||||
|
new_environ = os.environ.copy()
|
||||||
|
new_environ["RUN_MAIN"] = 'true'
|
||||||
|
exit_code = os.spawnve(os.P_WAIT, sys.executable, args, new_environ)
|
||||||
|
if exit_code != 3:
|
||||||
|
return exit_code
|
||||||
|
|
||||||
|
def main(main_func, args=None, kwargs=None):
|
||||||
|
if os.environ.get("RUN_MAIN") == "true":
|
||||||
|
if args is None:
|
||||||
|
args = ()
|
||||||
|
if kwargs is None:
|
||||||
|
kwargs = {}
|
||||||
|
thread.start_new_thread(main_func, args, kwargs)
|
||||||
|
try:
|
||||||
|
reloader_thread()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
sys.exit(restart_with_reloader())
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
Loading…
Reference in New Issue