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
方法,主要包括了以下几步:
- 检查传入的参数:根据传入的参数判断执行何种子命令。
- 通过
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 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
类中最重要的就是如下几个方法:
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
是我们自定义命令的名称。
相关文章:
Django命令模块
这篇文章我们主要来介绍一下关于 Django 的命令模块,我们经常会使用到,比如以下几个常用的命令,都属于 Django 的命令模块: python manage.py makemigrations python manage.py migrate python manage.py startapp python manage…...

【linux驱动开发】在linux内核中注册一个杂项设备与字符设备以及内核传参的详细教程
文章目录 注册杂项设备驱动模块传参注册字符设备 开发环境: windows ubuntu18.04 迅为rk3568开发板 注册杂项设备 相较于字符设备,杂项设备有以下两个优点: 节省主设备号:杂项设备的主设备号固定为 10,在系统中注册多个 misc 设备驱动时&…...
Golang条件编译 | 获取系统的磁盘空间内存占用demo | gopsutil/disk库(跨平台方案)
文章目录 一、Golang条件编译1. 构建标签( Build tags)2. 文件后缀(File suffixes) 二、GO golang 获取磁盘空间 条件编译思路 三、【推荐】使用github.com/shirou/gopsutil/disk这个库,如何获取机器下不同磁盘分区的内容 一、Golang条件编译…...
22/76-池化
池化(最大池化层:选每个kernel中最大的数) 填充、步幅、多个通道: 池化层与卷积层类似,都具有填充和步幅。 没有可学习的参数。 在每个输入通道应用池化层以获得相应的输出通道。 输出通道数输入通道数。 平均池化层…...

江科大STM32 下
目录 ADC数模转换器DMA直接存储器存取USART串口9-2 串口发送接受9-3 串口收发HEX数据包 I2C(mpu6050陀螺仪和加速度计)SPI协议10.1 SPI简介W25Q64简介10.3 SPI软件读写W25Q6410.4 SPI硬件读写W25Q64 BKP、RTC11.0 Unix时间戳11.1 读写备份寄存器BKP11.2 RTC实时时钟 十二、PWR1…...

