I need to dynamically generate urlpatterns based on data in the session in a thread-safe way.
I implemented this via a custom URLResolver that defers url resolving until later. I do know about setting request.urlconf from a middleware; but there are reasons I cannot do that (Django caches resolvers, and in my case would result in unbounded memory usage).
I need someone to take a look at the implementation and see if I've handled the thread-safety correctly.
Thanks!
The code:
myapp/urls.py:
urlpatterns = patterns('',
# other urlconfs
url(r'^/foo', include('foo.urls')),
)
foo/urls.py:
import threading
from django.core.urlresolvers import ResolverMatch
class MyResolver(RegexURLResolver):
def __init__(self):
self.resolver = threading.local()
return super(MyResolver, self).__init__(r'', None)
@property
def urlconf_module(self):
return self.resolver.value
def resolve(self, path):
def view(request):
resolver = request.session.get('myresolver', 'default')
resolver = getattr(import_module('foo.resolvers'), resolver)
self.resolver.value = resolver()
view, args, kwags = super(MyResolver, self).resolve(path)
return view(request, *args, **kwargs)
return ResolverMatch(view, (), {})
urlpatterns = [MyResolver()]
foo/resolvers.py:
class default(object):
@property
def urlpatterns(self):
return patterns('foo.views',
url(r'', 'error'),
)
class test(object):
@property
def urlpatterns(self):
return dynamically_generated_urlpatterns
I would say that you are actually better off implementing this as Middleware as it might be faster and give you more control.
Perhaps you could show more about what data you plan on submitting to the function and possible outputs.
More detail on the use case would be good.