我正在创建基于Django的网站(我知道它是纯Python,所以也许那些熟悉Python的人也可以回答)我需要动态调用一些方法。
例如,我在我的网站中使用views.py中的方法“do_search()”的应用程序(模块)很少。然后我有一个模块,例如“搜索”,我希望有一个动作,可以在其他应用程序中调用所有现有的“do_search()”。当然我不想将每个应用程序添加到导入,然后直接调用它。我需要一些更好的方法来动态地完成它。
我可以从设置中读取INSTALLED_APPS变量,并以某种方式运行所有已安装的应用程序并查找具体方法?一段代码将在这里帮助很多:)
提前致谢! Ignas
答案 0 :(得分: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源代码,你应该能够充实它并删除任何错误。
答案 1 :(得分:0)
如果您可以通过
导入其他应用程序import other_app
然后应该可以执行
method = getattr(other_app, 'do_' + method_name)
result = method()
但是你的方法值得怀疑。