#28567: Unclear documentation for 'next' parameter of set_language view
-------------------------------------+-------------------------------------
Reporter: George Tantiras | Owner: George
| Tantiras
Type: Bug | Status: assigned
Component: | Version: master
Internationalization |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Carlton Gibson):
* cc: Claude Paroz (added)
* has_patch: 1 => 0
* component: Documentation => Internationalization
Comment:
This looks like a bug to me, rather than a documentation issue.
You shouldn't have to set the `next` parameter, manually calling
`translate_url()` to get the value, since
[https://github.com/django/django/blob/8ba20d9071e9e1b8f2c81d4df977db4278342085/django/views/i18n.py#L45-L48
the `set_language()` view does that itself]:
{{{
next_trans = translate_url(next, lang_code)
if next_trans != next:
response = HttpResponseRedirect(next_trans)
}}}
A breakpoint inserted here, in the failing test case George provided
([https://github.com/django/django/pull/9058 Original PR]), shows the
`translate_url()` call failing.
Furthermore, as per the report, the `translate_url()` call works when
`prefix_default_language=True`.
The issue lies in the relation between the `set_language()` view,
LocaleMiddleware, and `i18n_patterns()` when
`prefix_default_language=False`.
If you disable `LocaleMiddleware` and set the the request language using
`translation.override()` (to, e.g. `'el'` here) the test passes.
The issue is in
[https://github.com/django/django/blob/8ba20d9071e9e1b8f2c81d4df977db4278342085/django/middleware/locale.py#L18-L26
`LocaleMiddle.process_request()`]:
{{{
def process_request(self, request):
urlconf = getattr(request, 'urlconf', settings.ROOT_URLCONF)
i18n_patterns_used, prefixed_default_language =
is_language_prefix_patterns_used(urlconf)
language = translation.get_language_from_request(request,
check_path=i18n_patterns_used)
language_from_path =
translation.get_language_from_path(request.path_info)
if not language_from_path and i18n_patterns_used and not
prefixed_default_language:
language = settings.LANGUAGE_CODE
translation.activate(language)
request.LANGUAGE_CODE = translation.get_language()
}}}
Here, because the `set_language()` view is routed outside of
`i18n_patterns()`, `not language_from_path and i18n_patterns_used and not
prefixed_default_language` is `True` and so the language is **always** set
to `settings.LANGUAGE_CODE`. This means that `translate_url()` never gets
a match trying to resolve the url to translate (because the wrong language
is activated).
**IF** you route the `set_language()` view inside `i18n_patterns()` then
the test passes **but you can't do that** because it's
[https://docs.djangoproject.com/en/2.2/topics/i18n/translation/#django.views.i18n.set_language
explicitly warned against in the docs]:
> **Warning**
> Make sure that you don’t include the above URL within i18n_patterns() -
it needs to be language-independent itself to work correctly.
Two thoughts:
* I'm not sure right now why that warning is required. (Could it be
changed?)
* `translate_url()` only functions on URLs coming from the currently
active language. Would it be feasible to have `set_language()` redetermine
the request language before calling `translate_url()`?
* Is `LocaleMiddleware's `not language_from_path and i18n_patterns_used
and not prefixed_default_language` correct? (I mean it seems it but...)
Option 2 seems the most likely. None of them look that nice.
Claude: I'd be grateful if you could check my reasoning here. 😬 Thanks.
--
Ticket URL: <https://code.djangoproject.com/ticket/28567#comment:14>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/066.364ba7522ee2504f4303763132a6f3aa%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.