2011-07-11 115 views
15

我想在啓動一個django命令之前運行一個命令。有什麼方法可以將功能添加到現有的django命令?

例如:

$ 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的來源?

回答

16

只要意識到您可以輕鬆地重寫命令,就像使用具有相同名稱的命令創建應用程序一樣。

因此,我創建了一個應用程序並創建一個與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) 

這工作得很好。

https://docs.djangoproject.com/en/dev/howto/custom-management-commands/關於Django的更多細節命令

希望有人發現這是很有幫助的

+1

使用此命令你有任何靜態問題?我不知道爲什麼,但是即使有空的inner_run函數(僅在調用了supper inner_run時),statics也不會被加載。他們都得到了404。 –

+0

@ts_pati查看我的答案,下面介紹靜態文件的情況。 – Wtower

+1

來自[django 1.9文檔](https://docs.djangoproject.com/en/1.9/ref/settings/)的注意事項: 當多個應用程序提供相同資源的不同版本時(模板,靜態文件,管理命令,翻譯),首先在INSTALLED_APPS中列出的應用程序具有優先權。 編輯:@Wtower在下面的回答中提到了這個 – msnider

1

在運行您的命令的應用程序中編寫您自己的管理命令,然後調用Django的內置實現。

+1

謝謝,我看了一下django核心的命令,我做了一個代碼來做到這一點,我發佈了答案。再次感謝:-) –

3

要在@Mario塞薩爾的出色答卷進一步擴大,我想提供他最初的2011碼的現代版改編Django的1.8+:

的Django 1.8之前,管理命令所依據的optparse模塊[...]現在,管理命令argparse使用的參數解析,所有的參數都在默認情況下,[**選項中傳遞。 ..]

Source

此外,我想指出的是,這是選擇的問題,具體的命令runserver有輕微的併發症,使得它既有好的和壞的例子。

不好的例子,因爲複雜的是該命令也被Django本身覆蓋。事實上,Django使用的方法與Mario提出的方法相同:Django在靜態文件應用程序中覆蓋它(請參見Django code on github)以提供額外的靜態文件選項。

因此,如果使用靜態,最好覆蓋staticfiles應用程序命令而不是核心命令。這也回答@ 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 

編輯:我也想加入INSTALLED_APPS這個順序顯然很重要,它必須在django.contrib.staticfiles之前。

相關問題