Установка псевдонима для подключаемого приложения Django - PullRequest
2 голосов
/ 20 декабря 2009

Есть ли какой-нибудь питонный способ загрузки приложения django через псевдоним? Я думаю, это было бы одним из способов сделать приложение более «дружественным к подключаемым устройствам».

есть шаблон, используемый в settings.py:

INSTALLED_APPS = ('... ','...', )

где INSTALLED_APPS - это кортеж, содержащий названия приложений. Это хорошо, но я не хочу вставлять некоторые приложения явно таким образом.

Я хотел бы иметь дескриптор приложения с именем скажем external_login_app, отображающий на drupal_login или mediawiki_login (должен быть предоставлен конечным пользователем или третьей стороной), где имя фактического Пользовательский модуль / приложение предоставляется строковой переменной в settings.py

Подключаемая часть (например, mediawiki_login) должна быть полноценным приложением с собственными представлениями, моделями, формами и т. Д., В то время как external_login_app должен быть доступен в любом месте остального кода.

Цель здесь - отделить распределенный код от плагинов, подобных этому.

изменить 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. Эта проблема кажется очень коварной, поскольку я не могу использовать даже простые вещи, такие как render_to_response ярлык в представлениях, импортированных с помощью оператора __import__ в settings.py.

edit 2: через некоторое время я обнаружил, что использование __import__() в файле settings.py не будет работать из-за почти неизбежных циклических зависимостей

Лучший рабочий метод, который я нашел на данный момент, - это помещать __import__() вызовы в другие .py файлы приложения, обеспечивающие универсальный «потребительский» интерфейс - тот, который вызывает функции плагина:

в settings.py: как Михал предлагает в своем ответе

EXTERNAL_LOGIN_APP = 'drupal_login'
INSTALLED_APPS = (
                  '...',
                  EXTERNAL_LOGIN_APP,
                )

например. в 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.

Ответы [ 2 ]

4 голосов
/ 20 декабря 2009

Установить

LOGIN_APP_NAME = 'drupal_login' # or 'mediawiki_login', or whatever

достаточно рано в файле settings.py, затем поместите LOGIN_APP_NAME (без кавычек!) В INSTALLED_APPS вместо названия самого приложения.

Если вам требуется более сложная функциональность, связанная с определением того, какое приложение использовать, как насчет того, чтобы поместить что-то вроде external_login_app() (вызов функции - не заключайте в кавычки!) В INSTALLED_APPS и заставить функцию external_login_app вернуть все, что это он должен возвращаться в зависимости от настроек в settings.py, или, может быть, где-нибудь содержимое файла конфигурации или что-то еще? ( РЕДАКТИРОВАТЬ: Ответ Тобу показывает, что может потребоваться для возврата такой функции и как можно добиться этого с помощью __import__.)

Во всяком случае, я не уверен, что таким образом можно достичь многого в плане разделения частей сайта - если пользователю все еще нужно изменить settings.py, почему бы ему не указать имя соответствующее приложение в нужном месте? ( РЕДАКТИРОВАТЬ: ОК, так что теперь я вроде вижу, что можно получить с помощью правильного решения здесь ... Я думаю, что обсуждение продолжается о том, как лучше всего сделать то, что требуется.)

РЕДАКТИРОВАТЬ: Я разместил это до оригинального плаката, внося поправки в вопрос с любыми изменениями, и теперь редактирование 2 включает идею перемещения имени приложения для входа в отдельную переменную в settings.py и включая переменную в INSTALLED_APPS. Теперь, когда внесены два изменения в исходный вопрос, я думаю, что я могу как-то увидеть проблему яснее, хотя это только заставляет меня думать, что для этого требуется приложение abstract_login с бэкэндами для поддержки '*_login' модули, связанные с Drupal, MediaWiki и т. д. схемы входа. Ну, я не могу сказать, что могу предоставить такую ​​вещь прямо сейчас ... Надеюсь, кто-то другой может. Отредактирую снова, если я верю, что у меня есть блестящая идея, упрощающая все это за пределы редактирования ОП.

2 голосов
/ 20 декабря 2009

Определение имени приложения в настройках (как делает Михал и ваше редактирование) работает хорошо:

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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...