广告
返回顶部
首页 > 资讯 > 后端开发 > Python >django如何自定义manage.py管理命令
  • 562
分享到

django如何自定义manage.py管理命令

2024-04-02 19:04:59 562人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录创建文件夹布局编写命令代码实际应用场景案例1:检查数据库连接是否已就绪案例2:周期性发送邮件每次在启动Django服务之前,我们都会在终端运行python manage.py x

每次在启动Django服务之前,我们都会在终端运行python manage.py xxx的管理命令。其实我们还可以自定义管理命令,这对于执行独立的脚本或任务非常有用,比如清除缓存、导出用户邮件清单或发送邮件等等。

自定义的管理命令不仅可以通过manage.py运行,还可以通过linux或Celery的crontab服务将其设成定时任务。本文主要讲解如何自定义DjanGo-admin命令,并提供一些演示案例。

自定义Django-admin命令一共分三步:创建文件夹布局、编写命令代码和测试使用。

创建文件夹布局

自定义的Django-admin管理命令本质上是一个Python脚本文件,它的存放路径必须遵循一定的规范,一般位于app/management/commands目录。整个文件夹的布局如下所示:


 app01/
    __init__.py
    models.py
    management/
        __init__.py
        commands/
            __init__.py
            _private.py # 以下划线开头文件不能用作管理命令
            my_commands.py # 这个就是自定义的管理命令脚本,文件名即为命令名
    tests.py
    views.py

注意:

  • management和commands每个目录下都必须有个__init__.py空文件,表明这是一个python包。另外以下划线开头的文件名不能用作管理命令脚本。
  • management/commands目录可以位于任何一个app的目录下,Django都能找到它。
  • 一般建议每个python脚本文件对应一条管理命令。

编写命令代码

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


 from django.core.management.base import BaseCommand
 
 class Command(BaseCommand):
     # 帮助文本, 一般备注命令的用途及如何使用。
     help = 'Some help texts'
 
     # 处理命令行参数,可选
     def add_arguments(self, parser):
        pass
 
     # 核心业务逻辑
     def handle(self, *args, **options):
         pass

我们现在来看一个最简单的例子,希望定义一个名为hello_world的命令。这样当我们运行python manage.py hello_world命令时,控制台会打印出Hello World!字样。在app/management/commands目录下新建hello_world.py, 添加如下代码:


 from django.core.management.base import BaseCommand
 
 class Command(BaseCommand):
    # 帮助文本, 一般备注命令的用途及如何使用。
    help = "Print Hello World!"
 
    # 核心业务逻辑
    def handle(self, *args, **options):
        self.stdout.write('Hello World!')

注意:当你使用管理命令并希望在控制台输出指定信息时,你应该使用self.stdout和self.stderr方法,而不能直接使用python的print方法。另外,你不需要在消息的末尾加上换行符,它将被自动添加。

此时当你进入项目文件夹运行python manage.py hello_world命令时,你将得到如下输出结果:

现在我们来增加点难度,来通过命令行给hello_world命令传递一个name参数,以实现运行python manage.py helloworld John命令时 打印出Hello World! John。

现在修改我们的hello_world.py, 添加add_arguments方法,该方法的作用是给自定义的handle方法添加1个或多个参数。


 from django.core.management.base import BaseCommand
 
 class Command(BaseCommand):
    # 帮助文本, 一般备注命令的用途及如何使用。
    help = "Print Hello World!"
 
    # 给命令添加一个名为name的参数
    def add_arguments(self, parser):
        parser.add_argument('name')
 
    # 核心业务逻辑,通过options字典接收name参数值,拼接字符串后输出
    def handle(self, *args, **options):
        msg = 'Hello World ! '+ options['name']
        self.stdout.write(msg)

此时当你再次运行python manage.py hello_world John命令时,你将得到如下输出结果:

如果你直接运行命令而不携带参数,将会报错,如下所示:

实际应用场景

前面的案例过于简单,我们现在来看两个自定义管理命令的实际应用案例。

案例1:检查数据库连接是否已就绪

无论你使用常规方式还是Docker在生产环境中部署Django项目,你需要确保数据库连接已就绪后才进行数据库迁移(migrate)的命令(Docker-compose的depends选项并不能确保这点),否则Django应用程序会出现报错。

