I have a small Django application, which I tried to localize.
In the urls.py I have
urlpatterns += i18n_patterns(
path('add_request/',AddRequest.as_view(),name='add_request'),
path('add_offer/', AddOffer.as_view(), name='add_offer'),
)
In the settings.py I have
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',
]
and
LANGUAGE_CODE = 'de'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
LOCAL_PATHS = (
os.path.join(BASE_DIR, 'locale/'),
)
USE_TZ = True
LANGUAGES= [
('en', 'English'),
('de', 'German')
]
I have marked strings for translation in my models.py (verbose_name),
the forms.py (label) and in a template.
I extracted po files via
django-admin makemessages -l en
django-admin makemessages -l de
Translated them and ran
django-admin compilemessages
Now I have the prefixes de/ and en/ for my urls. The Locale seems to be set correctly, as date input fields change to the right date format, but the translations are not used.
I'm an idiot. It is of course supposed to be LOCALE_PATHS, instead of LOCAL_PATHS.
Related
I have configured Django i18n and it works just fine if you change the browser language using the browser configuration UI. I have tested both English and Spanish. However, when I try to let the user pick the language from the navigation bar and set a new LANGUAGE_SESSION_KEY based on the selection made by the user it would not work. The browser language will continue to be the selected language instead.
Here follows my code:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
...
LANGUAGE_CODE = 'en'
LANGUAGE_SESSION_KEY = 'en'
TIME_ZONE = 'America/Sao_Paulo'
USE_I18N = True
USE_L10N = True
USE_TZ = True
LOCALE_PATHS = (
os.path.join(BASE_DIR, 'locale'),
)
LANGUAGES = (
('en', _('English')),
('es', _('Spanish')),
('pt', _('Portuguese'))
)
The view that is triggered by the navbar:
def setLanguage(request, language_code):
language = get_language()
try:
request.session[LANGUAGE_SESSION_KEY] = language_code
translation.activate(language_code)
request.LANGUAGE_CODE = translation.get_language()
request.session[translation.LANGUAGE_SESSION_KEY] = language_code
request.session.save()
except Exception as e:
print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ Oops!", e.__class__, "occurred.")
translation.activate(language)
return redirect('home_index')
I have debugged that the language_code passed corresponds correctly to the selected language (e.g. es instead of en) but it is not activated. The browser language remains as the active language.
I would appreciate any ideas. Thanks!
Alberto
After some research I found that the locale middleware is causing this, so I just commented it out. It is working as expected now.
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
#'django.middleware.locale.LocaleMiddleware',
By default django messages framework does not localize it's messages correctly.
For example in admin interface
As you can see all other things in admin panel are localized. The translation file exists. Here is my settings.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
...
]
MIDDLEWARE = [
'debug_toolbar.middleware.DebugToolbarMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.locale.LocaleMiddleware',
]
LANGUAGE_CODE = 'ru' # I've tried 'ru-RU'
TIME_ZONE = 'Europe/Moscow'
USE_I18N = True
USE_L10N = True
USE_TZ = True
How to fix this? Thanks in advance. I have django version 3.0.6. This error also is absent in django 1.8
It was a breaking change from django/django#42b9a23 (Django 3.0+) that only updated the French translations.
You can patch DjangoTranslation.gettext to handle the smart quotes.
def _patch_gettext():
from django.utils.translation.trans_real import DjangoTranslation
_gettext = DjangoTranslation.gettext
def gettext(self, message):
text = _gettext(self, message)
if text is message and '“' in message:
new_message = message.replace('“', '"').replace('”', '"')
new_text = _gettext(self, new_message)
if new_text is not new_message:
return new_text
return text
DjangoTranslation.gettext = gettext
About patching
Subclass AppConfig in mysite/apps.py:
from django.apps import AppConfig
class MySiteAppConfig(AppConfig):
name = 'mysite'
def ready(self):
_patch_gettext()
Put the dotted path to that subclass in INSTALLED_APPS in mysite/settings.py:
INSTALLED_APPS = [
...
'mysite.apps.MySiteAppConfig',
]
Reference: https://docs.djangoproject.com/en/3.0/ref/applications/#configuring-applications
Django 1.9.6 i18n works perfect when I open the browser and change language.
But I want to save language and the other times when user comes it will be in his/her prefered language.
Now when I open the site it always redirect me to /en .I tried to change my settings and set
LANGUAGE_CODE='ru'
or something else but it does not work here is my settings file
ALLOWED_HOSTS = []
LOGIN_URL=reverse_lazy('login')
AUTH_USER_MODEL='custom.MyUser'
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'custom',
'languages',
]
MIDDLEWARE_CLASSES = [
'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.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'builtcustom.urls'
WSGI_APPLICATION = 'builtcustom.wsgi.application'
LANGUAGES=(
('en',_('ENGLISH')),
('fr',_('FRENCH')),
('cs', _('czech')),
('hy', _('ARMENIAN')),
('ru', _('RUSSIAN')),
)
LOCALE_PATHS = (
os.path.join(BASE_DIR, 'locale'),
)
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ =False
How can i solve this problem and redirect to url with a language that I want(Dynamically selected from database)??
For a particular url you an select language like this in Django.
from django.utils.translation import activate
activate('fr') # To use french
Checkout the documentation.
You can easily get whatever language you want from the database and call activate on it. Make sure your the languages in database has same abbreviations as in Django.
I have a Django 1.9.1 app. Some of it appears in French, but not all. When I visit one of my forms, I get some stock phrases in French ("Search" => "Rechercher", "Name" => "Nom"), but not any of my app's phrases (e.g., "Add New Patient", "Caregiver" are both in English).
I have language settings configured:
PROJECT_DIR = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.dirname(
os.path.abspath(__file__)))))
LANGUAGES = [
('fr', _('French')),
('en', _('English')),
]
USE_I18N = True
USE_L10N = True
LOCALE_PATHS = (
os.path.join(PROJECT_DIR, "locale"),
)
I have LocaleMiddleware configured:
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
# LocaleMiddleware should be after SessionMiddleware and before CommonMiddleware
# See https://docs.djangoproject.com/en/1.9/topics/i18n/translation/#how-django-discovers-language-preference
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
)
I have a some translation files that came from "makemessages -l fr" with my phrases translated:
locale/fr/LC_MESSAGES/django.po
locale/fr/LC_MESSAGES/django.mo
I load i18n in my template.
{% load i18n %}
Some of it is in French, so that shouldn't be the problem anyway.
I am using the Quick Language Switcher to send the Accept-Language: HTTP header 'fr'.
The Django debug toolbar shows up in French (!), and says "Accept-Language: fr" in the HTTP request, and "Content-Language: fr" in the HTTP response. It also says the Django variable LANGUAGE_CODE is "en-us" (?), even though I have that setting commented out.
I have read "How Django discovers language preference" and I don't see what I'm missing.
My LOCALE_PATH was wrong. It was one level too high. Here is the right LOCALE_PATH for me:
BASE_DIR = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
LOCALE_PATHS = (
os.path.join(BASE_DIR, "locale"),
)
Settings.py constants
TIME_ZONE = 'Europe/Vilnius'
LANGUAGE_CODE = 'lt'
USE_I18N = True
USE_L10N = True
USE_TZ = True
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
If I add LocaleMiddleware to the middleware classes and edit source code so that it would print my locale, it prints lt as expected.
Moreover:
./manage.py makemessages -l lt generated the file and I translated text occurences.
./manage.py compilemessages returns processing file django.po in /Users/aemdy/PycharmProjects/rezervavau_v2/locale/lt/LC_MESSAGES
But sadly I still see english text in my pages.
I use django admin and the phrases included in the basic django admin are translated (Change password, password, edit and some others). Still, my own defined phrases are shown in english.
Well, I have found the answer myself.
I needed to add the following line in settings.py:
LOCALE_PATHS = (os.path.join(os.path.dirname(__file__), '../locale/'),)