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) + '\n')
64             elif not options.args:
65                 sys.stdout.write(self.main_help_text() + '\n')
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() + '\n')
72         elif self.argv[1:] in (['--help'], ['-h']):
73             sys.stdout.write(self.main_help_text() + '\n')
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

猜你喜欢

转载自www.cnblogs.com/arrow-kejin/p/10359468.html
今日推荐