Django源碼分析

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定義的方法。這樣,就把所有的命令通過這里分發(fā)到不同的Command中去執(zhí)行了。

  • 下面是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. 解析命令行的參數(shù) create_parser, 使用python的內(nèi)置OptionParser來解析參數(shù)
  2. 校驗參數(shù) check, 實際使用checks.run_checks方法。 具體分析看 Django源碼分析-checks設(shè)計
  3. 執(zhí)行 實際調(diào)用handle方法執(zhí)行實際邏輯
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容