Opened 10 years ago

Closed 5 years ago

#9340 closed Bug (fixed)

`translation.get_language()` should process `settings.LANGUAGE_CODE`

Reported by: Joost Cassee Owned by: nobody
Component: Internationalization Version: 1.0
Severity: Normal Keywords:
Cc: Triage Stage: Design decision needed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


When translation.get_language_from_request() processes the Accept-Language HTTP header it makes sure to remove the 'sublanguage' (territory) code if it is not in settings.LANGUAGES. So for example, if the HTTP headers contain Accept-Language: en_US and LANGUAGES = ('en', ...), then get_language_from_request() returns 'en'. However, if language negotiation fails then get_language_from_request() returns settings.LANGUAGE_CODE without checking LANGUAGES. Using default settings, get_language_from_request() would return 'en-us' while LANGUAGES only contains 'en'.

This behaviour is inconsistent. Either get_language_from_request() should not remove the sublanguage code from the negotiated language or it should also do so for the default language. In other words, either

  1. translation.get_language() is always in LANGUAGES, or
  2. translation.get_language() or its root language is always in LANGUAGES.

In the first case, 'en-us' should not be the default LANGUAGE_CODE (at least not as returned from get_language()). In the second case Django should not strip the sublanguage from the negotiated language code.

Because installations that do not use content negotiation will never call get_language_from_request() any stripping of the sublanguage code might need to be moved to translation.get_language().

Change History (9)

comment:1 Changed 9 years ago by Jacob

Triage Stage: UnreviewedDesign decision needed

comment:2 Changed 9 years ago by mrts

The proposed "get_language_from_request() should not remove the sublanguage code from the negotiated language" is backwards-incompatible. I for one would be hit by this, as a lot of my code assumes that behaviour. -1 on backwards-incompatibility.

I'd rephrase the problem: if settings.LANGUAGE_CODE is not in settings.LANGUAGES, your settings are inconsistent and should be fixed. The only "fix" in this case is a warning on ./ validate or a documentation update.

See also #11648.

comment:3 Changed 8 years ago by Jakub Wilk

Please note that settings.LANGUAGE_CODE is not in settings.LANGUAGES in the default configuration.

comment:4 Changed 7 years ago by Ramiro Morales

Could you describe what are the practical consequences of the reported inconsistency?

comment:5 Changed 7 years ago by Joost Cassee

The documentation of get_language_from_request says: "Analyzes the request to find what language the user wants the system to show. Only languages listed in settings.LANGUAGES are taken into account. If the user requests a sublanguage where we have a main language, we send out the main language." This is simply not true if the function returns settings.LANGUAGE_CODE, because it is 'en-us' by default and only 'en' is in settings.LANGUAGES.

I have been working around this issue myself. For example, if I want to get the language name of request.LANGUAGE_CODE from settings.LANGUAGES, I have to try both LANGUAGE_CODE itself and base_lang(LANGUAGE_CODE). I had the same problem once when I did model translation by adding name_LANGUAGE_CODE fields to models.

So, not a big problem, more of a "thousand cuts"-type of inconsistency.

comment:6 Changed 7 years ago by Luke Plant

Severity: Normal
Type: Bug

comment:7 Changed 6 years ago by Aymeric Augustin

UI/UX: unset

Change UI/UX from NULL to False.

comment:8 Changed 6 years ago by Aymeric Augustin

Easy pickings: unset

Change Easy pickings from NULL to False.

comment:9 Changed 5 years ago by Ramiro Morales

Resolution: fixed
Status: newclosed

#19763 was a four years younger duplicate. The fix implemented in 8c8f94fe9 chose option 2 as presented by the OP of this ticket.

I'm closing this one as fixed.

Note: See TracTickets for help on using tickets.
Back to Top