Django扩展自定义manage命令

使用django开发,对python manage.py ***命令模式肯定不会陌生。比较常用的有runserver,migrate。。。

本文讲述如何自定义扩展manage命令。

1、源码分析

manage.py文件是通过django-admin startproject project_name生成的。

1)manage.py的源码

a)首先设置了settings文件,本例中CIServer指的是project_name。

b)其次执行了一个函数django.core.management.execute_from_command_line(sys.argv),这个函数传入了命令行参数sys.argv

#!/usr/bin/env python
import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CIServer.settings")
    try:
        from django.core.management import execute_from_command_line
    except ImportError:
        raise ImportError(
            "Couldn‘t import Django. Are you sure it‘s installed and available "
            "on your PATH environment variable? Did you forget to activate a "
            "virtual environment?"
        )
    execute_from_command_line(sys.argv)

2)execute_from_command_line

里面调用了ManagementUtility类中的execute方法

def execute_from_command_line(argv=None):
    """
    A simple method that runs a ManagementUtility.
    """
    utility = ManagementUtility(argv)
    utility.execute()

在execute中主要是解析了传入的参数sys.argv,并且调用了get_command()

3)get_command

def get_commands():
    """
    Returns a dictionary mapping command names to their callback applications.

    This works by looking for a management.commands package in django.core, and
    in each installed application -- if a commands package exists, all commands
    in that package are registered.

    Core commands are always included. If a settings module has been
    specified, user-defined commands will also be included.

    The dictionary is in the format {command_name: app_name}. Key-value
    pairs from this dictionary can then be used in calls to
    load_command_class(app_name, command_name)

    If a specific version of a command must be loaded (e.g., with the
    startapp command), the instantiated module can be placed in the
    dictionary in place of the application name.

    The dictionary is cached on the first call and reused on subsequent
    calls.
    """
    commands = {name: ‘django.core‘ for name in find_commands(upath(__path__[0]))}

    if not settings.configured:
        return commands

    for app_config in reversed(list(apps.get_app_configs())):
        path = os.path.join(app_config.path, ‘management‘)
        commands.update({name: app_config.name for name in find_commands(path)})

    return commands

get_command里遍历所有注册的INSTALLED_APPS路径下的management寻找(find_commands)用户自定义的命令。

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‘)
    # Workaround for a Python 3.2 bug with pkgutil.iter_modules
    sys.path_importer_cache.pop(command_dir, None)
    return [name for _, name, is_pkg in pkgutil.iter_modules([npath(command_dir)])
            if not is_pkg and not name.startswith(‘_‘)]

可以发现并注册的命令是commands目录下不以"_"开头的文件名。

4)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()

5)Command类

Command类要继承BaseCommand类,其中很多方法,一定要实现的是handle方法,handle方法是命令实际执行的代码。

2、如何实现自定义命令

根据上面说的原理,我们只需要在app目录中建立一个目录management,并且在下面建立一个目录叫commands,下面增加一个文件,叫hello.py即可。

要注意一下几点

1)说是目录,其实应该是包,所以在management下面和commands下面都要添加__init__.py。

2)app一定要添加在INSTALLED_APPS中,不然命令加载不到。

应该是这样的

在hello.py中实现命令的具体内容

#-*- coding:utf-8 -*-
from django.core.management.base import BaseCommand, CommandError

class Command(BaseCommand):

    def add_arguments(self, parser):

        parser.add_argument(
            ‘-n‘,
            ‘--name‘,
            action=‘store‘,
            dest=‘name‘,
            default=‘close‘,
            help=‘name of author.‘,
        )

    def handle(self, *args, **options):
        try:
            if options[‘name‘]:
                print ‘hello world, %s‘ % options[‘name‘]

            self.stdout.write(self.style.SUCCESS(‘命令%s执行成功, 参数为%s‘ % (__file__, options[‘name‘])))
        except Exception, ex:
            self.stdout.write(self.style.ERROR(‘命令执行出错‘))

执行方式

python manage.py hello -n kangaroo

hello world, kangaroo命令hello.py执行成功,参数为kangaroo

原文地址:https://www.cnblogs.com/ExMan/p/9516878.html

时间: 2024-10-06 00:17:10

Django扩展自定义manage命令的相关文章

