是否有一些pythonic方式通过别名加载django应用程序?我认为这是使应用程序更“可插拔友好”的一种方法。
在settings.py中使用了一种模式:
INSTALLED_APPS = ('... ','...', )
其中INSTALLED_APPS
是包含应用名称的元组。
这很好,但我不想以这种方式明确地放入某些应用程序。
我希望将应用处理命名为external_login_app
映射到drupal_login
或mediawiki_login
(由最终用户或第三方提供) ),其中实际自定义模块/应用程序的名称由settings.py
可插入部分(例如mediawiki_login
)必须是具有自己的视图,模型,表单等的完整应用程序,而external_login_app
必须可以在其余代码中的任何位置访问。< / p>
这里的目标是将分布式代码与插件解耦。
编辑1:以下是我正在尝试的内容:
在settings.py 中
EXTERNAL_LOGIN = __import__(EXTERNAL_LOGIN_APP)
#setting name must be upper case according to
#django docs
但我的自定义登录应用程序也取决于设置文件,因此看起来我有一个循环导入问题,错误如module external_login does not have attribute views
。
这个问题似乎非常隐蔽,因为我无法在settings.py中使用render_to_response
语句导入的视图中使用__import__
快捷方式等简单的内容。
编辑2 我发现在settings.py调用中使用__import__()
将无法正常工作,因为几乎不可避免的循环依赖
到目前为止,我发现的最佳工作方法是将__import__()
调用放入应用程序的其他.py文件中,提供通用的“消费者”界面 - 调用插件函数的界面:
settings.py
中的:Michał在他的回答中建议
EXTERNAL_LOGIN_APP = 'drupal_login'
INSTALLED_APPS = (
'...',
EXTERNAL_LOGIN_APP,
)
e.g。在app/views.py
:
from django.conf import settings
EXTERNAL_LOGIN = __import__(settings.EXTERNAL_LOGIN_APP, \
[], [], ['api','forms'])
def login_view(request, external=False):
if external:
form = EXTERNAL_LOGIN.forms.LoginForm(request.POST)
if form.is_valid():
login = form.cleaned_data['login']
password = form.cleand_data['password']
if EXTERNAL_LOGIN.api.check_password(login, password):
#maybe create local account,
#do local authentication
#set session cookies for the
#external site to synchronize logins, etc.
答案 0 :(得分:4)
集
LOGIN_APP_NAME = 'drupal_login' # or 'mediawiki_login', or whatever
在settings.py中尽早,然后在LOGIN_APP_NAME
中添加INSTALLED_APPS
(不带任何引号!),而不是实际应用的名称。
如果您需要更复杂的功能来确定要使用的应用程序,那么如何在INSTALLED_APPS中放置external_login_app()
(函数调用 - 在它周围没有引号!)之类的东西,并让external_login_app函数返回任何它是应该根据settings.py中的设置返回,还是某个配置文件的内容或其他什么? (编辑: Tobu的回答显示了这样一个函数可能需要返回的内容以及如何使用__import__
实现这一功能。)
无论如何,我不确定在解除部分网站方面是如何实现的 - 如果用户仍然需要修改settings.py,为什么不让他/她放入名称适当的应用程序在正确的地方? (编辑:好的,现在我有点看到在这里使用正确的解决方案可以获得什么......我想继续讨论如何最好地完成所需的工作。)
编辑:我在原始海报之前发布了这个,修改了任何编辑的问题,现在编辑2包括将登录应用的名称移动到settings.py中的单独变量的想法并在INSTALLED_APPS
中包含变量。既然原始问题的两个编辑已经到位,我想我可以更清楚地看到问题,尽管这只是让我认为情况所要求的是abstract_login
应用程序,后端支持{ {1}}模块处理drupal,mediawiki等登录方案。好吧,我不能说我现在可以提供那种东西......希望别人可以。如果再次编辑,我相信我有一个明智的想法,可以简化整个OP的编辑范围。
答案 1 :(得分:2)
在设置中定义应用名称(如Michał和您的编辑一样)效果很好:
EXTERNAL_LOGIN_APP = 'drupal_login'
INSTALLED_APPS = (
'...',
EXTERNAL_LOGIN_APP,
)
同样在设置或公共模块中,您可以考虑导入应用程序:
def external_login_app():
return __import__(EXTERNAL_LOGIN_APP, …)
在导入后使用它:
external_login_app = settings.external_login_app()