Reputation: 118
Some of our urls include #
. These are used for reverse lookup, both using reverse
and the {% url
template tag (which uses reverse
internally). Django 1.8 used to leave it alone, 1.11 now encodes it to %23
.
Is it possible to put a monkey patch wrapper somewhere and have it be used everywhere without fail? Here's the wrapper I have:
def patch_reverse(func):
def inner(*args, **kwargs):
print "inner reverse"
url = func(*args, **kwargs)
return url.replace("%23", "#")
return inner
from django.urls import base
base.reverse = patch_reverse(base.reverse)
The print
statement is so I can see if it's actually running.
I've tried putting it in settings, the __init__
of the first installed app, and in the urls
of the first installed app. Nothing works.
Upvotes: 2
Views: 1030
Reputation: 118
This works. In your settings.py
or equivalent settings module:
from django import urls
from django.core import urlresolvers
_django_reverse = urlresolvers.reverse
def _reverse(*args, **kwargs):
result = _django_reverse(*args, **kwargs)
# Do whatever you want to do to reverse here
return result.replace("%23", "#")
urlresolvers.reverse = _reverse
urls.reverse = _reverse
Upvotes: 1
Reputation: 308999
By the time you've patched reverse
the original function may have already been imported into django.urls
(where you usually import it from) and django.template.defaulttags
(where the {% url %}
tag uses it. Try patching it in those modules instead:
import django.urls
django.urls.reverse = patch_reverse(django.urls.reverse)
import django.template.defaulttags
django.template.defaulttags = patch_reverse(django.template.defaulttags)
Upvotes: 1