Django命令模块

这篇文章我们主要来介绍一下关于 Django 的命令模块,我们经常会使用到,比如以下几个常用的命令,都属于 Django 的命令模块:

python manage.py makemigrations
python manage.py migrate
python manage.py startapp
python manage.py runserver

management 模块是 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(argv=None):"""Run a ManagementUtility."""utility = ManagementUtility(argv)utility.execute()

我们从 ManagementUtility 这个核心类开始入手解析我们的命令模块。

ManagementUtility类

ManagementUtility 类是 Django management 模块中的核心类,它位于 django.core.management 包中。这个类负责解析命令行参数,并根据参数执行相应的命令。

简化后的 ManagementUtility 的核心代码如下,并对重要的部分做了注释:

class ManagementUtility:def __init__(self, argv=None):# 初始化操作passdef main_help_text(self, commands_only=False):# 打印帮助文档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(prog=self.prog_name,usage="%(prog)s subcommand [options] [args]",add_help=False,allow_abbrev=False,)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 didn't 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 方法,主要包括了以下几步:

  1. 检查传入的参数:根据传入的参数判断执行何种子命令。
  2. 通过 CommandParser 对象来解析命令行参数,并调用 parse_known_args() 方法解析参数
  3. django 初始化: django.setup 确保 django 初始化。
  4. 调用子命令:根据子命令获取相应的命令类,并创建该命令类的实例,执行该命令实例的 run_from_argv 方法执行具体的命令内容。

通过上面的步骤,我们发现最后会执行具体子命令的 run_from_argv 方法,子命令为继承了 BaseCommand 类的子类,接下来我们来看看 BaseCommand 类。

BaseCommand类

每一个自定义的管理命令本质是一个Command类, 它继承了Django的Basecommand或其子类, 主要通过重写handle()方法实现自己的业务逻辑代码,而add_arguments()则用于帮助处理命令行的参数,如果运行命令时不需要额外参数,可以不写这个方法,下面是 BaseCommand 类的主要代码:

class BaseCommand:# 帮助文本, 一般备注命令的用途及如何使用。help = 'Some help texts'def 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 raised``Exception`` 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 aren't 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 can't be used together.")if options["force_color"]:self.style = color_style(force_color=True)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(tags=self.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类中最重要的就是如下几个方法:

  1. add_arguments:这个方法用于添加自定义的命令行参数。
  2. handle: 这是 BaseCommand 类中最重要的方法,用于执行实际的命令逻辑。当管理命令被调用时,Django 将调用该方法。你需要在子类中重写这个方法,并在其中定义你的命令的具体逻辑。
  3. run_from_argv(argv): 这个方法用于从命令行参数列表 argv 中解析命令并执行它。它是 BaseCommand 类的入口点方法,被 Django 的管理脚本 manage.py 调用。它会解析命令行参数,调用 handle() 方法执行实际的命令逻辑。
  4. 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 是我们自定义命令的名称。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/626152.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电脑的硬件介绍

电脑的硬件有哪些? 1. 处理器(CPU):CPU就像是计算机的大脑。它负责执行各种计算任务和指令,让你的计算机能够正常工作。它是电脑的核心组件,直接影响性能。 通常来说,Intel Core i5或AMD Ryze…

计算3种颜色粉刷立方体的所有可能方法

“(伯恩赛德引理)设G是一个作用在有限集合X上的有限群,令N为轨道的个数,则 其中Fix(x)是被τ固定的x∈X的个数.“ *高等近世代数 Joseph J. Rotman P78 “设G是一个有限群,作用在集合X上。对每个g属于G令X^g表示X中在g…

K8s(三)Pod资源——pod亲和性与反亲和性,pod重启策略

目录 pod亲和性与反亲和性 pod亲和性 pod反亲和性 pod状态与重启策略 pod状态 pod重启策略 本文主要介绍了pod资源与pod相关的亲和性,以及pod的重启策略 pod亲和性与反亲和性 pod亲和性(podAffinity)有两种 1.podaffinity,…

大模型学习篇(一):初识大模型

目录 一、大模型的定义 二、大模型的基本原理与特点 三、大模型的分类 四、大模型的相关落地产品 五、总结 一、大模型的定义 大模型是指具有数千万甚至数亿参数的深度学习模型。大模型具有以下特点: 参数规模庞大:大模型的一个关键特征是其包含了…

在 Linux 本地部署 stable diffusion

由于工作站安装的是 ubuntu,卡也在上面,就只能在 ubuntu 上部署安装 stable diffusion 了。另外,Linux 上使用 stable diffusion 也会方便很多。 1 准备工作 NVIDIA 官网下载驱动,主要是为了规避多卡驱动不同的问题。由于本机是…

机器学习_梯度下降

