Programmatically add URL Patterns in Django?
Is there a way to programmatically add URL Patterns to Django w开发者_运维技巧ithout having to restart the server?
Or is there a way force Django to reprocess/cache URL patterns ( the URLconf )?
If you use gunicorn without code preloading, just send a HUP to the gunicorn master process, it will spawn new workers which load the new code, and gracefully shut down the old ones, without a single lost request!
I tried something like this by hacking some things in django.core.urlresolvers
– it worked for me but note that it's a hack. I don't still have the code, but I did something like this:
- Django typically uses
urlresolvers.get_resolver()
to get aRegexURLResolver
which is responsible for resolving URLs. PassingNone
to this function gets your "root" URLConf. get_resolver()
uses a cache,_resolver_cache
, for loaded URLConfs.- Resetting
_resolver_cache
should force Django to recreate a clean URLResolver.
Alternatively, you might try to unset the _urlconf_module
attribute of the root RegexURLResolver
, which should force Django to reload it (not sure about this though, it's possible that the module will be cached by Python).
from urlresolvers import get_resolver
delattr(get_resolver(None), '_urlconf_module')
Again, not guaranteed that this will work (I'm working from memory from code that I've obviously discarded for some reason). But django/core/urlresolvers.py is definitely the file you'll want to look at.
EDIT: Decided to experiment some with this and it didn't work...
EDIT2:
As I thought, your URL modules will be cached by Python. Simply reloading them as they change might work (using reload
). If, your problem is that you're dynamically constructing urlpatterns
based on some data which might change.
I tried reload
ing my root URLs (project.urls) and a suburl module (app.urls). That's all I had to do for the new URLs to be displayed by get_resolver(None).url_patterns
So the trick might be this simple: Manually reload your URL module.
Here is your answer :
import sys
from django.conf import settings
from importlib import reload
from django.urls import clear_url_caches
urlconf = settings.ROOT_URLCONF
if urlconf in sys.modules:
clear_url_caches()
reload(sys.modules[urlconf])
This seams also an elegant way to do it :
http://codeinthehole.com/writing/how-to-reload-djangos-url-config/
Simply do that to reload your root urls module :
reload_urlconf()
精彩评论