2013-08-02 13 views
0

(也許這個問題更多的是Python的,但Django是上下文,所以這裏有雲)在Django中,是否可以定義基於另一個的動態計算設置?

假設你需要設置FOO,其價值取決於設定BAR的值(簡單的情況是讓CELERY_RESULT_BACKEND等於BROKER_URL) 。

如果你只有一個設置文件,這是簡單的實現:

BAR = some_value 
FOO = some_function(BAR) 

然而,這是很常見的有很多設置文件,每一個環境(如生產,開發,測試階段,等),從書「的Django的兩勺:最佳實踐的Django 1.5」中的project layout建議。

在這種情況下有一個settings.base模塊,其通過settings.devsettings.prod其所有內容導入等,其添加他們自己的特定的值或覆蓋在settings.base定義。

當我想在其中一些模塊中覆蓋BAR時,會出現問題,但我必須記得在每次覆蓋後重新計算FOO。這很容易出錯,而不是幹。

lambda函數不會工作,因爲該設置將是一個可調用的,而不是結果值。內置函數/裝飾器property將是理想的,但它只能在類中使用(新樣式)。我什麼都不知道。

想法?

+0

嗯。這有點不整潔,但可能會將您的相關設置拆分爲不同的文件並在設置BAR之後導入該文件? –

回答

0

輕微的hackish:

class DynamicWrapper(object): 
    _initialized = False 

    def __init__(self, wrapped_name) 
     self._wrapped = wrapped_name 

    def __get__(self): 
     if not self._initialized: 
      self._initialized = True 
      return self 
     if not hasattr(self, '_computed_val'): 
      from django.conf import settings 
      val = getattr(settings, self._wrapped) 
      self._computed_val = some_func(val) 
     return self._computed_val 

BAR = 'some_value' 
FOO = DynamicWrapper('BAR') 

的想法如下:

  • Django的設置對象使用getattr(settings_module, setting)一旦當初始化設置對象(注意,當你做from django.conf import settings你居然導入的對象,而不是一個模塊)。結果被設置爲設置對象的屬性。調用__get__,返回self,因此settings.FOODynamicWrapper實例。
  • 當訪問settings.FOO時,這將在DynamicWrapper對象上第二次調用__get__,這是您希望它返回實際值的時候。該值根據some_func計算並且該值被返回,而不是DynamicWrapper對象。
  • 任何後續嘗試獲得值settings.FOO的方法也將調用__get__方法,但是這次計算的值被緩存爲self._computed_val並立即返回。

當存在多個對象Settings,當FOO以另一種方式通過django.conf.settings訪問比,或當沒有定義該BAR不處理(邊緣)的情況。

+0

好主意,雖然它肯定是hackish的方式來實現我想要的。它從未想過以這種方式解決問題。恭喜 – glarrain

0

是的,這就是,設置文件僅僅是一個Python腳本,以及。

大多數人做的,它已經建立模板路徑設置。

Django template Path

現在讓我們想象一下:

ref = { 
    'dev': 'FOO', 
    'qa': 'BAR' 
    'prod': 'BAZ' 
} 

ENV = 'PROD' # Can also be DEV or QA 

DYNAMIC_SETTING = ref.get(ENV.lower(), None) # => 'BAZ' 
+0

我想你誤解了我所需要的。你發佈爲'DYNAMIC_SETTING'的情況並非如此:如果我在你的代碼片段之後更改'ENV',然後再次訪問'DYNAMIC_SETTING',它的值不會改變。爲什麼?因爲該行('DYNAMIC_SETTING = ref ...')已經執行,不會再次執行。 – glarrain

相關問題