Django分析之如何自定义manage命令

我们都用过Django的manage.py的命令,而manage.py是在我们创建Django项目的时候就自动生成在根目录下的一个命令行工具,它可以执行一些简单的命令,其功能是将Django project放到sys.path目录中,同时设置DJANGO_SETTINGS_MODULE环境变量为当前project的setting.py文件.我们来看一下代码: #!/usr/bin/env python import os import sys if __name__ == "__main__&q

Django:manage命令扩展

每个学习django框架的童鞋都知道如何创建一个django项目和app,这都离不开django-admin.py和manage.py. django-admin.py是Django的一个用于管理任务的命令行工具,创建project就需要该命令行工具,另外,在每一个Django project中都会有一个manage.py. 想想当初,刚刚接触这些东西的时候,只知道死记硬背(想必很多人跟我一样),其实帮助工具要利用好,就像linux命令,有时候你知道某个命令但是忘记了它参数的含义,可以用帮助工具

【Django】如何自定义manage.py命令? 达到启动后台进程的目的?

代码: #-*- coding:utf-8 -*- """ The handle active user mail send """ from django.core.management.base import BaseCommand, CommandError from django.db import models #from placeholders import * import os import time import loggin

ValueError: Related model 'myapp.ExUser' cannot be resolved django扩展User字段

扩展字段目前有两种方法: 扩展字段 新建一张表->然后与原有表创建一对一关系 继承django.contrib.auth.models下的AbstractUser类 ,重写User类 两种方式都是官方文档提到的,,实现方法可以在官网以及搜索引擎搜到各大佬的博客上,我今天只分享一下自己遇到的问题及解决方法 我采用的是第2种, 重写User的方法,但是在迁移数据库的时候,遇到问题, 编写好其它表之后,发现User表中字段需要添加于是在models.py 文件中添加了 ExUser类 from dja

自定义django-admin命令

我们可以通过manage.py编写和注册自定义的命令. 自定义的管理命令对于独立脚本非常有用,特别是那些使用Linux的crontab服务,或者Windows的调度任务执行的脚本.比如,你有个需求,需要定时清空某篇文章下面的评论,一种解决方案就是写一个django-admin命令,再写一个运行该命令的独立脚本,最后通过crontab服务,定时执行该脚本. 下面,我们将为教程最开始的第一个Django应用中的polls应用编写一个自定义的closepoll命令. 一.创建management/co

Django的基本使用命令

本节主要是为了让您了解一些django最基本的命令,请尝试着记住它们,并且多多练习下,特别是标记为红色的那些 打开 Linux 或 MacOS 的 Terminal (终端)直接在 终端中输入这些命令(不是 python 的 shell中) 如果是 windows 用 cmd(开始 搜索 cmd 或者 快捷键 win + R,输入 cmd) 直接在 cmd 上操作. 1. 新建一个 django project 1 2 django-admin.py startproject project-n

Django使用自定义认证方式

Django使用自定义认证方式 创建登录应用 首先创建一个新的login app,用来存放认证用到代码 python manage.py startapp login 修改settings.py中的认证项 AUTHENTICATION_BACKENDS = ( 'login.auth.UsernamePasswordAuth', ) 自定义认证类 在login app下创建auth.py文件,内容如下 #coding:utf-8 from django.contrib.auth.models i

Spring Security4实战与原理分析视频课程( 扩展+自定义)

Spring Security概述与课程概要介绍 Spring Security快速入门(基于XML) Spring Security快速入门(基于XML) URL匹配详解 自定义登陆 配置退出 Ajax登陆退出 JDBC认证 层级角色关系 认证体系介绍 自定义认证 匿名认证 认证流程分析 配置权限 授权体系介绍 自定义授权 自定义JDBC授权 表达式权限原理分析 表达式权限扩展 自定义异常处理 过滤器分析 过滤器应用 FilterChainProxy初始化流程分析 授权流程分析 Spring

EasyUI 扩展自定义EasyUI校验规则 验证规则(常用的)

例如 校验输入框只能录入0-1000之间 最多有2位小数的数字 表单<input type="text" id="rate" name="rate" required="true" class="easyui-validatebox"  validType="rateCheck[0,1000]"  maxlength="6" /> $.extend($.f