Django, dynamic urlconfs, thread-safety

657 Views Asked by At

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
1

There are 1 best solutions below

0
On

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.