2011-02-27 23 views
1

我正在創建基於Django的網站(我知道它是純Python,所以也許它也可以由熟悉Python的人回答),我需要動態調用一些方法。動態調用方法,如果它存在於Django

例如,我在我的網站中使用views.py中的方法「do_search()」有幾個應用程序(模塊)。然後我有一個模塊叫做「搜索」,在那裏我想要一個能夠在其他應用程序中調用所有現有的「do_search()」的動作。當然,我不喜歡將每個應用程序添加到導入,然後直接調用它。我需要一些更好的方式來動態地做到這一點。

我可以從設置中讀取INSTALLED_APPS變量,並以某種方式通過所有已安裝的應用程序運行並查找特定方法?一塊代碼將在這裏幫助很多:)

在此先感謝! Ignas

+0

我不認爲你在做什麼是推薦的做法。 – 2011-02-27 09:19:53

+0

那麼推薦的方法是什麼?如果我做錯了,我總是想學習正確的事情:) – 2011-02-27 09:30:55

+0

這實在是一個評論,而不是問題的答案。請使用「添加評論」爲作者留下反饋。 – sloth 2012-08-15 13:42:01

回答

3

我不知道我是否真正理解了這個問題,但請在我的答案的評論中澄清,如果我關閉了。

# search.py 
searchables = [] 

def search(search_string): 
    return [s.do_search(search_string) for s in searchables] 

def register_search_engine(searchable): 
    if hasattr(searchable, 'do_search'): 
     # you want to see if this is callable also 
     searchables.append(searchable) 
    else: 
     # raise some error perhaps 


# views.py 
def do_search(search_string): 
    # search somehow, and return result 

# models.py 

# you need to ensure this method runs before any attempt at searching can begin 
# like in models.py if this app is within installed_apps. the reason being that 
# this module may not have been imported before the call to search. 
import search 
from views import do_search 
search.register_search_engine(do_search) 

至於在哪裏註冊您的搜索引擎,在django的信號文檔中有一些與此有關的有用文檔。

您可以將信號處理和註冊碼放在任何你喜歡的地方。但是,您需要確保它所在的模塊能夠儘早導入,以便在需要發送任何信號之前對信號進行處理。這使您的應用程序的models.py成爲註冊信號處理程序的好地方。

因此,您的models.py文件應該是註冊您的搜索引擎的好地方。

,我只是想的備選答案:

在你settings.py,你可以有你的聲明所有搜索功能的設置。像這樣:

# settings.py 
SEARCH_ENGINES = ('app1.views.do_search', 'app2.views.do_search') 

# search.py 
from django.conf import settings 
from django.utils import importlib 

def search(search_string): 
    search_results = [] 
    for engine in settings.SEARCH_ENGINES 
     i = engine.rfind('.') 
     module, attr = engine[:i], engine[i+1:] 
     mod = importlib.import_module(module) 
     do_search = getattr(mod, attr) 
     search_results.append(do_search(search_string)) 
    return search_results 

這工作有點類似於註冊MIDDLEWARE_CLASSES和TEMPLATE_CONTEXT_PROCESSORS。以上都是未經測試的代碼,但是如果您環顧django源代碼,您應該可以充實並刪除任何錯誤。

+0

看起來很酷。但有些問題: - 在search.py​​中創建靜態類是值得的,以保留所有註冊的模塊?我不知道什麼時候這個對象會消失...在生產中,我使用apache,當然不是django的web服務器,當對象被刪除時它很有趣?對於一個用戶會話將被保留,另一個會得到新的對象,對吧? - 所以一般來說,當模型被調用時,它會得到一些信號,然後嘗試註冊可搜索對象,對吧? – 2011-02-27 08:35:01

+0

據我所知,對象的生命週期是請求/響應階段。如果你使用的是WSGI接口,我相當確信每個請求都有自己的沙箱來執行。如果我錯了,其他人可以糾正我 - 或者快速谷歌搜索應該得出答案。不需要一個類,但這種方法可以正常工作。也許一個檢查,以確保搜索只註冊一次將是一個好主意。 – 2011-02-27 08:41:54

+0

謝謝!關於最後一點 - 確定:)閱讀有關信號的時間!再次感謝您的幫助! – 2011-02-27 08:45:58

0

如果你可以通過

import other_app 

導入其他應用程序,那麼它應該有可能進行

method = getattr(other_app, 'do_' + method_name) 
    result = method() 

但是你的做法是值得商榷的。