Django manage.py 自定义命令

原理介绍

在创建Django项目时(使用django-admin或者通过pycharm创建)会生成一个manage.py文件, 这个文件中的内容如下:

import os
import sys


def main():
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.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()

 主要做两件事情:

  1.  设置环境变量 DJANGO_SETTINGS_MODULE为你的项目的配置文件
  2. excute_from_command_line()负责执行参数传递过来的指令 (例如:python manage.py runserver)

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

commands的创建方法:

  1. 在app中创建management目录
  2. 在management中创建commands目录
  3. 在commands中创建任意.py文件, 该文件即为启动命令

那django是如何找到我们定义的命令呢?

Django通过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函数找到命令实现类, 用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为例:

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')

加入文件名称为test.py

终端执行: python manage test 即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值