在Django开发过程中我们都用过django-admin.py和manage.py命令。

django-admin.py是一个命令行工具,可以执行一些管理任务,比如创建Django项目。而manage.py是在创建每个Django project时自动添加在项目目录下的,只是对manage.py的一个简单包装,其功能是将Django project放到sys.path目录中,同时设置DJANGO_SETTINGS_MODULE环境变量为当前project的setting.py文件。

Django 对于命令的添加有自己的一套规范,我们可以为每个app 指定命令。简单来书就是我们在使用manage.py文件执行命令的时候,可以自定制自己的命令,来实现命令的扩充。

对于自定义Command我们从两方面介绍一是内部执行原理,二是如何实行自定义Command

一、内部原理实现

django-admin.py调用django.core.management来执行命令:

创建django项目会自动生成manage.py文件:

  1. import os
  2. import sys
  3.  
  4. def main():
  5. os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'gaoyou.settings')
  6. try:
  7. from django.core.management import execute_from_command_line
  8. except ImportError as exc:
  9. raise ImportError(
  10. "Couldn't import Django. Are you sure it's installed and "
  11. "available on your PYTHONPATH environment variable? Did you "
  12. "forget to activate a virtual environment?"
  13. ) from exc
  14. execute_from_command_line(sys.argv)
  15.  
  16. if __name__ == '__main__':
  17. main()

excute_from_command_line()函数会根据命令行参数解析出命令的名称,根据命令名称调用相应的Command执行命令。Command位于各个管理模块的commands模块下面。

commands的创建方法:

  1. 1、在app内创建一个名字为:management文件夹(在你自己指定的应用下创建即可)
  2. 2、在management文件夹里面创建名为:commands的文件夹
  3. 3、在commands文件夹下创建名为:任意py文件(启动的时候就是根据该文件名进行启动的,注意:commands目录内都包含__init__.py文件)

此时py文件名就是你的自定制命令,我们可以使用下面方式进行执行

  1. python manage.py 命令名(即任意py文件名不用加.py)
  2. #类似我们迁移数据库命令
  3. #python manage.py makemigrations
  4. #python manage.py migrate

所谓管理模块,是指在app模块下的名字为management的模块。Django通过django.core.management.find_management_module函数发现"管理模块":

  1. django.core.management.find_management_module()
  2. def find_management_module(app_name):
  3. """
  4. Determines the path to the management module for the given app_name,
  5. without actually importing the application or the management module.
  6.  
  7. Raises ImportError if the management module cannot be found for any reason.
  8. """
  9. parts = app_name.split('.')
  10. parts.append('management')
  11. parts.reverse()
  12. part = parts.pop()
  13. path = None

然后通过django.core.management.find_commands函数找到命令类。find_commands函数会在管理模块下查找.py文件,并将.py文件的名称匹配到命令名称:

  1. def find_commands(management_dir):
  2. """
  3. Given a path to a management directory, returns a list of all the command
  4. names that are available.
  5.  
  6. Returns an empty list if no commands are defined.
  7. """
  8. command_dir = os.path.join(management_dir, 'commands')
  9. try:
  10. return [f[:-3] for f in os.listdir(command_dir)
  11. if not f.startswith('_') and f.endswith('.py')]
  12. except OSError:
  13. return []

最后,通过django.core.management.load_command_class函数加载该.py文件中的Command类:

  1. def load_command_class(app_name, name):
  2. """
  3. Given a command name and an application name, returns the Command
  4. class instance. All errors raised by the import process
  5. (ImportError, AttributeError) are allowed to propagate.
  6. """
  7. module = import_module('%s.management.commands.%s' % (app_name, name))
  8. return module.Command()

在执行命令的时候,会执行相应Command类的handle方法。所有的Command类都应该是django.core.management.base.BaseCommand的直接或间接子类。

二、自定义应用

Django的Command命令是要放到我们创建app下的management/commands目录下的(需自己手动创建该文件目录)。

注意:请确保management/commands目录下包含__init__.py文件

首先对于文件名可以自行定义没有要求,内部需要定义一个Command类并继承BaseCommand类或其子类。

  1. 它必须定义一个Command类并扩展自BaseCommand或其 子类。
  2. 其中help是command功能作用简介,handle函数是主处理程序,add_arguments函数是用来接收可选参数的(如果没有参数该方法可以不写)

我们通过在输入命令后再控制台输出一个hello world为例:

task.py

  1. from django.core.management.base import BaseCommand, CommandError
  2. from django.db import models
  3.  
  4. class Command(BaseCommand):
  5. help = '每日凌晨对当天数据库进行更新'
  6.  
  7. def handle(self, *args, **options):
  8. print('hello world')

在Terminal控制台将目录切换到你创建的Django项目目录下执行:python manage.py task

执行后即可在控制台看到输出hello world 说明自定义Commond成功!!!

如果在输入命令想要输出参数怎么办呢?例如:python mange.py task 参数

task.py

  1. from django.core.management.base import BaseCommand, CommandError
  2. from django.db import models
  3.  
  4. class Command(BaseCommand):
  5. help = '每日凌晨对当天数据库进行更新'
  6.  
  7. # 接收参数
  8. def add_arguments(self, parser):
  9. parser.add_argument('offset', type=int, help='天数转移量')
  10.  
  11. def handle(self, *args, **options):
  12. offset = options['offset'] # 拿到参数的值
  13. print(offset)
  14. print('hello world')
  15. self.stdout.write(self.style.SUCCESS('{} Successfully {}'.format('接收成功', offset))) #可以自定制在控制台输出的内容

