django实现自定义manage命令的扩展

django实现自定义manage命令的扩展,第1张

概述在Django开发过程中我们都用过django-admin.py和manage.py命令。 django-admin.py是一个命令行工具,可以执行一些管理任务,比如创建Django项目。而manage.py是在创建每个Django project时自动添加在项目目录下的,只是对manage.py的一个简单包装,其功能是将Django project放到sys.path目录中,同时设置DJANGO

在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文件:

import osimport sysdef main():    os.environ.setdefault(DJANGO_SETTINGS_MODulE,gaoyou.settings)    try:        from django.core.management import execute_from_command_line except importError as exc:        raise importError(            "Couldn‘t import Django. Are you sure it‘s installed and "            "available on your PYTHONPATH environment variable? DID you "            "forget to activate a virtual environment?"        ) from exc    execute_from_command_line(sys.argv)if __name__ == __main__:    main()

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

commands的创建方法:

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

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

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

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

django.core.management.find_management_module()def find_management_module(app_name):    """    Determines the path to the management module for the given app_name,without actually importing the application or the management module.    Raises importError if the management module cannot be found for any reason.    """    parts = app_name.split(.)    parts.append(management)    parts.reverse()    part = parts.pop()    path = None

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

def find_commands(management_dir):    """    Given a path to a management directory,returns a List of all the command    names that are available.    Returns an empty List if no commands are defined.    """    command_dir = os.path.join(management_dir,commands)    try:        return [f[:-3] for f in os.Listdir(command_dir)           if not f.startswith(_) and f.endswith(.py)]    except OSError:    return []

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

def load_command_class(app_name,name):    """    Given a command name and an application name,returns the Command    class instance. All errors raised by the import process    (importError,AttributeError) are allowed to propagate.    """    module = import_module(%s.management.commands.%s % (app_name,name))    return module.Command()

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

二、自定义应用

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

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

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

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

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

task.py

from django.core.management.base import BaseCommand,CommandErrorfrom django.db import modelsclass Command(BaseCommand):    help = 每日凌晨对当天数据库进行更新    def handle(self,*args,**options):        print(hello world)

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

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

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

task.py

from django.core.management.base import BaseCommand,CommandErrorfrom django.db import modelsclass Command(BaseCommand):    help = 每日凌晨对当天数据库进行更新    # 接收参数    def add_arguments(self,parser):        parser.add_argument(offset,type=int,help=天数转移量)    def handle(self,**options):        offset = options[‘offset‘]  # 拿到参数的值        print(offset)        print(hello world)        self.stdout.write(self.style.SUCCESS({} Successfully {}.format(接收成功,offset)))  #可以自定制在控制台输出的内容

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

总结

以上是内存溢出为你收集整理的django实现自定义manage命令的扩展全部内容,希望文章能够帮你解决django实现自定义manage命令的扩展所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1191956.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存