这时你可以自定义一个wait_for_db的命令,如下所示:


 # app/management/commands/wait_for_db.py
 
 import time
 from django.db import connections
 from django.db.utils import OperationalError
 from django.core.management import BaseCommand
 
 
 class Command(BaseCommand):
     help = 'Run data migrations until db is available.'
 
     def handle(self, *args, **options):
         self.stdout.write('Waiting for database...')
         db_conn = None
         while not db_conn:
             try:
                 # 尝试连接
                 db_conn = connections['default']
             except OperationalError:
                 # 连接失败,就等待1秒钟
                 self.stdout.write('Database unavailable, waiting 1 second...')
                 time.sleep(1)
 
         self.stdout.write(self.style.SUCCESS('Database available!'))

定义好这个命令后每次在运行python manage.py migrate命令前先运行python manage.py wait_for_db即可。

案例2:周期性发送邮件

如果你是网站管理员,你肯定希望知道每天有多少新用户已注册,这时你可以自定义一条mail_admin的管理命令,将每天新注册用户数量以邮件形式发给自己,如下所示:


 # app/management/commands/mail_admin.py
 
 #-*- coding:utf-8 -*-
 from datetime import timedelta, time, datetime
 from django.core.mail import mail_admins
 from django.core.management import BaseCommand
 from django.utils import timezone
 from django.contrib.auth import get_user_model
 
 User = get_user_model()
 
 today = timezone.now()
 yesterday = today - timedelta(1)
 
 
 class Command(BaseCommand):
     help = "Send The Daily Count of New Users to Admins"
 
     def handle(self, *args, **options):
         # 获取过去一天注册用户数量
         user_count =User.objects.filter(date_joined__range=(yesterday, today)).count()
         
         # 当注册用户数量多余1个,才发送邮件给管理员
         if user_count >= 1:
             message = "You have got {} user(s) in the past 24 hours".fORMat(user_count)
 
             subject = (
                 f"New user count for {today.strftime('%Y-%m-%d')}: {user_count}"
            )
 
             mail_admins(subject=subject, message=message, html_message=None)
 
             self.stdout.write("E-mail was sent.")
         else:
             self.stdout.write("No new users today.")

如果你在终端运行python manage.py mail_admin命令,你将得到如下输出结果:

注意:真正发送邮件成功需要设置Email后台及管理员,测试环境下可以使用如下简单配置:


 EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
 DEFAULT_FROM_EMAIL = "noreply@example.com"
 ADMINS = [("大江狗", "yunbo.shi@example.com"), ]

但是如果每天都要进入终端运行这个命令实在太麻烦了,我们完全可以使用Linux的crontab服务或Celery-Beat将其设成周期性定时任务task,这时只需要调用Django的call_command方法即可。


 # app/tasks.py, 可以任一app目录下新建task
 from celery import shared_task
 from django.core.management import call_command
 
 @shared_task
 def mail_admin():
     call_command("mail_admin", )

关于Django项目中如何使用Celery执行异步和周期性任务,请参加下篇Django进阶-异步和周期任务篇。

以上就是django如何自定义manage.py管理命令的详细内容,更多关于django 自定义manage.py管理命令的资料请关注编程网其它相关文章!

--结束END--

本文标题: django如何自定义manage.py管理命令

