Hello,
is there some pythonic way to load a django app trough an alias name? This I think would be one way to make an app more "pluggable-friendly".
there is a pattern used in settings.py:
INSTALLED_APPS = ('... ','...', )
where INSTALLED_APPS
is a tuple containing names of apps.
That's fine, but I don't want to put in certain apps explicitly this way.
I would like to have an app handle named say external_login_app
mapping to drupal_login
or mediawiki_login
(to be supplied by the end user or a third party), where name of the actual custom module/app is provided by a string variable in settings.py
The pluggable part (e.g. mediawiki_login
) must be a full-fledged app with it's own views, models, forms, etc, while external_login_app
must be accessible anywhere in the rest of the code.
The goal here is to decouple distributed code from plugins like that.
edit 1: here is what I'm trying:
in settings.py
EXTERNAL_LOGIN = __import__(EXTERNAL_LOGIN_APP)
#setting name must be upper case according to
#django docs
but my custom login app depends on the settings file too, so looks like I have a circular import problem with errors like module external_login does not have attribute views
.
This problem seems to be very insidious, as I am unable to use even simple things like render_to_response
shortcut in views imported with __import__
statement in settings.py.
edit 2: after trying a while I found that using __import__()
in settings.py call won't work because of almost inevitable circular dependencies
The best working method I found so far is to place __import__()
calls into other .py files of the app providing the generic "consumer" interface - the one that calls the plugin functions:
in settings.py
: as Michał suggests in his answer
EXTERNAL_LOGIN_APP = 'drupal_login'
INSTALLED_APPS = (
'...',
EXTERNAL_LOGIN_APP,
)
e.g. in 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.