Django: URL pattern translation with gettext
In some Django applications I encountered URL patterns with gettext such as:
from django.utils.translation import ugettext as _
urlpatterns = patterns('',
...
url(r'^%s$' % _('about/'), about, name='about'),
...
)
At first, it seemed to be a good idea to have internationalized URLs 开发者_运维问答in a uniform way with the rest of the project but I have doubts.
AFAIK, URL patterns are loaded at application start-up. So I suspect they will be build according to the language preferences of the user who makes the first request to the application. This may get even more unpredictable when threads are in the play too.
This approach may be reasonable for cases where an installation will be in single language but there may be other installations in other languages, like forum applications.
Do you think this is a problem or just my imagination? Can this approach be used for multilingual sites? Can ugettext_lazy
avoid this problem?
Have a read of the django docs: https://docs.djangoproject.com/en/dev/topics/i18n/translation/#url-internationalization
Basically, you can use ugettext_lazy to translate your patterns and it will work provided a language is set for every request. To ensure this, you should use LocaleMiddleware. https://docs.djangoproject.com/en/dev/ref/middleware/#django.middleware.locale.LocaleMiddleware
This approach will not work. Your translation takes place when the application loads. This means your URL patterns will be of a single language, the default language of your app.
Translations only work when the context they are called from have access to a user's language preference.
For your URLs to be multilingual, you have to use some run-time url definitions. These would be loaded based on the user's current language.
You are right about ugettext_lazy is evaluated right away when concatenating strings.
Sth like that works: url(_(r'^contact/'), include('contact.urls')),
But you have to translate patterns what could be erroneus.
You could do it like this:
import six
from django.utils.functional import lazy
def lazy_url_pattern(pattern):
return lazy(pattern, six.text_type)()
And then in your dispatcher:
urlpatterns = [
url(lazy_url_pattern(lambda: r'^{n}/$'.format(n=ugettext_lazy(u'foo'))), MyView.as_view(), name='...'),
But it's still error-prone though....
Paul
精彩评论