Reputation: 4743
In my Django 2.0 site, I want to set the lang
atribute of the html tag to the current locale's language. In my base.html
which other templates extend, I use get_current_language
in the following way
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
<!DOCTYPE html>
<html lang="{{ LANGUAGE_CODE }}">
...
</html>
The site has translations for multiple languages. If I switch the language in the browser, I see the correct translations, but the lang
attribute will always contain en
.
In my settings.py
I have
USE_I18N = True
LANGUAGE_CODE = 'en-us'
and based on the suggestion of Goran the following middleware order
MIDDLEWARE = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
]
The LANGUAGES
setting is unset.
As suggested by Kostadin Slavov I have tried printing the language from the view. It seems that get_current_language calls django.utils.translation.get_language, so I have inserted the following in my view
from django.utils import translation
print(translation.get_language())
It prints the correct value (eg de
when accessing the view with a browser set to German).
What else am I missing?
Upvotes: 21
Views: 8281
Reputation: 245
Had the same problem. In my case, the function was called async and always returned the default language.
SOLUTION: pass language from 'main' context.
Code like in this example:
def get_context_data( self, **kwargs ):
context = super().get_context_data(**kwargs)
lng_code = get_language() # -> 'de'
@sync_to_async
def get_data():
context['data1'] = Model1.objects.filter(language==get_language()) # get_language() -> 'en'
@sync_to_async
def get_data2():
...
@sync_to_async
def get_data3():
...
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(
asyncio.gather(
get_data1(),
get_data2(),
get_data3()
))
loop.close()
Upvotes: 0
Reputation: 6122
I tried to simulate your environment with these steps:
$ cd ~
$ python3 -m venv ~/venvs/mysite
$ source ~/venvs/mysite/bin/activate
$ pip install django==2.0.8
$ django-admin startproject mysite
Then I updated the generate code as in your example:
mysite/settings.py
...
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
...
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
...
mysite/urls.py
from django.contrib import admin
from django.urls import path
from django.views.generic.base import TemplateView
urlpatterns = [
path('', TemplateView.as_view(template_name='base.html'), name='home'),
path('admin/', admin.site.urls),
]
templates/base.html
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
<!DOCTYPE html>
<html lang="{{ LANGUAGE_CODE }}">
<body>
<pre>LANGUAGE_CODE = {{ LANGUAGE_CODE }}</pre>
<body>
</html>
With the Django generated code and my few above updates I can see different language code if I switch the language of my browser visiting http://localhost:8000/ after starting it with:
$ python manage.py runserver
Try my steps on your local environment and check if it works, and then compare your project to the code above.
Try to use diffsettings to see "differences between the current settings file and Django’s default settings".
Upvotes: 6