本文链接: https://www.lsjlt.com/news/124749.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • django如何自定义manage.py管理命令
    目录创建文件夹布局编写命令代码实际应用场景案例1:检查数据库连接是否已就绪案例2:周期性发送邮件每次在启动Django服务之前,我们都会在终端运行python manage.py x...
    99+
    2022-11-12
  • linux中如何定义自己的命令
    这篇文章主要介绍linux中如何定义自己的命令,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!学习如何创建别名:你可以将太长或难以记忆的命令打包成你自己构建的命令。命令别名Alias在 Linux shell 中指的是...
    99+
    2023-06-16
  • Django 自定义模型管理器类2个应用
    class BookManager(models.Manager): # 改变查询集的结果集 def all(self): books = super().all() # QuerySet ...
    99+
    2023-01-30
    自定义 管理器 模型
  • vue如何自定义配置运行run命令
    目录1、vuecli3以下package.jsonbuild/build.jswebpack.prod.conf.jsbuild/utils.jsbuild/webpack.base...
    99+
    2022-11-13
  • 如何在Linux中自定义bash命令提示符
    前言 众所周知, bash (the B ourne- A gain Sh ell)是目前绝大多数 linux 发行版使用的默认 shell。本文将会介绍如何通过添加颜色和样式来自定义 bash 命令提示符的显示。尽管很...
    99+
    2022-06-04
    linux bash命令 linux-bash linux自定义bash
  • 在Linux上如何自定义bash命令提示符
    这篇文章给大家分享的是有关在Linux上如何自定义bash命令提示符的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。在 Linux 中自定义 bash 命令提示符在 bash 中,我们可以通过更改 $PS...
    99+
    2023-06-16
  • Angular.js如何自定义指令
    这篇文章主要介绍了Angular.js如何自定义指令,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。具体代码如下所示:<!DOCTYPE...
    99+
    2022-10-19
  • 如何用特定命令管理 Linux进程
    这篇文章主要讲解了“如何用特定命令管理 Linux进程”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何用特定命令管理 Linux进程”吧!进程(process)是指正在执行的程序;是程序正...
    99+
    2023-06-16
  • Django rest framework如何自定义用户表
    目录说明1. Django项目和应用创建2. 自定义User表3. 序列化和路由3. DRF配置4. 同步数据库5. 测试6. 命令行注册用户说明 Django 默认的用户表 aut...
    99+
    2022-11-12
  • Vue中如何自定义指令
    这篇文章主要介绍Vue中如何自定义指令,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Vue中除了内置指令,也允许注册自定义的指令。自定义指令提供一种将数据的变化映射为DOM的行为例如:当我们想用一个函数表示焦点Vue...
    99+
    2023-06-04
  • vue如何自定义加载指令
    本文小编为大家详细介绍“vue如何自定义加载指令”,内容详细,步骤清晰,细节处理妥当,希望这篇“vue如何自定义加载指令”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。前言用过element-ui的都应该知道,里面...
    99+
    2023-07-02
  • vue如何使用自定义指令
    这篇文章将为大家详细讲解有关vue如何使用自定义指令,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 使用自定义指令的逻辑与使用事件修饰符的逻辑...
    99+
    2022-10-19
  • Vue中如何使用自定义指令
    今天就跟大家聊聊有关Vue中如何使用自定义指令,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1.自定义指令的语法Vue自定义指令语法如下:Vue.d...
    99+
    2022-10-19
  • Angular中如何自定义创建指令
    小编给大家分享一下Angular中如何自定义创建指令,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!指令介绍在 Angular 中有三种类型的指令:组件,有模板的指...
    99+
    2023-06-14
  • vue中的自定义指令如何使用
    这篇文章主要介绍“vue中的自定义指令如何使用”,在日常操作中,相信很多人在vue中的自定义指令如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”vue中的自定义指令如何使用”的疑惑有所帮助!接下来,请跟...
    99+
    2023-06-29
  • 如何写一个Vue3的自定义指令
    目录背景插件指令的实现前端巅峰 以下文章来源于微信公众号前端巅峰 背景 众所周知,Vue.js 的核心思想是数据驱动 + 组件化,通常我们开发页面的过程就是在编写一些组件,...
    99+
    2022-11-12
  • Vue如何自定义指令回顾v-内置指令
    这篇文章主要介绍了Vue如何自定义指令回顾v-内置指令,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Vue.js 的各种指令(Directi...
    99+
    2022-10-19
  • Angular中如何实现自定义管道
    这篇文章给大家分享的是有关Angular中如何实现自定义管道的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、管道的作用方便我们在模板中对我们的数据进行格式化处理。二、内置的常用...
    99+
    2022-10-19
  • 如何使用linux shell 管道命令及管道命令与shell重定向区别
    这篇文章主要介绍“如何使用linux shell 管道命令及与shell重定向区别”,在日常操作中,相信很多人在如何使用linux shell 管道命令及与shell重定向区别问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希...
    99+
    2023-06-09
  • Linux管道命令该如何理解
    这期内容当中小编将会给大家带来有关Linux管道命令该如何理解,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。 示例假设我们想要知道 /etc/ 底下有多少文件,那么可以利用 ls /etc 来查...
    99+
    2023-06-28
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作