Reputation: 19969
I am using i18n_patterns
but I want to use reverse
to create a link to the page without language in the url (such that the user will be redirected based on cookies and headers and such).
I have tried
from django.utils.translation import activate, deactivate, get_language
current_lang = get_language()
deactivate()
url = reverse(things)
activate(current_lang)
That works for getting other language versions using activate(target_lang)
, but if I deactivate
I just get urls for the default language (/en/account/
but I want /account/
).
I already thought getting alternate language versions is overly complicated, but this I cannot manage at all. Any hints? (Without manually stripping LANGUAGE_CODE
from the url)
UPDATE: I also tried
from django.core.urlresolvers import get_resolver
get_resolver(None).reverse(*args, **kwargs)
but get NoReverseMatch
Upvotes: 4
Views: 3849
Reputation: 6382
Another route that is vanilla Django, but affects your URLs, Django provides the ability to omit the language prefix for your default language. Then reverse
will work as you wish.
If in urls.py
you turn off the language prefix for your default language, using the prefix_default_language
parameter of the i18n_patterns method:
i18n_patterns(path(), path(), ..., prefix_default_language=False)
Then, when the default language is activated, the URL without the prefix is returned by reverse
:
>>> activate(settings.LANGUAGE_CODE) # or activate("en")
>>> reverse("news:index")
'/news/'
>>> activate("nl")
>>> reverse("news:index")
'/nl/news/'
Upvotes: 0
Reputation: 41
I also spent time to find a nice solution and here is mine.
Next to main urls file ('my_project/urls.py'), create the file 'my_project/urls_without_lang.py' with the content below.
Then, you can use reverse('viewname', urlconf='my_project.urls_without_lang')
Django=<1.11
from copy import copy
from django.urls.resolvers import LocaleRegexURLResolver
from .urls import urlpatterns as urlpatterns_i18n
"""
Purpose of this file is to be able to reverse URL patterns without language prefix.
This is usefull to build URL meant to be communicated "outside" of the domain without any language duty.
To use it with 'reverse' method (from django.shortcuts module), simply give the additional parameter:
`urlconf='my_project.urls_without_lang'`
Example: `reverse('viewname', urlconf='my_project.urls_without_lang')`
"""
urlpatterns = copy(urlpatterns_i18n)
for el in urlpatterns_i18n:
if isinstance(el, LocaleRegexURLResolver):
urlpatterns.remove(el)
urlpatterns += el.url_patterns
Django>1.11
from copy import copy
from django.urls import URLResolver
from .urls import urlpatterns as urlpatterns_i18n
urlpatterns = copy(urlpatterns_i18n)
for el in urlpatterns_i18n:
if isinstance(el, URLResolver) and isinstance(el.urlconf_name, list):
urlpatterns.remove(el)
urlpatterns += el.url_patterns
Hope that will help some of you.
Upvotes: 0
Reputation: 1011
I think the easiest way is to let Django resolve the URL with the language prefix and then just remove the language prefix.
You can write the following function:
import re
from django.core.urlresolvers import reverse
def reverse_no_i18n(viewname, *args, **kwargs):
result = reverse(viewname, *args, **kwargs)
m = re.match(r'(/[^/]*)(/.*$)', result)
return m.groups()[1]
Now, anywhere in your code you can do something like this:
from myproject.utils import reverse_no_i18n
def my_view(request):
return HttpResponseRedirect(reverse_no_i18n('my_view_name'))
You might also want to create a custom {% url %}
templatetag which calls your custom function.
Upvotes: 3