Программно добавлять шаблоны URL в Django?

Есть ли способ программно добавлять шаблоны URL в Django, не перезагружая сервер?

Или существует способ заставить Django перерисовывать/кэшировать шаблоны URL (URLconf)?

Ответ 1

Если вы используете gunicorn без предварительной загрузки кода, просто отправьте HUP в мастер-процесс пушки, он будет порождать новых работников, которые загружают новый код и изящно закрывают старые, без единого потерянного запроса!

Ответ 2

Я пробовал что-то вроде этого, взломав некоторые вещи в django.core.urlresolvers - он работал у меня, но обратите внимание, что это хак. У меня еще нет кода, но я сделал что-то вроде этого:

  • Django обычно использует urlresolvers.get_resolver() для получения RegexURLResolver, который отвечает за разрешение URL-адресов. Передача None этой функции получает ваш корневой URLConf.
  • get_resolver() использует кеш _resolver_cache для загруженных URLConfs.
  • Сброс _resolver_cache должен заставить Django воссоздать чистый URLResolver.

В качестве альтернативы вы можете попытаться отключить атрибут _urlconf_module корня RegexURLResolver, который должен заставить Django перезагрузить его (не уверен в этом, но возможно, что модуль будет кэшироваться Python).

from urlresolvers import get_resolver

delattr(get_resolver(None), '_urlconf_module')

Опять же, не гарантируется, что это сработает (я работаю из памяти из кода, который я, очевидно, отбросил по какой-то причине). Но django/core/urlresolvers.py - это, безусловно, файл, который вы хотите посмотреть.

РЕДАКТИРОВАТЬ: Решили поэкспериментировать с этим, и это не сработало...

EDIT2:

Как я думал, ваши URL-модули будут кэшироваться Python. Просто перезарядить их по мере их изменения может работать (используя reload). Если ваша проблема заключается в том, что вы динамически создаете urlpatterns на основе некоторых данных, которые могут измениться.

Я попробовал reload мои корневые URL (project.urls) и модуль suburl (app.urls). Это все, что я должен был сделать для новых URL-адресов, отображаемых get_resolver(None).url_patterns

Таким образом, трюк может быть таким простым: вручную перезагрузите URL-адрес.