django i18n_patterns hide default lang_code from url

时光毁灭记忆、已成空白 提交于 2019-12-17 22:25:58

问题


I'm using the i18n_patterns to add a prefix of current lang_code to my url.

urlpatterns += i18n_patterns('',
    url(r'^', include('blaszczakphoto2.gallery.urls')),
)

It allowes me to get urls like /en/about-us/ , /pl/about-us/ etc.. My default language is pl

LANGUAGE_CODE = 'pl'

I want url like /about-us/ for clients viewing my site in polish lenguage. Is there any way to hide lang_code prefix from url for default lang_code?


回答1:


Here is a very simple package: django-solid-i18n-urls

After setup, urls without language prefix will always use default language, that is specified in settings.LANGUAGE_CODE. Redirects will not occur.

If url will have language prefix, then this language will be used.

Also answered here: https://stackoverflow.com/a/16580467/821594.




回答2:


Django >=1.10 can handle this natively. There is a new prefix_default_language argument in i18n_patterns function.

Setting prefix_default_language to False removes the prefix from the default language (LANGUAGE_CODE). This can be useful when adding translations to existing site so that the current URLs won’t change.

Source: https://docs.djangoproject.com/en/dev/topics/i18n/translation/#language-prefix-in-url-patterns

Example:

# Main urls.py:
urlpatterns = i18n_patterns(
    url(r'^', include('my_app.urls', namespace='my_app')), 
    prefix_default_language=False
)

# my_app.urls.py:
url(r'^contact-us/$', ...),

# settings:
LANGUAGE_CODE = 'en' # Default language without prefix

LANGUAGES = (
    ('en', _('English')),
    ('cs', _('Czech')),
)

The response of example.com/contact-us/ will be in English and example.com/cs/contact-us/ in Czech.




回答3:


I faced this problem and solved this way:

  • Created an alternative i18n_patterns that do not prefix the site main language (defined in settings.LANGUAGE_CODE).

  • Created an alternative middleware that only uses the URL prefixes language to activate the current language.

I didn't see any side-effect using this technique.

The code:

# coding: utf-8
"""
Cauê Thenório - cauelt(at)gmail.com

This snippet makes Django do not create URL languages prefix (i.e. /en/)
for the default language (settings.LANGUAGE_CODE).

It also provides a middleware that activates the language based only on the URL.
This middleware ignores user session data, cookie and 'Accept-Language' HTTP header.

Your urls will be like:

In your default language (english in example):

    /contact
    /news
    /articles

In another languages (portuguese in example):

    /pt/contato
    /pt/noticias
    /pt/artigos

To use it, use the 'simple_i18n_patterns' instead the 'i18n_patterns'
in your urls.py:

    from this_sinppet import simple_i18n_patterns as i18n_patterns

And use the 'SimpleLocaleMiddleware' instead the Django's 'LocaleMiddleware'
in your settings.py:

    MIDDLEWARE_CLASSES = (
    ...
        'this_snippet.SimpleLocaleMiddleware'
    ...
    )

Works on Django >=1.4
"""

import re

from django.conf import settings
from django.conf.urls import patterns
from django.core.urlresolvers import LocaleRegexURLResolver
from django.middleware.locale import LocaleMiddleware
from django.utils.translation import get_language, get_language_from_path
from django.utils import translation


class SimpleLocaleMiddleware(LocaleMiddleware):

    def process_request(self, request):

        if self.is_language_prefix_patterns_used():
            lang_code = (get_language_from_path(request.path_info) or
                         settings.LANGUAGE_CODE)

            translation.activate(lang_code)
            request.LANGUAGE_CODE = translation.get_language()


class NoPrefixLocaleRegexURLResolver(LocaleRegexURLResolver):

    @property
    def regex(self):
        language_code = get_language()

        if language_code not in self._regex_dict:
            regex_compiled = (re.compile('', re.UNICODE)
                              if language_code == settings.LANGUAGE_CODE
                              else re.compile('^%s/' % language_code, re.UNICODE))

            self._regex_dict[language_code] = regex_compiled
        return self._regex_dict[language_code]


def simple_i18n_patterns(prefix, *args):
    """
    Adds the language code prefix to every URL pattern within this
    function, when the language not is the main language.
    This may only be used in the root URLconf, not in an included URLconf.

    """
    pattern_list = patterns(prefix, *args)
    if not settings.USE_I18N:
        return pattern_list
    return [NoPrefixLocaleRegexURLResolver(pattern_list)]

The code above is available on: https://gist.github.com/cauethenorio/4948177




回答4:


You might want to check yawd-translations which does exactly that. If you don't care about the extra functionality (manage languages from db), you can have a look at the urls.translation_patterns method and the middleware.TranslationMiddleware to see how it can be done.




回答5:


This is my solution:

Create django middleware: django_app/lib/middleware/locale.py

from django.utils import translation

    class SwitchLanguageMiddleware(object):

        def process_request(self, request):
            lang = request.GET.get('lang', '')

            if lang:
                translation.activate(lang)
                request.LANGUAGE_CODE = translation.get_language()

        def process_response(self, request, response):
            request.session['django_language'] = translation.get_language()
            if 'Content-Language' not in response:
                response['Content-Language'] = translation.get_language()
            translation.deactivate()

            return response

It's read the get parameter of request and if it has lang attribute, then switching language. Ex.: /about-us/?lang=pl

Include this middleware to settings.py:

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.common.CommonMiddleware',

    'django_app.libs.middleware.locale.SwitchLanguageMiddleware',
)


来源:https://stackoverflow.com/questions/11348303/django-i18n-patterns-hide-default-lang-code-from-url

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!