如何在 Django 中創(chuàng)建自定義的管理命令
用過(guò) Django 的朋友應(yīng)該最熟悉這三個(gè)命令:
python?manage.py?runserver
python?manage.py?makemigrations
python?manage.py?migrate
非常方便,不是嗎?那其實(shí),我們也可以自定義這樣的命令,來(lái)提高我們的開(kāi)發(fā)效率。
今天就來(lái)分享如何在 Django 中創(chuàng)建自定義的管理命令。
和 Django 的模版 template 一樣,自定義的命令也遵循一定的路徑格式。
在每個(gè) app 目錄下,新建一個(gè) management/commands 目錄,Django 會(huì)給目錄下的每個(gè) Python 文件注冊(cè)一個(gè) manage.py 命令,這個(gè)命令的名字不以下劃線(xiàn)開(kāi)頭。例如:
polls/
????__init__.py
????models.py
????management/
????????__init__.py
????????commands/
????????????__init__.py
????????????_private.py
????????????closepoll.py
????tests.py
????views.py
請(qǐng)注意,上述路徑中的 _private.py 不會(huì)生效。polls 需要在 settings.py 中的 INSTALLED_APPS 中注冊(cè),python manage.py closepoll 才會(huì)生效。
接下來(lái)說(shuō)下 closepoll 這個(gè)文件的格式。
對(duì) closepoll.py 模塊只有一個(gè)要求,那就是必須定義 Command 類(lèi),該類(lèi)繼承自 BaseCommand 或其子類(lèi)。
比如像這樣:
from?django.core.management.base?import?BaseCommand,?CommandError
class?Command(BaseCommand):
????help?=?'Closes?the?specified?poll?for?voting'
????def?add_arguments(self,?parser):
????????parser.add_argument('poll_ids',?nargs='+',?type=int)
????def?handle(self,?*args,?**options):
????????for?poll_id?in?options['poll_ids']:
????????????print(f"closing?{poll_id}?done.")
????????????#do?something?here
????????????self.stdout.write(self.style.SUCCESS('Successfully?closed?poll?"%s"'?%?poll_id))
通常,主要的處理邏輯會(huì)放在 handle 函數(shù)里面,在 INSTALLED_APPS 中添加 polls 后,運(yùn)行一下 python manage.py closepoll 1 2 3 會(huì)得到如下結(jié)果:
當(dāng)你使用管理命令并希望提供控制臺(tái)輸出時(shí),你需要 write 至 self.stdout 和 self.stderr,而不是直接 print 至 stdout 和 stderr,這樣可以輸出多彩的結(jié)果。還需要注意的是,你不需要用換行符來(lái)結(jié)束消息,它會(huì)自動(dòng)添加,除非你指定了 ending 參數(shù):
self.stdout.write("Unterminated?line",?ending='')
還可以為命令添加可選參數(shù),通過(guò)接受額外的命令行選項(xiàng)來(lái)刪除一個(gè)給定的投票,而不是關(guān)閉它。這些自定義選項(xiàng)可以在 add_arguments() 方法中添加,比如:
class?Command(BaseCommand):
????def?add_arguments(self,?parser):
????????#?Positional?arguments
????????parser.add_argument('poll_ids',?nargs='+',?type=int)
????????#?Named?(optional)?arguments
????????parser.add_argument(
????????????'--delete',
????????????action='store_true',
????????????help='Delete?poll?instead?of?closing?it',
????????)
????def?handle(self,?*args,?**options):
????????#?...
????????if?options['delete']:
????????????poll.delete()
????????#?...
本例中 delete 是由 handle 方法的 options 字典參數(shù)傳入的,參見(jiàn) Python 文檔查詢(xún) argparse,獲取更多 add_argument 的用法。
最后的話(huà)
自定義管理命令在運(yùn)行獨(dú)立腳本命令方面十分有用,也可用于 UNIX 的周期性 crontab 任務(wù),或是 Windows 的定時(shí)任務(wù)。如果今天的分享有幫助,還請(qǐng)給個(gè)在看,多謝支持。
