动态调用方法(如果 Django 中存在)

发布于 2024-10-19 04:50:47 字数 327 浏览 3 评论 0原文

我正在创建基于Django的网站(我知道它是纯Python,所以也许熟悉Python的人也可以回答),我需要动态调用一些方法。

例如,我的网站中很少有应用程序(模块)在views.py 中使用“do_search()”方法。然后我有一个名为“search”的模块,我想要一个能够调用其他应用程序中所有现有“do_search()”的操作。当然我不喜欢将每个应用程序都添加到导入中,然后直接调用。我需要一些更好的方法来动态地完成它。

我可以从设置中读取 INSTALLED_APPS 变量,并以某种方式运行所有已安装的应用程序并查找特定方法?一段代码在这里会有很大帮助:)

提前致谢! 伊格纳斯

I'm creating website based on Django (I know it's pure Python, so maybe it could be also answered by people who knows Python well) and I need to call some methods dynamically.

For example I have few applications (modules) in my website with the method "do_search()" in the views.py. Then I have one module called for example "search" and there I want to have an action which will be able to call all the existing "do_search()" in other applications. Of course I don't like to add each application to the import, then call it directly. I need some better way to do it dynamically.

I can read INSTALLED_APPS variable from settings and somehow run through all of the installed apps and look for the specific method? Piece of code will help here a lot :)

Thanks in advance!
Ignas

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风渺 2024-10-26 04:50:47

我不确定我是否真正理解这个问题,但如果我不在,请在对我的答案的评论中澄清。

# 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 源代码,你应该能够充实它并消除任何错误。

I'm not sure if I truly understand the question, but please clarify in a comment to my answer if I'm off.

# 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)

As for where to register your search engine, there is some sort of helpful documentation in the signals docs for django which relates to this.

You can put signal handling and registration code anywhere you like. However, you'll need to make sure that the module it's in gets imported early on so that the signal handling gets registered before any signals need to be sent. This makes your app's models.py a good place to put registration of signal handlers.

So your models.py file should be a good place to register your search engine.

Alternative answer that I just thought of:

In your settings.py, you can have a setting that declares all your search functions. Like so:

# 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

This works somewhat similar to registering MIDDLEWARE_CLASSES and TEMPLATE_CONTEXT_PROCESSORS. The above is all untested code, but if you look around the django source, you should be able to flesh this out and remove any errors.

哀由 2024-10-26 04:50:47

如果您可以通过导入其他应用程序

import other_app

,那么应该可以执行

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

但是您的方法是有问题的。

If you can import the other applications through

import other_app

then it should be possible to perform

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

However your approach is questionable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文