2012-03-29 1 views
4

Я разрабатываю приложение Django, которое требует загрузки динамических модулей (во время выполнения). Теперь я могу загрузить (от браузера клиента к серверу) «плагины» и зарегистрировать модель плагина в базе данных и т. Д. Но мне нужен способ обработки URL-адресов для каждого плагина. В настоящее время я написал функцию в «ядре» webapp, которая регистрирует модель и (теоретически) добавляет urlpatterns загруженного плагина к webapp urls.py, включив его. Эта функция:Модификация urlpatterns во время выполнения в Django

def register_plugin_model(model,codename): 
# Standard syncdb expects models to be in reliable locations, 
# so dynamic models need to bypass django.core.management.syncdb. 
# On the plus side, this allows individual models to be installed 
# without installing the entire project structure. 
# On the other hand, this means that things like relationships and 
# indexes will have to be handled manually. 
# This installs only the basic table definition. 

if model is not None: 
    style = color.no_style() 
    cursor = connection.cursor() 
    tables = connection.introspection.table_names() 
    seen_models = connection.introspection.installed_models(tables) 
    statements,trsh = connection.creation.sql_create_model(model, style, seen_models) 
    for sql in statements: 
     cursor.execute(sql) 

# add urlpatterns 
from django.conf.urls.defaults import patterns, url,include 
from project.plugins.urls import urlpatterns 
urlpatterns += patterns(url(r'^' + codename + '/' , include ('media.plugins.' + codename + '.urls'))) 

Плагины загружены в «медиа/TMP» в формате TGZ, а затем экстрагируют на «медиа/плагинов /», где это кодовое название плагина, и загруженные пользовательские модули управляются " project.plugins».

Все логики плагинов работают отлично, однако, когда я пытаюсь включить загруженный файл urls.py плагина в webapp (project.plugins.urls), он не имеет никакого эффекта. Я напечатал значение «project.plugins.urls.urlpatterns» и не изменил его после «urlpatterns + = pat ...».

Есть ли способ сделать то, что мне нужно?

С наилучшими пожеланиями

ответ

3

Проблема вы столкнулись, является то, что urlpatterns определены в проектах url.py файл, и urlpatterns определены в файле register_plugin разные переменные. Они локальны для модуля. Представьте себе следующий сценарий:

#math.py 
pi = 3.14 

#some_nasty_module.py 
from math import pi 
pi = 'for_teh_luls' 

#your_module.py 
from math import pi 
pi * 2 
>>> 'for_teh_lulsfor_teh_luls' 
# wtf? 

Вам явно не разрешено это делать. Что вам, вероятно, понадобится сделать, попросите оригинал urls.py попытаться обнаружить URL-адреса в вашей папке плагинов.

# urls.py 
urlpatterns += (...) 

def load_plugin_urls(): 
    for module in get_plugin_modules(): 
     try: 
      from module.urls import urlpatterns as u 
      urlpatterns += u 
     except: 
      pass 

К сожалению, веб-сервер нужно будет переработать процесс для этого кода для запуска, поэтому загрузка плагинов будет только в силу как только это произойдет.

1

Функция, которая изменяет urls.py и urls.py, принадлежит к одному модулю. Я решил, добавив "пустой шаблон":

urlpatterns += patterns('',url(r'^' + codename + '/' , include ('media.plugins.' + codename + '.urls'))) 

Теперь он говорит:

BEFORE: 
<RegexURLPattern plugins ^$> 
<RegexURLPattern plugin_new ^new/$> 
<RegexURLPattern plugin_profile ^profile/(?P<plugin>\w+)$> 
AFTER 
<RegexURLPattern plugins ^$> 
<RegexURLPattern plugin_new ^new/$> 
<RegexURLPattern plugin_profile ^profile/(?P<plugin>\w+)$> 
<RegexURLResolver media.plugins.sampleplugin.urls (None:None) ^sampleplugin/> 

Но уже вы сказали, что не вступает в силу мгновенно:/

Я перезапустил приложение, не удаляя файлы * .pyc, но изменения не вступили в силу. В чем проблема?

PD: файл плагина urls.py содержит:

from django.conf.urls.defaults import patterns, url 
from .views import index_view 

urlpatterns = patterns('' , url(r'^.*' , index_view)) 

Спасибо за ваш ответ

С наилучшими пожеланиями