利用HTML和CSS实现的浮动布局
代码如下 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><style>*{m…...

2024年第十届控制、自动化与机器人国际会议(ICCAR 2024)即将召开!
2024年4月27~29日 新加披 会议官网:10th-ICCAR 2024https://iccar.org/index.html 第十届控制、自动化和机器人国际会议将于2024年4月27-29日在新加坡举办。本次会议由新加坡电子学会,IEEE机器人和自动控制协会和IEEE联合主办,并得到北京航空…...

基于python集成学习算法XGBoost农业数据可视化分析预测系统
文章目录 基于python集成学习算法XGBoost农业数据可视化分析预测系统一、项目简介二、开发环境三、项目技术四、功能结构五、功能实现模型构建封装类用于网格调参训练模型系统可视化数据请求接口模型评分 0.5*mse 六、系统实现七、总结 基于python集成学习算法XGBoost农业数据可…...

第29集《佛法修学概要》
丁三、声闻乘 分二:戊一、释义;戊二、四谛法;戊三、结示 请大家打开讲义第八十二页。我们看丁三,声闻乘。 在祖师大德的判教当中,把我们整个大乘的成佛之道分成了三个部分:第一个是安乐道,第…...

奥伦德光电耦合器5G通信领域及其相关领域推荐
光电耦合器是以光为媒介传输电信号的一种电-光-电转换器件。由于该器件使用寿命长、工作温度范围宽,所以在过程控制、工业通信、家用电器、医疗设备、通信设备、计算机以及精密仪器等方面有着广泛应用在当前工艺技术持续发展与提升的过程中,其工作速度、…...

机器学习算法 - 马尔可夫链
马尔可夫链(Markov Chain)可以说是机器学习和人工智能的基石,在强化学习、自然语言处理、金融领域、天气预测、语音识别方面都有着极其广泛的应用 > The future is independent of the past given the present 未来独立于过去ÿ…...
Linux下防火墙相关命令整理
目录 一.前言二.相关命令整理 一.前言 这篇文章简单整理一下Linux系统中防火墙相关命令。 二.相关命令整理 开启防火墙 systemctl start firewalld关闭防火墙 systemctl stop firewalld重启防火墙 systemctl restart firewalld开机启用防火墙 systemctl enable firewall…...
Python八股文总结
一. Python基本数据结构有哪四种?区别是什么? 列表(List)元组(Tuple)字典(Dictionary)集合(Set) 区别主要在于它们的可变性(是否可以修改&#x…...

计算机导论05-计算机网络
文章目录 计算机网络基础计算机网络概述计算机网络的概念计算机网络的功能计算机网络的组成 计算机网络的发展计算机网络的类型 网络体系结构网络互联模型OSI/RM结构与功能TCP/IP结构模型TCP/IP与OSI/RM的比较 网络地址与分配IP地址构成子网的划分IPv6 传输介质与网络设备网络传…...

sentinel熔断与限流
文章目录 一、sentinel简介Sentinel 是什么?Sentinel安装 二、sentinel整合工程新建cloudalibaba-sentinel-service8401微服务引入依赖yml配置主启动类添加EnableDiscoveryClient业务类测试 三、sentinel流控规则基本介绍流控模式直接(默认)关…...

vi/vim 编辑器 --基本命令
1 vi/vim编辑器介绍 vi 是visual interface 的简称,是Linux中最经典的文本编辑器 vim是vi的加强版。兼容了vi的所有指令,不仅能编辑文本,而且具有shell程序编辑的功能,可以通过不同颜色的字体辨别语法的正确性,极大…...
C++——STL标准模板库——容器详解——set
一、基本概念 set容器是一种具备自动排序功能的集合,默认递增排序;元素无法直接修改,且不能重复;另一个版本叫做multiset,允许存在重复元素,其他功能和性质一样。 set容器底层结构一般为自平衡二叉搜索树…...

Vim一键配置指南,打造高效率C++开发环境
文章目录 前言安装与卸载功能演示gcc/g升级问题 前言 Vim作为当下最受欢迎的文本编译器之一,不仅具有强大的文本编辑功能,还提供了高度的可定制性。用户可以根据自己的喜好自定义配置,并且通过自己编写插件或者使用现有的插件来扩展Vim的功能…...

新航向,新生态: Michael在出海业务圆桌会议分享HyperBDR全球业务拓展之道
1月15日-16日,以“领航新开局,共赢新生态”为主题的华为云生态大会2024在华为云贵安数据中心云上屯盛大举行。本次会议聚焦于华为云全国生态伙伴与开发者,旨在共同见证华为云生态战略的最新进展和伙伴政策的新升级。与会者将分享来自优秀生态…...
SpringBoot异步处理
Spring boot异步处理 业务场景: 如执行数据库备份任务,前端发起请求到后端,后端备份数据库的处理逻辑需要很长一段时间,此时前端会一直等待后端返回结果,给用户给等待时间过长,这是就要考虑异步处理了&…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...

接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一:HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二:Floyd 快慢指针法(…...

Win系统权限提升篇UAC绕过DLL劫持未引号路径可控服务全检项目
应用场景: 1、常规某个机器被钓鱼后门攻击后,我们需要做更高权限操作或权限维持等。 2、内网域中某个机器被钓鱼后门攻击后,我们需要对后续内网域做安全测试。 #Win10&11-BypassUAC自动提权-MSF&UACME 为了远程执行目标的exe或者b…...

Android Framework预装traceroute执行文件到system/bin下
文章目录 Android SDK中寻找traceroute代码内置traceroute到SDK中traceroute参数说明-I 参数(使用 ICMP Echo 请求)-T 参数(使用 TCP SYN 包) 相关文章 Android SDK中寻找traceroute代码 设备使用的是Android 11,在/s…...

Spring是如何实现无代理对象的循环依赖
无代理对象的循环依赖 什么是循环依赖解决方案实现方式测试验证 引入代理对象的影响创建代理对象问题分析 源码见:mini-spring 什么是循环依赖 循环依赖是指在对象创建过程中,两个或多个对象相互依赖,导致创建过程陷入死循环。以下通过一个简…...
ubuntu清理垃圾
windows和ubuntu 双系统,ubuntu 150GB,开发用,基本不装太多软件。但是磁盘基本用完。 1、查看home目录 sudo du -h -d 1 $HOME | grep -v K 上面的命令查看$HOME一级目录大小,发现 .cache 有26GB,.local 有几个GB&am…...