詳解django實(shí)現(xiàn)自定義manage命令的擴(kuò)展
在Django開(kāi)發(fā)過(guò)程中我們都用過(guò)django-admin.py和manage.py命令。
django-admin.py是一個(gè)命令行工具,可以執(zhí)行一些管理任務(wù),比如創(chuàng)建Django項(xiàng)目。而manage.py是在創(chuàng)建每個(gè)Django project時(shí)自動(dòng)添加在項(xiàng)目目錄下的,只是對(duì)manage.py的一個(gè)簡(jiǎn)單包裝,其功能是將Django project放到sys.path目錄中,同時(shí)設(shè)置DJANGO_SETTINGS_MODULE環(huán)境變量為當(dāng)前project的setting.py文件。
Django 對(duì)于命令的添加有自己的一套規(guī)范,我們可以為每個(gè)app 指定命令。簡(jiǎn)單來(lái)書(shū)就是我們?cè)谑褂胢anage.py文件執(zhí)行命令的時(shí)候,可以自定制自己的命令,來(lái)實(shí)現(xiàn)命令的擴(kuò)充。
對(duì)于自定義Command我們從兩方面介紹一是內(nèi)部執(zhí)行原理,二是如何實(shí)行自定義Command
一、內(nèi)部原理實(shí)現(xiàn)
django-admin.py調(diào)用django.core.management來(lái)執(zhí)行命令:
創(chuàng)建django項(xiàng)目會(huì)自動(dòng)生成manage.py文件:
import os import sys def 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()函數(shù)會(huì)根據(jù)命令行參數(shù)解析出命令的名稱(chēng),根據(jù)命令名稱(chēng)調(diào)用相應(yīng)的Command執(zhí)行命令。Command位于各個(gè)管理模塊的commands模塊下面。
commands的創(chuàng)建方法:
1、在app內(nèi)創(chuàng)建一個(gè)名字為:management文件夾(在你自己指定的應(yīng)用下創(chuàng)建即可)
2、在management文件夾里面創(chuàng)建名為:commands的文件夾
3、在commands文件夾下創(chuàng)建名為:任意py文件(啟動(dòng)的時(shí)候就是根據(jù)該文件名進(jìn)行啟動(dòng)的,注意:commands目錄內(nèi)都包含__init__.py文件)
此時(shí)py文件名就是你的自定制命令,我們可以使用下面方式進(jìn)行執(zhí)行
python manage.py 命令名(即任意py文件名不用加.py) #類(lèi)似我們遷移數(shù)據(jù)庫(kù)命令 #python manage.py makemigrations #python manage.py migrate
所謂管理模塊,是指在app模塊下的名字為management的模塊。Django通過(guò)
django.core.management.find_management_module函數(shù)發(fā)現(xiàn)"管理模塊": 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
然后通過(guò)django.core.management.find_commands函數(shù)找到命令類(lèi)。find_commands函數(shù)會(huì)在管理模塊下查找.py文件,并將.py文件的名稱(chēng)匹配到命令名稱(chēng):
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 []
最后,通過(guò)django.core.management.load_command_class函數(shù)加載該.py文件中的Command類(lèi):
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()
在執(zhí)行命令的時(shí)候,會(huì)執(zhí)行相應(yīng)Command類(lèi)的handle方法。所有的Command類(lèi)都應(yīng)該是django.core.management.base.BaseCommand的直接或間接子類(lèi)。
二、自定義應(yīng)用
Django的Command命令是要放到我們創(chuàng)建app下的management/commands目錄下的( 需自己手動(dòng)創(chuàng)建該文件目錄 )。
注意:請(qǐng)確保management/commands目錄下包含 __init__.py 文件
首先對(duì)于文件名可以自行定義沒(méi)有要求,內(nèi)部需要定義一個(gè)Command類(lèi)并繼承BaseCommand類(lèi)或其子類(lèi)。
- 它必須定義一個(gè)Command類(lèi)并擴(kuò)展自BaseCommand或其 子類(lèi)。
- 其中help是command功能作用簡(jiǎn)介,handle函數(shù)是主處理程序,add_arguments函數(shù)是用來(lái)接收可選參數(shù)的( 如果沒(méi)有參數(shù)該方法可以不寫(xiě) )
我們通過(guò)在輸入命令后再控制臺(tái)輸出一個(gè)hello world為例:
task.py
from django.core.management.base import BaseCommand, CommandError from django.db import models class Command(BaseCommand): help = '每日凌晨對(duì)當(dāng)天數(shù)據(jù)庫(kù)進(jìn)行更新' def handle(self, *args, **options): print('hello world')
在Terminal控制臺(tái)將目錄切換到你創(chuàng)建的Django項(xiàng)目目錄下執(zhí)行: python manage.py task
執(zhí)行后即可在控制臺(tái)看到輸出hello world 說(shuō)明自定義Commond成功?。?!
如果在輸入命令想要輸出參數(shù)怎么辦呢?例如: python mange.py task 參數(shù)
task.py
from django.core.management.base import BaseCommand, CommandError from django.db import models class Command(BaseCommand): help = '每日凌晨對(duì)當(dāng)天數(shù)據(jù)庫(kù)進(jìn)行更新' # 接收參數(shù) def add_arguments(self, parser): parser.add_argument('offset', type=int, help='天數(shù)轉(zhuǎn)移量') def handle(self, *args, **options): offset = options['offset'] # 拿到參數(shù)的值 print(offset) print('hello world') self.stdout.write(self.style.SUCCESS('{} Successfully {}'.format('接收成功', offset))) #可以自定制在控制臺(tái)輸出的內(nèi)容
在Terminal控制臺(tái)將目錄切換到你創(chuàng)建的Django項(xiàng)目目錄下執(zhí)行: python manage.py task 1314
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
pytho多張圖片的無(wú)損拼接的實(shí)現(xiàn)示例
很多人都會(huì)是用PS進(jìn)行拼接,本文主要介紹了pytho多張圖片的無(wú)損拼接的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07Python異步庫(kù)asyncio、aiohttp詳解
這篇文章主要介紹了Python異步庫(kù)asyncio、aiohttp使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06Tensorflow簡(jiǎn)單驗(yàn)證碼識(shí)別應(yīng)用
這篇文章主要為大家詳細(xì)介紹了Tensorflow簡(jiǎn)單驗(yàn)證碼識(shí)別應(yīng)用的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05Python添加進(jìn)度條tqdm進(jìn)階使用實(shí)例
這篇文章主要為大家介紹了Python添加進(jìn)度條tqdm進(jìn)階使用實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06解決python問(wèn)題 Traceback (most recent call&n
這篇文章主要介紹了解決python問(wèn)題 Traceback (most recent call last),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12