2013-03-11 41 views
1

我們總是從settings_test運行我們的測試,如下所示:./manage.py test someapp --settings = settings_test。問題是,記住添加選項有時是有問題的。(Django)創建一個管理命令,將覆蓋BaseCommand中的默認設置

我想介紹一個只有管理命令test.py的通用應用程序。根據它在INSTALLED_APPS設置中的位置,它將覆蓋默認值。在命令本身中,我想更改--settings選項的默認值。我怎樣才能做到這一點?

我知道我可以創建一個類似於manage.py但使用settings_test而不是設置的local.py文件。然而,重點仍然是運行./manage.py,但是將settings_test作爲默認值,而不是在./manage.py之後不斷鍵入「--settings = settings_test」。測試someapp

+0

您是否考慮過爲'manage管理寫一個別名?py在shell中測試someapp --settings = settings_test'? – 2013-03-11 20:47:10

+0

這只是出於實際的目的:創建別名意味着每個正在從事項目工作的程序員都必須在其側面創建別名,並且我想避免這種情況。我想將settings_test設置爲默認設置,所以其他通常忘記添加該選項的程序員最終不會關注錯誤類型的錯誤,如果他們添加了錯誤,則不會出現錯誤類型。 – 2013-03-11 22:02:59

+0

爲什麼不用這樣的常用命令創建一個Makefile並將其與您的存儲庫一起檢查?然後你可以'make test_someapp'並完成它。 – mVChr 2013-03-11 22:05:31

回答

1

您可以通過實施來覆蓋默認命令他們在你的應用程序(說:common_app)。

在common_app中創建一個management.commands包。 ,並在那裏執行測試命令:

# this is commonapp/management/commands/test.py 
try: 
    from south.management.commands import test 
except ImportError: 
    from django.core.management.commands import test 


class Command(test.Command): 
    def handle(self, *args, **kwargs): 
     kwargs['settings'] = kwargs.get('settings', 'common_app.settings') 
     super(Command, self).handle(*args, **kwargs) 

這將使用settings.py文件中common_app如果沒有「--settings =」標誌中給出。但是你可以在「settings_test」中更改該字符串,並且會加載它可以在你的python路徑中找到的第一個settings_test.py。

South也是這個命令覆蓋太多,所以爲了完整我加了南進口。但是,如果您的其他已安裝的應用程序也覆蓋了測試命令......您會明白。

不要忘記空的__init__.py文件來做'管理'和'命令'packages

RTFM有關Django自定義管理命令的更多信息。

+0

該代碼並不像預期的那樣工作 - 至少在Django 1.7中。 線 'kwargs [ '設置'] = kwargs.get( '設置', 'common_app.settings')' 似乎實際上從未改變的值,因爲獲得()發現的關鍵,這恰好值爲None。 我已通過將其更改爲: 'kwargs ['settings'] = kwargs.get('settings',None)或'common_app.settings'' HTH。 – pgcd 2015-05-22 07:44:45

+0

@pgcd請擴展 – 2015-05-22 07:49:35

+0

實際上還有另外一個問題:顯然,它看起來像Django 1.7已經解析設置,當它處理() - 我只是試圖設置kwargs ['settings']隨機胡言亂語,它削弱愉快。 – pgcd 2015-05-22 07:55:06

1

經過多次嘗試,我發現manage.py在實際管理命令被調用之前設置了足夠長的時間,以至於在那裏改變它們基本上是不可能的(據我所知)。 最後我決定,因爲它似乎是確定以改變manage.py - 有默認的設置文件存在,例如 - 這將是一個合理的地方來解決這個問題,所以我實現它還有:

if __name__ == "__main__": 
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings") 

    argv = sys.argv 
    try: 
     if argv[1] == 'test' and not any([k.startswith('--settings') for k in argv]): 
      os.environ["DJANGO_SETTINGS_MODULE"] = "myapp.test_settings" 
    except IndexError: 
     pass 

    from django.core.management import execute_from_command_line 
    execute_from_command_line(argv) 

這似乎按預期工作,我沒有看到任何主要的缺點或問題 - 樂意予以糾正。

0

您可以覆蓋@Chris Wesseling在他的回答中描述的django命令。

注:如果有正在擴展命令的其他應用程序,將在INSTALLED_APPS列表中的那些應用程序上面您的應用程序,即

  • 覆蓋runserver命令,並且您使用'django.contrib.staticfiles',將您的應用程序前staticfiles應用
  • 覆蓋test命令和你正在使用一個測試應用程序,即django_nose,同樣,django_nose應用之前將您的應用程序
相關問題