django启动过程剖析
Posted arrow-kejin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django启动过程剖析相关的知识,希望对你有一定的参考价值。
在manage.py文件中
1 if __name__ == ‘__main__‘: 2 os.environ.setdefault(‘DJANGO_SETTINGS_MODULE‘, ‘test11.settings‘) 3 try: 4 from django.core.management import execute_from_command_line 5 except ImportError as exc: 6 raise ImportError( 7 "Couldn‘t import Django. Are you sure it‘s installed and " 8 "available on your PYTHONPATH environment variable? Did you " 9 "forget to activate a virtual environment?" 10 ) from exc 11 execute_from_command_line(sys.argv) #在这里获取命令行参数
在execute_from_command_line函数中实现一系列操作:
def execute_from_command_line(argv=None): """Run a ManagementUtility.""" utility = ManagementUtility(argv) #实例化ManagementUtility对象 utility.execute()
在ManagementUtility对象的execute方法中:
1 def execute(self): 2 """ 3 Given the command-line arguments, figure out which subcommand is being 4 run, create a parser appropriate to that command, and run it. 5 """ 6 try: 7 subcommand = self.argv[1] #这里获取第一个参数(命令)如runserver 8 except IndexError: 9 subcommand = ‘help‘ # Display help if no arguments were given. 10 11 # Preprocess options to extract --settings and --pythonpath. 12 # These options could affect the commands that are available, so they 13 # must be processed early. 14 parser = CommandParser(usage=‘%(prog)s subcommand [options] [args]‘, add_help=False, allow_abbrev=False) 15 parser.add_argument(‘--settings‘) 16 parser.add_argument(‘--pythonpath‘) 17 parser.add_argument(‘args‘, nargs=‘*‘) # catch-all 18 try: 19 options, args = parser.parse_known_args(self.argv[2:]) #这里把后面的参数装入options中如[‘127.0.0.1:8000‘] 20 handle_default_options(options) 21 except CommandError: 22 pass # Ignore any option errors at this point. 23 24 try: 25 settings.INSTALLED_APPS 26 except ImproperlyConfigured as exc: 27 self.settings_exception = exc 28 except ImportError as exc: 29 self.settings_exception = exc 30 31 if settings.configured: 32 # Start the auto-reloading dev server even if the code is broken. 33 # The hardcoded condition is a code smell but we can‘t rely on a 34 # flag on the command class because we haven‘t located it yet. 35 if subcommand == ‘runserver‘ and ‘--noreload‘ not in self.argv: 36 try: 37 autoreload.check_errors(django.setup)() 38 except Exception: 39 # The exception will be raised later in the child process 40 # started by the autoreloader. Pretend it didn‘t happen by 41 # loading an empty list of applications. 42 apps.all_models = defaultdict(OrderedDict) 43 apps.app_configs = OrderedDict() 44 apps.apps_ready = apps.models_ready = apps.ready = True 45 46 # Remove options not compatible with the built-in runserver 47 # (e.g. options for the contrib.staticfiles‘ runserver). 48 # Changes here require manually testing as described in 49 # #27522. 50 _parser = self.fetch_command(‘runserver‘).create_parser(‘django‘, ‘runserver‘) 51 _options, _args = _parser.parse_known_args(self.argv[2:]) 52 for _arg in _args: 53 self.argv.remove(_arg) 54 55 # In all other cases, django.setup() is required to succeed. 56 else: 57 django.setup() 58 59 self.autocomplete() 60 61 if subcommand == ‘help‘: 62 if ‘--commands‘ in args: 63 sys.stdout.write(self.main_help_text(commands_only=True) + ‘ ‘) 64 elif not options.args: 65 sys.stdout.write(self.main_help_text() + ‘ ‘) 66 else: 67 self.fetch_command(options.args[0]).print_help(self.prog_name, options.args[0]) 68 # Special-cases: We want ‘django-admin --version‘ and 69 # ‘django-admin --help‘ to work, for backwards compatibility. 70 elif subcommand == ‘version‘ or self.argv[1:] == [‘--version‘]: 71 sys.stdout.write(django.get_version() + ‘ ‘) 72 elif self.argv[1:] in ([‘--help‘], [‘-h‘]): 73 sys.stdout.write(self.main_help_text() + ‘ ‘) 74 else: 75 self.fetch_command(subcommand).run_from_argv(self.argv)
在django.setup中调用apps.populate方法:
1 def populate(self, installed_apps=None): 2 """ 3 Load application configurations and models. 4 5 Import each application module and then each model module. 6 7 It is thread-safe and idempotent, but not reentrant. 8 """ 9 if self.ready: 10 return 11 12 # populate() might be called by two threads in parallel on servers 13 # that create threads before initializing the WSGI callable. 14 with self._lock: 15 if self.ready: 16 return 17 18 # An RLock prevents other threads from entering this section. The 19 # compare and set operation below is atomic. 20 if self.loading: 21 # Prevent reentrant calls to avoid running AppConfig.ready() 22 # methods twice. 23 raise RuntimeError("populate() isn‘t reentrant") 24 self.loading = True 25 26 # Phase 1: initialize app configs and import app modules. 27 for entry in installed_apps: 28 if isinstance(entry, AppConfig): 29 app_config = entry 30 else: 31 app_config = AppConfig.create(entry) 32 if app_config.label in self.app_configs: 33 raise ImproperlyConfigured( 34 "Application labels aren‘t unique, " 35 "duplicates: %s" % app_config.label) 36 37 self.app_configs[app_config.label] = app_config 38 app_config.apps = self 39 40 # Check for duplicate app names. 41 counts = Counter( 42 app_config.name for app_config in self.app_configs.values()) 43 duplicates = [ 44 name for name, count in counts.most_common() if count > 1] 45 if duplicates: 46 raise ImproperlyConfigured( 47 "Application names aren‘t unique, " 48 "duplicates: %s" % ", ".join(duplicates)) 49 50 self.apps_ready = True 51 52 # Phase 2: import models modules. 53 for app_config in self.app_configs.values(): 54 app_config.import_models() 55 56 self.clear_cache() 57 58 self.models_ready = True 59 60 # Phase 3: run ready() methods of app configs. 61 for app_config in self.get_app_configs(): 62 app_config.ready() 63 64 self.ready = True
以上是关于django启动过程剖析的主要内容,如果未能解决你的问题,请参考以下文章
第8章2节《MonkeyRunner源代码剖析》MonkeyRunner启动执行过程-解析处理命令行參数