美文网首页Django学习
Django源码分析

Django源码分析

作者: 宋尉 | 来源:发表于2015-12-12 01:20 被阅读1426次

    django.core.management.init.py

    • 将 execute_from_command_line 方法对外暴露,也就是django manage.py 中的标准引用

      def execute_from_command_line(argv=None):
        utility = ManagementUtility(argv)
        utility.execute()
      
    • ManagementUtility 写法

      class ManagementUtility(object):
      def __init__(self, argv=None):
        self.argv = argv or sys.argv[:]
        self.prog_name = os.path.basename(self.argv[0])
        self.settings_exception = None
      
      def execute(self):
        parser = LaxOptionParser(...)
        options, args = parser.parse_args(self.argv)
        handle_default_options(options)
        ....
        self.fetch_command(subcommand).run_from_argv(self.argv)
      
      def fetch_command(self, subcommand):
        #getCommands()会把django.core.management.commands中的          
        #所有文件一一列出来,因为一个文件就是对应一个命令
        commands = get_commands()
        app_name = commands[subcommand]
        if isinstance(app_name, BaseCommand):
            klass = app_name
        else:
            klass = load_command_class(app_name, subcommand)
      

    所有的Command继承于BaseCommand,run_from_argv方法是BaseCommand定义的方法。这样,就把所有的命令通过这里分发到不同的Command中去执行了。

    • 下面是BaseCommand类的方法定义

      class BaseCommand(object):
      
        def create_parser(self, prog_name, subcommand):
              return OptionParser(prog=prog_name,
                            usage=self.usage(subcommand),
                            version=self.get_version(),
                            option_list=self.option_list)
      
        def run_from_argv(self, argv):
              parser = self.create_parser(argv[0], argv[1])
              options, args = parser.parse_args(argv[2:])
              handle_default_options(options)
              self.execute(*args, **options.__dict__)
      
        def execute(self, *args, **options):
              self.stdout = OutputWrapper(options.get('stdout', sys.stdout))
              self.check()
              output = self.handle(*args, **options)
              self.stdout.write(output)
            
        def check(self, app_configs=None, tags=None, display_num_errors=False):
              all_issues = checks.run_checks(app_configs=app_configs, tags=tags)
      
        def handle(self, *args, **options):
              raise NotImplementedError('subclasses of BaseCommand must provide a handle() method')
      

    子Command类需要做的是,重写handle方法。
    对于BaseCommand来说,有几个重要的事情

    1. 解析命令行的参数 create_parser, 使用python的内置OptionParser来解析参数
    2. 校验参数 check, 实际使用checks.run_checks方法。 具体分析看 Django源码分析-checks设计
    3. 执行 实际调用handle方法执行实际逻辑

    相关文章

      网友评论

        本文标题:Django源码分析

        本文链接:https://www.haomeiwen.com/subject/briyhttx.html