廢話很少,直接開始了。python
既然要看啓動,那就要找到程序的入口,django的程序入口在manage.py中:django
if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "auth.settings") from django.core.management import execute_from_command_line execute_from_command_line(sys.argv)
這裏的app
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "auth.settings")
是對環境進行添加(佔時這麼理解了)函數
那麼關鍵來了fetch
execute_from_command_line(sys.argv)
這是從ui
django.core.management
中引入的。this
def execute_from_command_line(argv=None): """ A simple method that runs a ManagementUtility. """ utility = ManagementUtility(argv) utility.execute()
這裏是execute_from_command_lin進行了定義,首先經過參數來得到一個ManageMentUtility對象,這是個命令集合,用來執行命令的管理器。以後經過調用execute函數來執行相應的命令操做,這也是整個啓動的核心函數了。spa
def execute(self): """ Given the command-line arguments, this figures out which subcommand is being run, creates a parser appropriate to that command, and runs it. """ # Preprocess options to extract --settings and --pythonpath. # These options could affect the commands that are available, so they # must be processed early. parser = LaxOptionParser(usage="%prog subcommand [options] [args]", version=get_version(), option_list=BaseCommand.option_list) try: options, args = parser.parse_args(self.argv) handle_default_options(options) except: # Needed because parser.parse_args can raise SystemExit pass # Ignore any option errors at this point. try: subcommand = self.argv[1] except IndexError: subcommand = 'help' # Display help if no arguments were given. no_settings_commands = [ 'help', 'version', '--help', '--version', '-h', 'compilemessages', 'makemessages', 'startapp', 'startproject', ] try: settings.INSTALLED_APPS except ImproperlyConfigured as exc: self.settings_exception = exc # A handful of built-in management commands work without settings. # Load the default settings -- where INSTALLED_APPS is empty. if subcommand in no_settings_commands: settings.configure() if settings.configured: django.setup() self.autocomplete() if subcommand == 'help': if len(args) <= 2: parser.print_lax_help() sys.stdout.write(self.main_help_text() + '\n') elif args[2] == '--commands': sys.stdout.write(self.main_help_text(commands_only=True) + '\n') else: self.fetch_command(args[2]).print_help(self.prog_name, args[2]) elif subcommand == 'version': sys.stdout.write(parser.get_version() + '\n') # Special-cases: We want 'django-admin.py --version' and # 'django-admin.py --help' to work, for backwards compatibility. elif self.argv[1:] == ['--version']: # LaxOptionParser already takes care of printing the version. pass elif self.argv[1:] in (['--help'], ['-h']): parser.print_lax_help() sys.stdout.write(self.main_help_text() + '\n') else: self.fetch_command(subcommand).run_from_argv(self.argv)
這段函數首先經過分解得到命令參數:code
parser = LaxOptionParser(usage="%prog subcommand [options] [args]", version=get_version(), option_list=BaseCommand.option_list) try: options, args = parser.parse_args(self.argv) handle_default_options(options)
對命令的有效性進行分析:對象
try: subcommand = self.argv[1] except IndexError: subcommand = 'help' # Display help if no arguments were given. no_settings_commands = [ 'help', 'version', '--help', '--version', '-h', 'compilemessages', 'makemessages', 'startapp', 'startproject', ]
加載已經設置的APP模塊:
try: settings.INSTALLED_APPS except ImproperlyConfigured as exc: self.settings_exception = exc # A handful of built-in management commands work without settings. # Load the default settings -- where INSTALLED_APPS is empty. if subcommand in no_settings_commands: settings.configure() if settings.configured: django.setup()
在django.setup()中首先會對apps是否加載進行檢測,若是沒有加載那麼會調用load_command_class來import_module來加載這個包
最後
self.fetch_command(subcommand).run_from_argv(self.argv)
run_from_argv函數是來自於base.py主要是同個這個函數來執行相應的命令來啓動django