I'm developping a Django application that requires to load dynamic modules (at runtime). Now I'm able to upload (from client browser to server) "plugins" and register the plugin model in the database, etc. But I need a way to handle the urlpatterns for each plugin. Currently I've written a function in the "core" of the webapp that registers a model and (theoretically) adds the urlpatterns of the uploaded plugin to the webapp urls.py by including it. This function is:
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' )))
Plugins are uploaded to "media/tmp" in tgz format and then extracted to "media/plugins/" where is the codename of the plugin, and the user uploaded plugins are managed by "project.plugins".
All plugins logic works fine, however when I try to include the uploaded plugin urls.py file into the webapp (project.plugins.urls) it takes no effect. I've printed the value of "project.plugins.urls.urlpatterns" and it's not modified after "urlpatterns += pat....".
Is there any way to do what I need?
Best regards
The problem you're facing, is that urlpatterns
defined in your projects url.py
file, and the urlpatterns
defined in your register_plugin
file are different variables. They are local to the module. Imagine the following scenario:
#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?
You're obviously not allowed to do this. What you're probably going to need to do, is ask the original urls.py
to attempt to discover urls in your plugins folder.
# 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
Unfortunately, the webserver will need to recycle the process for this code to run, so uploading of plugins will only come into effect once that happens.
The function that modifies urls.py and urls.py belong to the same module. I've solved it by adding an "empty pattern":
urlpatterns += patterns('',url(r'^' + codename + '/' , include ( 'media.plugins.' + codename + '.urls' )))
Now, it says:
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/>
But has you said, it doesn't take effect instantaneously :/
I've restarted the application without deleting *.pyc files, but changes didn't taken effect. What's the problem?
PD: the plugin urls.py file contains:
from django.conf.urls.defaults import patterns, url
from .views import index_view
urlpatterns = patterns( '' , url(r'^.*' , index_view ) )
Thanks for your reply
Best regards
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With