在Django中运行时修改urlpatterns

7

我正在开发一个需要在运行时加载动态模块的Django应用程序。现在,我能够上传(从客户端浏览器到服务器)“插件”并在数据库中注册插件模型等。但是我需要一种处理每个插件的urlpatterns的方法。目前,我已经在webapp的“核心”中编写了一个函数,该函数注册一个模型并(理论上)通过包含它将上传的插件的urlpatterns添加到webapp urls.py中。这个函数是:

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' )))

插件以tgz格式上传到“media/tmp”,然后解压到“media/plugins/”,其中插件的代号是插件名称。用户上传的插件由“project.plugins”管理。
所有插件逻辑都正常工作,但是当我尝试将上传的插件urls.py文件包含到Web应用中(project.plugins.urls)时,它没有任何效果。我已经打印了“project.plugins.urls.urlpatterns”的值,发现在进行“urlpatterns += pat....”操作后,该值未被修改。
有没有办法实现我需要的功能呢?
此致
敬礼
2个回答

4
你面临的问题是,在项目的url.py文件中定义了urlpatterns,而在register_plugin文件中定义的urlpatterns是不同的变量。它们只在该模块内有效。想象以下情况:
#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

很遗憾,为了运行这段代码,Web服务器需要重新启动进程,因此只有在这种情况下上传的插件才会生效。


3

修改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文件,但更改并没有生效。问题出在哪里?
附注:插件urls.py文件包含以下内容:
from django.conf.urls.defaults import patterns, url
from .views import index_view

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

感谢您的回复。
最好的问候。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接