zoukankan      html  css  js  c++  java
  • 在django项目中自定义manage命令(转)

    add by zhj 是我增加的注释

    原文:http://www.cnblogs.com/holbrook/archive/2012/03/09/2387679.html

    我们都用过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 文件。(add by zhj 如果只有一个django project,那用manage.py就可以了)


    django-admin.py调用django.core.management来执行命令:

    #!/usr/bin/env python
    from django.core import management

    if __name__ == "__main__":
    management.execute_from_command_line()

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

    所谓管理模块,是指在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的直接或间接子类。

    原理搞清楚了,扩展manage命令就很容易了。创建一个app并加入到settings的INSTALLED_APPS中,在该app下面创建management.commands模块,并创建hello.py文件,目录结构为(add by zhj)

    app_name
    ├── __init__.py ├── management │   ├── commands │   │   ├── __init__.py │   │   └── hello.py │   └── __init__.py ├── models.py ├── tests.py └── views.py

    hello.py文件如下

    复制代码
    from django.core.management.base import BaseCommand, CommandError
    from django.db import models
    #from placeholders import *
    import os

    class Command(BaseCommand):
    def handle(self, *args, **options):
    print 'hello, django!'
    复制代码

    就可以使用hello命令了:

    $ python manage.py hello
    hello, django!

  • 相关阅读:
    [原]Linux ssh远程连接断开问题处理办法
    【网摘】CURL常用命令
    【树莓派】在树莓派中进行截图
    【树莓派】树莓派移动网络连接(配置4G网卡)
    【树莓派】基于TinyProxy搭建HTTP代理服务器
    【树莓派】制作树莓派所使用的img镜像(二)
    【树莓派】制作树莓派所使用的img镜像(一)
    macaca运行报错之chrome-driver问题处理,关闭 Chrome 的自动更新
    Git使用
    Longest Consecutive Sequence leetcode java
  • 原文地址:https://www.cnblogs.com/ajianbeyourself/p/3643304.html
Copyright © 2011-2022 走看看