Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 有没有一种方法可以向现有的django命令添加功能?_Python_Django - Fatal编程技术网

Python 有没有一种方法可以向现有的django命令添加功能?

Python 有没有一种方法可以向现有的django命令添加功能?,python,django,Python,Django,我想在Adjango命令启动之前运行一个命令 例如: $ python manage.py runserver Validating models... 0 errors found Django version 1.3, using settings 'creat1va.settings' Development server is running at http://127.0.0.1:8000/ Quit the server with CONTROL-C. (started some

我想在Adjango命令启动之前运行一个命令

例如:

$ python manage.py runserver
Validating models...

0 errors found
Django version 1.3, using settings 'creat1va.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
(started some command in the background)
[10/Jul/2011 21:50:26] "GET / HTTP/1.1" 200 1611
[10/Jul/2011 21:50:26] "GET /assets/css/master.css HTTP/1.1" 404 1783
[10/Jul/2011 21:50:26] "GET /assets/images/misc/logo.png HTTP/1.1" 404 1801
[10/Jul/2011 21:50:26] "GET /assets/images/icons/bo.gif HTTP/1.1" 404 1798
[10/Jul/2011 21:50:28] (My background process) "Some nice Feedback"
其主要思想是启动后台进程,并输出日志记录


有没有一种方法可以在不破坏django源代码的情况下实现这一点?

在运行命令的应用程序中编写自己的管理命令,然后调用django的内置实现。

只要意识到,您可以轻松地覆盖命令,就像使用同名命令创建应用程序一样

因此,我创建了一个应用程序,并创建了一个与runserver同名的文件,然后在运行之前扩展runserver基类以添加新功能

例如,我希望在runserver启动之前运行$compass watch命令,并使其在runserver执行过程中保持运行

"""
Start $compass watch, command when you do $python manage.py runserver

file: main/management/commands/runserver.py

Add ´main´ app to the last of the installed apps
"""

from optparse import make_option
import os
import subprocess

from django.core.management.base import BaseCommand, CommandError
from django.core.management.commands.runserver import BaseRunserverCommand
from django.conf import settings

class Command(BaseRunserverCommand):
    option_list = BaseRunserverCommand.option_list + (
        make_option('--adminmedia', dest='admin_media_path', default='',
            help='Specifies the directory from which to serve admin media.'),
        make_option('--watch', dest='compass_project_path', default=settings.MEDIA_ROOT,
            help='Specifies the project directory for compass.'),
    )

    def inner_run(self, *args, **options):
        self.compass_project_path = options.get('compass_project_path', settings.MEDIA_ROOT)

        self.stdout.write("Starting the compass watch command for %r\n" % self.compass_project_path)
        self.compass_pid = subprocess.Popen(["compass watch %s" % self.compass_project_path],
            shell=True,
            stdin=subprocess.PIPE,
            stdout=self.stdout,
            stderr=self.stderr)
        self.stdout.write("Compas watch process on %r\n" % self.compass_pid.pid)

        super(Command, self).inner_run(*args, **options)
这个很好用

有关django命令的更多详细信息,请参阅


希望有人觉得这有帮助

为了进一步扩展@Mario César的优秀答案,我想提供一个适用于Django 1.8+的2011年初始代码的现代版本:

在Django 1.8之前,管理命令基于optparse模块[…],现在管理命令使用argparse进行参数解析,默认情况下,所有参数都在**选项中传递[…]

此外,我想指出,在问题中选择的特定命令
runserver
有一点复杂,这使得它既是一个好例子,也是一个坏例子

糟糕的例子,因为复杂的是命令也被Django本身覆盖。事实上,Django使用了与Mario建议的相同的方法:Django在staticfiles应用程序中覆盖它(请参阅),以便提供额外的静态文件选项

因此,如果使用static,最好覆盖staticfiles app命令而不是core命令。这也回答了@ts_pati关于为什么会出现问题的评论。staticfiles的Django代码是如何覆盖它的一个很好的示例,但这次导入staticfiles是为了不丢失该功能:

from django.contrib.staticfiles.management.commands.runserver import Command as StaticfilesRunserverCommand


class Command(StaticfilesRunserverCommand):
    help = "Starts a lightweight Web server for development, serves static files and does some custom fancy stuff."

    def add_arguments(self, parser):
        super(Command, self).add_arguments(parser)
        parser.add_argument('--my-custom-argument', action="...", dest='my_custom_handler', default=True, help='do some stuff in fancy ways')

    def get_handler(self, *args, **options):
        """
        My fancy stuff function.
        """
        handler = super(Command, self).get_handler(*args, **options)
        my_custom_handler = options.get('my_custom_handler', True)
        # do stuff here
        return handler

编辑:我还想在
已安装的应用程序中添加此操作的顺序
显然很重要,它必须在
django.contrib.staticfiles
之前。谢谢,我查看了来自django核心的命令,我为此编写了一个代码,我将作为答案发布。再次感谢:-)使用此命令时,您对静态有任何问题吗?我不知道为什么,但即使使用空的internal_run函数(仅在调用super internal_run时),也不会加载statics。所有这些我都得到了404。@ts_pati请看我下面关于静态文件的回答。注意:当多个应用程序提供同一资源的不同版本(模板、静态文件、管理命令、翻译)时,安装的应用程序中首先列出的应用程序具有优先权。编辑:@Wtower在下面的回答中提到了这一点