文章目录 什么是梯度梯度下降梯度下降有什么用 什么是梯度 计算梯度向量其几何意义,就是函数变化的方向,而且是变化最快的方向。对于函数f(x),在点(xo,yo),梯度向量的方向也就是y值增加最快的方向。也就是说,沿着梯度…

【QML COOK】- 009-组件(Components)

组件对于QML来说就如同C的类一样。可以用同一个组件创建多个对象。 组件有两种定义方式: 用独立的.qml文件定义组件在.qml文件中用Component对象定义组件 1. 创建项目,新建文件IndependentComponent.qml import QtQuickRectangle {id : rootText {id…

绝地求生追封原理

绝地求生追封原理是指在网络游戏《绝地求生》中,玩家通过观察和分析游戏中的各种信息,追踪其他玩家的位置和行动,以便更好地进行战术和攻击。 追封原理主要通过以下几种方式实现: BattleEye作弊系统检测 绝地求生玩家对这个系统…

vue中使用mpegts.js播放flv的直播视频流

第一步&#xff1a;引入mpegts.js npm install --save mpegts.js 第二步&#xff1a;在vue文件中引入mpegts.js的依赖 第三步&#xff1a;编写展示视频的盒子 我这里是使用循环遍历的方式创建video标签&#xff0c;这样方便后面随机展示视频使用 <template><div>&l…

03 顺序表

目录 线性表顺序表练习 线性表(Linear list)是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串。。。 线性表在逻辑上时线性结构&#xff0c;是连续的一条直线。但在物理结…

【RTOS】快速体验FreeRTOS所有常用API(1)工程创建

目录 一、工程创建1.1 新建工程1.2 配置RCC1.3 配置SYS1.4 配置外设1&#xff09;配置 LED PC132&#xff09;配置 串口 UART13&#xff09;配置 OLED I2C1 1.5 配置FreeRTOS1.6 工程设置1.7 生成代码1.8 keil设置下载&复位1.9 添加用户代码 本工程皆在快速体验FreeRTOS所有…

智慧公厕:打造智慧城市公共厕所信息化管理的新升级

在现代社会中&#xff0c;随着科学技术的不断进步与应用&#xff0c;智慧公厕作为公共服务设施&#xff0c;正迎来一次新的升级与革新。利用先进技术&#xff0c;智慧公厕实现了信息化升级&#xff0c;能够实时监测人员、环境和设备状况&#xff0c;提高使用效率、安全性、舒适…

微信小程序(一)简单的结构及样式演示

注释很详细&#xff0c;直接上代码 涉及内容&#xff1a; view和text标签的使用类的使用flex布局水平方向上均匀分布子元素垂直居中对齐子元素字体大小文字颜色底部边框的宽和颜色 源码&#xff1a; index.wxml <view class"navs"><text class"active…

python多线程和多进程内存共享方式

目录 一:介绍 二:多线程共享内存方式 三:多进程共享内存方式 一:介绍 在Python中,多线程和多进程都有各自的内存管理机制,并且它们的内存共享方式也不同。 对于多线

Android 11.0 mtp模式下连接pc后显示的文件夹禁止删除copy重命名功能实现

1.前言 在11.0的系统rom定制化开发中,usb连接pc端的时候有好几种模式,在做otg连接pc端的时候,改成mtp模式的时候,在pc端可以看到产品设备 的显示的文件夹的内容,对于产品设备里面的文件在pc端禁止做删除重命名拷贝等操作功能的实现 2.mtp模式下连接pc后显示的文件夹禁止删…

Linux中文件名修改的多种方法

找一个不算漂亮的普通女孩&#xff0c;一起柴米油盐&#xff0c;一起日出日落&#xff0c;一起田间地头&#xff0c;一起春花冬雪&#xff01;要一个不算大的小房子&#xff0c;生两个健康可爱的宝宝&#xff0c;这样就很好。。。。。。 简介&#xff1a; 在Linux系统中&#x…

第二百六十八回

文章目录 概念介绍实现方法示例代码 我们在上一章回中介绍了跟手指移动的小球相关的内容&#xff0c;本章回中将介绍自定义组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 概念介绍 在项目中有些内容无法通过现有的组件来实现&#xff0c;因此需要自定义组件&#xff0…

docker 部署xxl-job-admin

导言 xxl-job是一款开源的分布式任务调度平台,支持在线管理任务和调度任务。本文将详细介绍如何基于2.2.0版本进行xxl-job的部署,包括数据库的初始化、镜像的拉取和运行、以及Nginx的配置。 部署数据库 首先,我们需要部署MySQL数据库作为xxl-job的后端存储。执行以下命令:…

MongoDB Compass当前版本及历史版本下载安装

mongoDB compass 当前版本下载 官网 https://www.mongodb.com/try/download/compass 官网下载一般只能下载最新版本。 github https://github.com/mongodb-js/compass MongoDB Compass与MongoDB的版本对应关系 MongoDB CompassMongoDB1.9.12MongoDB 2.6.11 Community