中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

詳解django實現自定義manage命令的擴展

發布時間:2020-10-23 20:53:08 來源:腳本之家 閱讀:189 作者:迎風而來 欄目:開發技術

在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 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()函數會根據命令行參數解析出命令的名稱,根據命令名稱調用相應的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類或其子類。

  1. 它必須定義一個Command類并擴展自BaseCommand或其 子類。
  2. 其中help是command功能作用簡介,handle函數是主處理程序,add_arguments函數是用來接收可選參數的( 如果沒有參數該方法可以不寫 )

我們通過在輸入命令后再控制臺輸出一個hello world為例:

task.py

from django.core.management.base import BaseCommand, CommandError
from django.db import models

class 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, CommandError
from django.db import models


class Command(BaseCommand):
  help = '每日凌晨對當天數據庫進行更新'

  # 接收參數
  def add_arguments(self, parser):
    parser.add_argument('offset', type=int, help='天數轉移量')

  def handle(self, *args, **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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

镇巴县| 太湖县| 惠来县| 平定县| 赤峰市| 贡觉县| 九江县| 山丹县| 百色市| 托克逊县| 棋牌| 信宜市| 阜新| 运城市| 淅川县| 平谷区| 昌乐县| 石河子市| 梨树县| 洛阳市| 麻城市| 鹤山市| 长沙县| 北流市| 原阳县| 松江区| 蛟河市| 乌恰县| 普格县| 巩义市| 林西县| 白水县| 诸暨市| 维西| 济阳县| 吕梁市| 乌鲁木齐市| 浦东新区| 德钦县| 商都县| 自治县|