在Terminal控制台将目录切换到你创建的Django项目目录下执行:python manage.py task 

自定义django-admin命令可以用来设置一些定时脚本,让其在指定的时间内进行运行

 

django实现自定义manage命令的扩展的更多相关文章

  1. Django扩展自定义manage命令

    使用django开发,对python manage.py ***命令模式肯定不会陌生.比较常用的有runserver,migrate... 本文讲述如何自定义扩展manage命令. 1.源码分析 ma ...

  2. Django分析之如何自定义manage命令

    我们都用过Django的manage.py的命令,而manage.py是在我们创建Django项目的时候就自动生成在根目录下的一个命令行工具,它可以执行一些简单的命令,其功能是将Django proj ...

  3. 在django项目中自定义manage命令(转)

    add by zhj 是我增加的注释 原文:http://www.cnblogs.com/holbrook/archive/2012/03/09/2387679.html 我们都用过Django的dj ...

  4. Django编写自定义manage.py 命令

    官网文档地址:编写自定义 django-admin 命令 金句: 你所浪费的今天,正是昨天死的人所期待的明天. 开篇话: python manage.py <command> 的命令我们用 ...

  5. Django项目中自定义manage命令

    挺不错的一篇文章:https://www.cnblogs.com/ajianbeyourself/p/3643304.html

  6. 【Django】如何自定义manage.py命令? 达到启动后台进程的目的?

    代码: #-*- coding:utf- -*- """ The handle active user mail send """ from ...

  7. 第六章:Django 综合篇 - 5:自定义django-admin命令

    我们可以通过manage.py编写和注册自定义的命令. 自定义的管理命令对于独立脚本非常有用,特别是那些使用Linux的crontab服务,或者Windows的调度任务执行的脚本.比如,你有个需求,需 ...

  8. 自定义django-admin命令

    我们可以通过manage.py编写和注册自定义的命令. 自定义的管理命令对于独立脚本非常有用,特别是那些使用Linux的crontab服务,或者Windows的调度任务执行的脚本.比如,你有个需求,需 ...

  9. Django 之 流程和命令行工具

    一.一个简单的web框架 框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单地说,就是你用别人搭建好的舞台来做表演. 对于所 ...

随机推荐

  1. TPL DataFlow .Net 数据流组件,了解一下

    回顾上文 作为单体程序,依赖的第三方服务虽不多,但是2C的程序还是有不少内容可讲: 作为一个常规互联网系统,无外乎就是接受请求.处理请求,输出响应. 由于业务渐渐增长,数据处理的过程会越来越复杂和冗长 ...

  2. IDEA为新手专业打造

    IDEA为新手专业打造 一.创建一个项目 新手的话可以先创建一个空项目 项目创建完成后会弹出一个Project Settings设置框,点击Project进行如图设置,设置完成点击OK 一.在创建的项 ...

  3. 魔道祖师 (作者:墨香铜臭)mobi格式下载

    下载地址:[点我]电视剧陈情令原著主要讲的是五大仙门世家的故事,其中主要讲述的就是魏无羡与蓝忘机之间的故事. 前世的魏无羡万人唾骂,声名狼藉. 被情同手足的师弟带人端了老巢, 纵横一世,死无全尸. 曾 ...

  4. JavaScript捕获与冒泡与委托

    事件捕获指的是从document到触发事件的那个节点,即自上而下的去触发事件. 相反的,事件冒泡是自下而上的去触发事件. 并不是所有的事件都能冒泡,以下事件不冒泡:blur.focus.load.un ...

  5. 《An Attentive Survey of Attention Models》阅读笔记

    本文是对文献 <An Attentive Survey of Attention Models> 的总结,详细内容请参照原文. 引言 注意力模型现在已经成为神经网络中的一个重要概念,并已经 ...

  6. springboot项目快速搭建

    1. 问题描述 springboot的面世,成为Java开发者的一大福音,大大提升了开发的效率,其实springboot只是在maven的基础上,对已有的maven gav进行了封装而已,今天用最简单 ...

  7. [NOIP2009]靶形数独 题解

    407. [NOIP2009] 靶形数独 时间限制:5 s   内存限制:128 MB [问题描述] 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低. ...

  8. idea中向pom.xml添加依赖时显示”not found dependency“

    总结: 起因:再输入hibernate-core的version时,开始写的是对的,就是 5.0.11.Final(这个也是跟着教程来的),直接就报错了,左等右等没用,也点过maven的reimpor ...

  9. C语言指针专题——如何理解指针

    本文为原创,欢迎转发! 最近在研读C primer plus 5版中文版,老外写的,还是很经典的,推荐给读者们,有需要的朋友可以在这里购买:C primer plus 5版中文版 指针,传说中是C语言 ...

  10. liunx某台服务器无法访问其他服务器!!!!!!!!

    针对于可以ping通ip地址,但是无法访问端口!!! 访问端口卡死,未响应, 例如mysql出现当前主机无法远程连接数据库,而其他主机都可以 前提条件:防火墙,mysql账号ip限制问题已经解决 问题 ...