详解django实现自定义manage命令的扩展
在Django开发过程中我们都用过django-admin.py和manage.py命令。
django-admin.py是一个命令行工具,可以执行一些管理任务,比如创建Django项目。而manage.py是在创建每个Djangoproject时自动添加在项目目录下的,只是对manage.py的一个简单包装,其功能是将Djangoproject放到sys.path目录中,同时设置DJANGO_SETTINGS_MODULE环境变量为当前project的setting.py文件。
Django对于命令的添加有自己的一套规范,我们可以为每个app指定命令。简单来书就是我们在使用manage.py文件执行命令的时候,可以自定制自己的命令,来实现命令的扩充。
对于自定义Command我们从两方面介绍一是内部执行原理,二是如何实行自定义Command
一、内部原理实现
django-admin.py调用django.core.management来执行命令:
创建django项目会自动生成manage.py文件:
importos
importsys
defmain():
os.environ.setdefault('DJANGO_SETTINGS_MODULE','gaoyou.settings')
try:
fromdjango.core.managementimportexecute_from_command_line
exceptImportErrorasexc:
raiseImportError(
"Couldn'timportDjango.Areyousureit'sinstalledand"
"availableonyourPYTHONPATHenvironmentvariable?Didyou"
"forgettoactivateavirtualenvironment?"
)fromexc
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文件名就是你的自定制命令,我们可以使用下面方式进行执行
pythonmanage.py命令名(即任意py文件名不用加.py) #类似我们迁移数据库命令 #pythonmanage.pymakemigrations #pythonmanage.pymigrate
所谓管理模块,是指在app模块下的名字为management的模块。Django通过
django.core.management.find_management_module函数发现"管理模块":
django.core.management.find_management_module()
deffind_management_module(app_name):
"""
Determinesthepathtothemanagementmoduleforthegivenapp_name,
withoutactuallyimportingtheapplicationorthemanagementmodule.
RaisesImportErrorifthemanagementmodulecannotbefoundforanyreason.
"""
parts=app_name.split('.')
parts.append('management')
parts.reverse()
part=parts.pop()
path=None
然后通过django.core.management.find_commands函数找到命令类。find_commands函数会在管理模块下查找.py文件,并将.py文件的名称匹配到命令名称:
deffind_commands(management_dir):
"""
Givenapathtoamanagementdirectory,returnsalistofallthecommand
namesthatareavailable.
Returnsanemptylistifnocommandsaredefined.
"""
command_dir=os.path.join(management_dir,'commands')
try:
return[f[:-3]forfinos.listdir(command_dir)
ifnotf.startswith('_')andf.endswith('.py')]
exceptOSError:
return[]
最后,通过django.core.management.load_command_class函数加载该.py文件中的Command类:
defload_command_class(app_name,name):
"""
Givenacommandnameandanapplicationname,returnstheCommand
classinstance.Allerrorsraisedbytheimportprocess
(ImportError,AttributeError)areallowedtopropagate.
"""
module=import_module('%s.management.commands.%s'%(app_name,name))
returnmodule.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函数是用来接收可选参数的( 如果没有参数该方法可以不写)
我们通过在输入命令后再控制台输出一个helloworld为例:
task.py
fromdjango.core.management.baseimportBaseCommand,CommandError
fromdjango.dbimportmodels
classCommand(BaseCommand):
help='每日凌晨对当天数据库进行更新'
defhandle(self,*args,**options):
print('helloworld')
在Terminal控制台将目录切换到你创建的Django项目目录下执行: pythonmanage.pytask
执行后即可在控制台看到输出helloworld说明自定义Commond成功!!!
如果在输入命令想要输出参数怎么办呢?例如: pythonmange.pytask 参数
task.py
fromdjango.core.management.baseimportBaseCommand,CommandError
fromdjango.dbimportmodels
classCommand(BaseCommand):
help='每日凌晨对当天数据库进行更新'
#接收参数
defadd_arguments(self,parser):
parser.add_argument('offset',type=int,help='天数转移量')
defhandle(self,*args,**options):
offset=options['offset']#拿到参数的值
print(offset)
print('helloworld')
self.stdout.write(self.style.SUCCESS('{}Successfully{}'.format('接收成功',offset)))#可以自定制在控制台输出的内容
在Terminal控制台将目录切换到你创建的Django项目目录下执行: pythonmanage.pytask 1314
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。