zoukankan      html  css  js  c++  java
  • Django如何启动源码分析

    Django如何启动源码分析

    启动

    我们启动Django是通过python manage.py runsever的命令

    解决

    这句话就是执行manage.py文件,并在命令行发送一个runsever字符串

    解析manage.py

    #!/usr/bin/env python
    import os
    import sys
    
    if __name__ == "__main__":
    	#os.environ.setdefault 方法可以修改系统环境变量,但是只能os.environ 只能影响到当前运行程序
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "zx2.settings")
        try:
        	#导入模块,其实这里不单单只是导入execute_from_command_line这个方法,更多的是检查Django的模块,配置是否有问题
            from django.core.management import execute_from_command_line
        except ImportError:
            # The above import may fail for some other reason. Ensure that the
            # issue is really that Django is missing to avoid masking other
            # exceptions on Python 2.
            try:
            	#精准判断是不是django模块的问题
                import django
            except ImportError:
                raise ImportError(
                    "Couldn't import Django. Are you sure it's installed and "
                    "available on your PYTHONPATH environment variable? Did you "
                    "forget to activate a virtual environment?"
                )
            raise
        #sys.argv是从外部获取参数,最后执行下面这个方法
        execute_from_command_line(sys.argv)
    

    测试sys.argv

    发现两种启动获取的参数不一样,但是第二个参数一样

    命令行启动项目
    ['manage.py', 'runserver']
    
    pycharm 启动项目
    ['C:/Users/Administrator/Desktop/01python/django/zx1/manage.py', 'runserver', '127.0.0.1:8000']
    

    解析execute_from_command_line(sys.argv)

    项目启动入口

    def execute_from_command_line(argv=None):
        """
        管理应用程序的简单方法
        A simple method that runs a ManagementUtility.
        """
        utility = ManagementUtility(argv)
        utility.execute()
    

    ManagementUtility初始化代码

    class ManagementUtility(object):
        """
        封装django-admin 和 manage.py的公共逻辑代码
        Encapsulates the logic of the django-admin and manage.py utilities.
        """
        def __init__(self, argv=None):
        	#把argv给self对象
            self.argv = argv or sys.argv[:]
            #返回path最后的文件名。若path以/或结尾,那么就会返回空值,为zx1
            self.prog_name = os.path.basename(self.argv[0])
            self.settings_exception = None
    

    utility.execute()分析

        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.
            """
            try:
            	#self.argv[1]值为runserver
                subcommand = self.argv[1]
            except IndexError:
                subcommand = 'help'  # Display help if no arguments were given.
    		#预处理选项以提取--settings和--pythonpath。
            # Preprocess options to extract --settings and --pythonpath.
            #这些选项可能会影响可用的命令,因此
            # These options could affect the commands that are available, so they
            #必须提前处理。
            # must be processed early.
            #创建一个命令分析器
            parser = CommandParser(None, usage="%(prog)s subcommand [options] [args]", add_help=False)
            parser.add_argument('--settings')
            parser.add_argument('--pythonpath')
            parser.add_argument('args', nargs='*')  # catch-all
            try:
            	#self.argv[2:]值为'127.0.0.1:8000',可以推断出这部分可能和启动服务器有关,并且有默认的ip和端口号
                options, args = parser.parse_known_args(self.argv[2:])
                handle_default_options(options)
            except CommandError:
                pass  # Ignore any option errors at this point.
    
            try:
            #获取app配置信息
                settings.INSTALLED_APPS
            except ImproperlyConfigured as exc:
                self.settings_exception = exc
    
            if settings.configured:
                # Start the auto-reloading dev server even if the code is broken.
                # The hardcoded condition is a code smell but we can't rely on a
                # flag on the command class because we haven't located it yet.
                #判断外部输入命令,这部分就是启动的核心代码了
                if subcommand == 'runserver' and '--noreload' not in self.argv:
                    try:
                        autoreload.check_errors(django.setup)()
                    except Exception:
                        # The exception will be raised later in the child process
                        # started by the autoreloader. Pretend it didn't happen by
                        # loading an empty list of applications.
                        apps.all_models = defaultdict(OrderedDict)
                        apps.app_configs = OrderedDict()
                        apps.apps_ready = apps.models_ready = apps.ready = True
    
                        # Remove options not compatible with the built-in runserver
                        # (e.g. options for the contrib.staticfiles' runserver).
                        # Changes here require manually testing as described in
                        # #27522.
                        _parser = self.fetch_command('runserver').create_parser('django', 'runserver')
                        _options, _args = _parser.parse_known_args(self.argv[2:])
                        for _arg in _args:
                            self.argv.remove(_arg)
    
                # In all other cases, django.setup() is required to succeed.
                else:
                    django.setup()
    
            self.autocomplete()
    
            if subcommand == 'help':
                if '--commands' in args:
                    sys.stdout.write(self.main_help_text(commands_only=True) + '
    ')
                elif len(options.args) < 1:
                    sys.stdout.write(self.main_help_text() + '
    ')
                else:
                    self.fetch_command(options.args[0]).print_help(self.prog_name, options.args[0])
            # Special-cases: We want 'django-admin --version' and
            # 'django-admin --help' to work, for backwards compatibility.
            elif subcommand == 'version' or self.argv[1:] == ['--version']:
                sys.stdout.write(django.get_version() + '
    ')
            elif self.argv[1:] in (['--help'], ['-h']):
                sys.stdout.write(self.main_help_text() + '
    ')
            else:
                self.fetch_command(subcommand).run_from_argv(self.argv)
    

    后续代码有点看的迷糊了,没有找到socket启动的部分,以后再来

  • 相关阅读:
    Android的数据存储
    Servlet第一天
    JavaScript高级程序设计读书笔记(3)
    Interesting Papers on Face Recognition
    Researchers Study Ear Biometrics
    IIS 发生意外错误 0x8ffe2740
    Father of fractal geometry, Benoit Mandelbrot has passed away
    Computer vision scientist David Mumford wins National Medal of Science
    Pattern Recognition Review Papers
    盒模型bug的解决方法
  • 原文地址:https://www.cnblogs.com/zx125/p/11745863.html
Copyright © 2011-2022 走看看