mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	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:
		| @@ -419,27 +419,30 @@ def runserver(port): | ||||
|     "Starts a lightweight Web server for development." | ||||
|     from django.core.servers.basehttp import run, WSGIServerException | ||||
|     from django.core.handlers.wsgi import AdminMediaHandler, WSGIHandler | ||||
|     from django.conf.settings import SETTINGS_MODULE | ||||
|     if not port.isdigit(): | ||||
|         sys.stderr.write("Error: %r is not a valid port number.\n" % port) | ||||
|         sys.exit(1) | ||||
|     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 "Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows)." | ||||
|     try: | ||||
|         run(int(port), AdminMediaHandler(WSGIHandler())) | ||||
|     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.", | ||||
|         } | ||||
|     def inner_run(): | ||||
|         from django.conf.settings import 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 "Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows)." | ||||
|         try: | ||||
|             error_text = ERRORS[e.args[0].args[0]] | ||||
|         except (AttributeError, KeyError): | ||||
|             error_text = str(e) | ||||
|         sys.stderr.write("Error: %s\n" % error_text) | ||||
|         sys.exit(1) | ||||
|     except KeyboardInterrupt: | ||||
|         sys.exit(0) | ||||
|             run(int(port), AdminMediaHandler(WSGIHandler())) | ||||
|         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.", | ||||
|             } | ||||
|             try: | ||||
|                 error_text = ERRORS[e.args[0].args[0]] | ||||
|             except (AttributeError, KeyError): | ||||
|                 error_text = str(e) | ||||
|             sys.stderr.write("Error: %s\n" % error_text) | ||||
|             sys.exit(1) | ||||
|         except KeyboardInterrupt: | ||||
|             sys.exit(0) | ||||
|     from django.utils import autoreload | ||||
|     autoreload.main(inner_run) | ||||
| runserver.args = '[optional port number]' | ||||
|   | ||||
							
								
								
									
										50
									
								
								django/utils/autoreload.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								django/utils/autoreload.py
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||
		Reference in New Issue
	
	Block a user