手机算命网站建设,重庆九龙快报,深圳市宝安区投资推广署,后台网站手机版视频怎么做这篇文章我们主要来介绍一下关于 Django 的命令模块#xff0c;我们经常会使用到#xff0c;比如以下几个常用的命令#xff0c;都属于 Django 的命令模块#xff1a;
python manage.py makemigrations
python manage.py migrate
python manage.py startapp
python manage…这篇文章我们主要来介绍一下关于 Django 的命令模块我们经常会使用到比如以下几个常用的命令都属于 Django 的命令模块
python manage.py makemigrations
python manage.py migrate
python manage.py startapp
python manage.py runservermanagement 模块是 Django 框架中用于管理命令行操作的核心组件。它提供了一种简单而强大的方式让开发人员可以通过命令行执行各种任务如数据库迁移、创建超级用户、运行开发服务器等。
目录结构
本质上在 Django 中这些都是使用 management 模块来进行管理的我们可以在 Django 源码目录以及通过 python manage.py startapp 创建的 app 目录中查看到所有支持的命令在 Django 源码中主要位于以下路径django.core.management,目录结构如下
├── management
│ ├── __init__.py
│ ├── __pycache__
│ ├── base.py
│ ├── color.py
│ ├── commands
│ ├── sql.py
│ ├── templates.py
│ └── utils.py
核心的内容都位于 commands 目录下我们再来看一下 commands 目录下都有什么文件
├── commands
│ ├── __init__.py
│ ├── __pycache__
│ ├── check.py
│ ├── compilemessages.py
│ ├── createcachetable.py
│ ├── dbshell.py
│ ├── diffsettings.py
│ ├── dumpdata.py
│ ├── flush.py
│ ├── inspectdb.py
│ ├── loaddata.py
│ ├── makemessages.py
│ ├── makemigrations.py
│ ├── migrate.py
│ ├── optimizemigration.py
│ ├── runserver.py
│ ├── sendtestemail.py
│ ├── shell.py
│ ├── showmigrations.py
│ ├── sqlflush.py
│ ├── sqlmigrate.py
│ ├── sqlsequencereset.py
│ ├── squashmigrations.py
│ ├── startapp.py
│ ├── startproject.py
│ ├── test.py
│ └── testserver.py
是不是非常熟悉我们平常执行 python manage.py help 所展示的命令几乎都位于这里。
对于 Django 来说它定义了关于命令模块的一些规则我们只需要遵循即可找到相关的内置命令及实现自己的命令后面会通过查看源码来解析原因
management和commands每个目录下都必须有个__init__.py空文件表明这是一个python包。另外以下划线开头的文件名不能用作管理命令脚本。management/commands目录可以位于任何一个app的目录下Django都能找到它。一般建议每个python脚本文件对应一条管理命令。
Django是如何定义命令的
management 模块的实现涉及多个关键类和函数我们来深入了解其中的一些重要概念和源码。
Django启动入口文件
我们从最熟悉的 Django 启动方式开始。我们都知道启动 Django的方式python manage.py runserver,查看 manage.py 文件的核心部分 from django.core.management import execute_from_command_lineexecute_from_command_line(sys.argv)发现其调用了management 模块的 execute_from_command_line
def execute_from_command_line(argvNone):Run a ManagementUtility.utility ManagementUtility(argv)utility.execute()我们从 ManagementUtility 这个核心类开始入手解析我们的命令模块。
ManagementUtility类
ManagementUtility 类是 Django management 模块中的核心类它位于 django.core.management 包中。这个类负责解析命令行参数并根据参数执行相应的命令。
简化后的 ManagementUtility 的核心代码如下并对重要的部分做了注释
class ManagementUtility:def __init__(self, argvNone):# 初始化操作passdef main_help_text(self, commands_onlyFalse):# 打印帮助文档passdef fetch_command(self, subcommand):# 根据传入的子命令名称 subcommand 返回该命令的类commands get_commands()try:app_name commands[subcommand]except KeyError:# 主要处理当输入命令错误或不存在时的错误信息passif isinstance(app_name, BaseCommand):klass app_nameelse:klass load_command_class(app_name, subcommand)return klassdef autocomplete(self):# 用于自动补全命令的。它是一个便利方法可以帮助开发人员在命令行中输入管理命令时提供自动补全的功能。pass# 核心方法整个命令入口执行的关键def execute(self):# 当不传任何命令是默认执行 help 命令即执行 python manage.py 等同于 python manage.py helptry:subcommand self.argv[1]except IndexError:subcommand help # Display help if no arguments were given.# 解析传入的命令行参数parser CommandParser(progself.prog_name,usage%(prog)s subcommand [options] [args],add_helpFalse,allow_abbrevFalse,)parser.add_argument(--settings)parser.add_argument(--pythonpath)parser.add_argument(args, nargs*) # catch-alltry:options, args parser.parse_known_args(self.argv[2:])handle_default_options(options)except CommandError:pass # Ignore any option errors at this point.# 确保所有的 INSTALLED_APPS 已经正确加载try:settings.INSTALLED_APPSexcept ImproperlyConfigured as exc:self.settings_exception excexcept ImportError as exc:self.settings_exception excif settings.configured:# 当命令为runserver并且不是 --noreload 模式时执行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 didnt happen by# loading an empty list of applications.apps.all_models defaultdict(dict)apps.app_configs {}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)# 进行 django 初始化操作这也是 django 启动必须执行的第一个初始化动作else:django.setup()# 自动补全命令self.autocomplete()if subcommand help:# 打印帮助信息passelif subcommand version or self.argv[1:] [--version]:# 打印 django 版本信息sys.stdout.write(django.get_version() \n)elif self.argv[1:] in ([--help], [-h]):# 同样是打印帮助信息sys.stdout.write(self.main_help_text() \n)else:# 执行具体子命令的 run_from_argv 方法子命令为继承了 BaseCommand 类的子类self.fetch_command(subcommand).run_from_argv(self.argv)ManagementUtility类中最重要的就是 execute 方法主要包括了以下几步
检查传入的参数根据传入的参数判断执行何种子命令。通过 CommandParser 对象来解析命令行参数并调用 parse_known_args() 方法解析参数django 初始化 django.setup 确保 django 初始化。调用子命令根据子命令获取相应的命令类并创建该命令类的实例执行该命令实例的 run_from_argv 方法执行具体的命令内容。
通过上面的步骤我们发现最后会执行具体子命令的 run_from_argv 方法子命令为继承了 BaseCommand 类的子类接下来我们来看看 BaseCommand 类。
BaseCommand类
每一个自定义的管理命令本质是一个Command类, 它继承了Django的Basecommand或其子类, 主要通过重写handle()方法实现自己的业务逻辑代码而add_arguments()则用于帮助处理命令行的参数如果运行命令时不需要额外参数可以不写这个方法下面是 BaseCommand 类的主要代码
class BaseCommand:# 帮助文本, 一般备注命令的用途及如何使用。help Some help textsdef add_arguments(self, parser):# 当我们自定义的命令类需要添加额外的参数选项时重写这个方法passdef run_from_argv(self, argv):Set up any environment changes requested (e.g., Python pathand Django settings), then run this command. If thecommand raises a CommandError, intercept it and print it sensiblyto stderr. If the --traceback option is present or the raisedException is not CommandError, raise it.self._called_from_command_line Trueparser self.create_parser(argv[0], argv[1])options parser.parse_args(argv[2:])cmd_options vars(options)# Move positional args out of options to mimic legacy optparseargs cmd_options.pop(args, ())handle_default_options(options)try:# 去掉异常处理后这个方法最重要的逻辑就在这里通过 self.execute 执行子命令的逻辑self.execute(*args, **cmd_options)except CommandError as e:if options.traceback:raise# SystemCheckError takes care of its own formatting.if isinstance(e, SystemCheckError):self.stderr.write(str(e), lambda x: x)else:self.stderr.write(%s: %s % (e.__class__.__name__, e))sys.exit(e.returncode)finally:try:connections.close_all()except ImproperlyConfigured:# Ignore if connections arent setup at this point (e.g. no# configured settings).passdef execute(self, *args, **options):Try to execute this command, performing system checks if needed (ascontrolled by the requires_system_checks attribute, except ifforce-skipped).if options[force_color] and options[no_color]:raise CommandError(The --no-color and --force-color options cant be used together.)if options[force_color]:self.style color_style(force_colorTrue)elif options[no_color]:self.style no_style()self.stderr.style_func Noneif options.get(stdout):self.stdout OutputWrapper(options[stdout])if options.get(stderr):self.stderr OutputWrapper(options[stderr])if self.requires_system_checks and not options[skip_checks]:if self.requires_system_checks ALL_CHECKS:self.check()else:self.check(tagsself.requires_system_checks)if self.requires_migrations_checks:self.check_migrations()output self.handle(*args, **options)if output:if self.output_transaction:connection connections[options.get(database, DEFAULT_DB_ALIAS)]output %s\n%s\n%s % (self.style.SQL_KEYWORD(connection.ops.start_transaction_sql()),output,self.style.SQL_KEYWORD(connection.ops.end_transaction_sql()),)self.stdout.write(output)return outputdef handle(self, *args, **options):# 任何自定义的命令都需要实现 handle 方法这里是具体的子命令执行逻辑raise NotImplementedError(subclasses of BaseCommand must provide a handle() method)BaseCommand类中最重要的就是如下几个方法
add_arguments这个方法用于添加自定义的命令行参数。handle: 这是 BaseCommand 类中最重要的方法用于执行实际的命令逻辑。当管理命令被调用时Django 将调用该方法。你需要在子类中重写这个方法并在其中定义你的命令的具体逻辑。run_from_argv(argv): 这个方法用于从命令行参数列表 argv 中解析命令并执行它。它是 BaseCommand 类的入口点方法被 Django 的管理脚本 manage.py 调用。它会解析命令行参数调用 handle() 方法执行实际的命令逻辑。execute 用于执行实际的命令逻辑的核心方法execute 方法会调用 handle 方法处理解析参数在执行 handle 方法时如果发生错误execute 方法会捕获并处理这些错误。
自定义命令
要注册自定义命令我们需要在 Django 项目的某个应用中创建一个名为 management 的子目录并在该目录中创建一个名为 commands 的子目录。在 commands 目录中我们可以创建一个 Python 模块文件并定义一个继承自 BaseCommand 的命令类。
以下是一个简单的自定义命令的示例
from django.core.management.base import BaseCommandclass Command(BaseCommand):help This is my custom command.def handle(self, *args, **options):self.stdout.write(Hello from my custom command!)在上述示例中我们创建了一个名为 Command 的自定义命令类从Django4开始该类的名称必须为Command继承自 BaseCommand。在 handle() 方法中我们简单地输出了一条消息。
要执行自定义命令我们可以在命令行中使用以下命令
python manage.py hello_world其中hello_world 是我们自定义命令的名称。