views:

108

answers:

1

I have some custom logic that needs to be executed every single time a URL is reversed, even for third-party apps. My project is a multitenant web app, and the tenant is identified based on the URL. There isn't a single valid URL that doesn't include a tenant identifier.

I already have a wrapper function around reverse, but now I need a way to tell every installed app to use it. The wrapper around reverse uses a thread-local to inject the identifier into the resulting URL. I could write this function as a decorator on reverse, but I don't know where to do the actual decoration.

Moderately Firm Constraint: I'm already using 3 3rd-party apps, and I'll probably add more. A solution should not require me to modify the source code of all these third-party apps. I don't relish the idea of maintaining patches on top of multiple 3rd-party source trees if there is an easier way. I can make the documentation abundantly clear that reverse has been decorated.

The Original Question: Where could I make such a change that guarantees it would apply to every invocation of reverse?

Possible Alternate Question: What's a better way of making sure that every URL—including those generated by 3rd-party apps—gets the tenant identifier? BTW, I'm open to a better way to handle any of this except the embedding of the tenant-id in the URL; that decision is pretty set in stone right now. Thanks.

Thanks.

+4  A: 

only way so that django reverse is replaced by ur_reverse is

django.core.urlresolvers.reverse = ur_reverse

or if you like decorator syntactic sugar

django.core.urlresolvers.reverse = ur_reverse_decorator(django.core.urlresolvers.reverse )

which i would not advice(and many will shout), unless you are not willing to change every usage of reverse with ur_reverse

Anurag Uniyal
This works... and is likely to continue working even as you upgrade django :)
Jiaaro
...even if you are monkeypatching django, it's still the answer to his question
Jiaaro
I'm aware that I want to decorate `reverse`. My question is *where* I should do the decoration?
Hank Gay
my solution you can apply in settings, or anywhere else once
Anurag Uniyal
Thanks. I was worried that doing it in `settings.py` might cause some sort of subtle bug due to incomplete initialization.
Hank Gay