Recently I had been working on website made 2 or 3 years ago by my predecessor (I write this because app is a mess and it's not my fault). Boss asked me to make it multilingual just simply adding English version. I followed instructions from djangoproject docs, made nice .po and .mo files in locale directory, set urls for i18n views and added form with proper select to HTML. The problem is, when I send POST with language code to setlang view from i18n, django do not change language nor throw any errors. Unfortunately, in 1.6.5, django.utils.translation doesn't have LANGUAGE_SESSION_KEY, so I don't even know how should I change session data... So, here you have my settings:
"""
Django settings for Profilaktyka project.
For more information on this file, see
https://docs.djangoproject.com/en/1.6/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.6/ref/settings/
"""
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
import time
from socket import gethostname
ROOT = BASE_DIR = os.path.dirname(os.path.dirname(__file__))
HOSTNAME = gethostname()
def make_path(path):
return os.path.join(BASE_DIR, path)
def make_abs_path(path):
return os.path.abspath(make_path(path))
def get_proj_root():
curr_path = make_abs_path('')
return os.path.split(curr_path)[0]
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = ''
# SECURITY WARNING: don't run with debug turned on in production!
try:
from Plan_Zajec import myconf
DEBUG = myconf.DEBUG
DIST = myconf.DIST
except ImportError:
DEBUG = True
DIST = False
TEMPLATE_DEBUG = DEBUG
if os.path.exists(os.path.join(BASE_DIR, 'my.cnf')):
ALLOWED_HOSTS = ['*']
# Database
# https://docs.djangoproject.com/en/1.6/ref/settings/#databases
# settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'OPTIONS': {
'read_default_file': os.path.join(BASE_DIR, 'my.cnf'),
},
}
}
else:
ALLOWED_HOSTS = []
# Database
# https://docs.djangoproject.com/en/1.6/ref/settings/#databases
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'dev.sqlite'),
# }
# }
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
'NAME': '', # Or path to database file if using sqlite3.
'USER': '', # Not used with sqlite3.
'PASSWORD': '', # Not used with sqlite3.
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
}
# Application definition
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# installed app:
# 'tinymce',
'djcelery',
'gunicorn',
'django_extensions',
'south',
# myapps:
'cv.editcv',
'cv.bazy',
)
MIDDLEWARE_CLASSES = (
'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',
'cv.lang.Language',
)
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.static',
'django.core.context_processors.tz',
'django.contrib.messages.context_processors.messages',
'django.core.context_processors.csrf'
)
ROOT_URLCONF = 'website.urls'
WSGI_APPLICATION = 'website.wsgi.application'
# Internationalization
# https://docs.djangoproject.com/en/1.6/topics/i18n/
LANGUAGE_CODE = 'pl'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.6/howto/static-files/
STATIC_ROOT = make_abs_path('static_root')
STATIC_URL = '/static/'
# file upload config
MEDIA_ROOT = make_abs_path('media')
MEDIA_URL = '/media/'
# TODO
if 'ibmed' in HOSTNAME:
MEDIA_URL = 'http://192.168.1.120:8080' + MEDIA_URL
STATIC_URL = 'http://192.168.1.120:8080' + STATIC_URL
# logging
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
},
'simple': {
'format': '%(levelname)s %(message)s'
},
},
'handlers': {
'null': {
'level': 'DEBUG',
'class': 'logging.NullHandler',
},
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
'filters': [],
}
},
'loggers': {
'django': {
'handlers': ['null'],
'propagate': True,
'level': 'INFO',
},
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
}
}
# South conf:
SOUTH_MIGRATION_MODULES = {
'django_extensions': 'ignore',
}
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
SESSION_COOKIE_AGE = 36000
ADRES = '/cv/'
LOGIN_URL = ADRES + "logowanie/"
DATE_FORMAT = 'Y-m-d'
MY_ADR = 'cv'
LOCALE_PATHS = (
make_abs_path('locale')
)
BROKER_TRANSPORT = 'redis'
BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = "redis"
CELERY_REDIS_HOST = "localhost"
CELERY_REDIS_PORT = 6379
CELERY_REDIS_DB = 0
Directory tree (as I told, this is mess but I can't rework that, because "We don't have time for that"...)
.
├── celerybeat-schedule
├── dryscrape
│ └── (...)
├── env
│ └── (...)
├── KARIERA.sublime-project
├── KARIERA.sublime-workspace
├── requirements.txt
├── src
│ ├── addons.py
│ ├── cv
│ │ ├── editcv
│ │ │ ├── administrator.py
│ │ │ ├── admin.py
│ │ │ ├── celeryconfig.py
│ │ │ ├── celery.py
│ │ │ ├── formularze2.py
│ │ │ ├── formularze.py
│ │ │ ├── formy.py
│ │ │ ├── __init__.py
│ │ │ ├── migrations
│ │ │ │ └── (...)
│ │ │ ├── models.py
│ │ │ ├── opisy.py
│ │ │ ├── publik.py
│ │ │ ├── PubMedApi.py
│ │ │ ├── punkty.py
│ │ │ ├── tasks.py
│ │ │ ├── templates
│ │ │ │ └── (...)
│ │ │ ├── templatetags
│ │ │ │ └── (...)
│ │ │ ├── UjBib.py
│ │ │ ├── views.py
│ │ │ ├── WebOfScienceAPI.py
│ │ │ ├── wykresy.py
│ │ ├── formy.py
│ │ ├── __init__.py
│ │ ├── lang.py
│ │ ├── std.py
│ │ ├── views.py
│ ├── czcionki
│ │ └── (...)
│ ├── develop.py
│ ├── dev.sqlite
│ ├── docxmp
│ │ └── (...)
│ ├── __init__.py
│ ├── locale
│ │ ├── en
│ │ │ └── LC_MESSAGES
│ │ │ ├── django.mo
│ │ │ └── django.po
│ │ └── pl
│ │ └── LC_MESSAGES
│ │ ├── django.mo
│ │ └── django.po
│ ├── manage.py
│ ├── media
│ │ └── (...)
│ └── website
│ ├── celery.py
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── wsgi.py
├── TAGS
├── webkit-server
│ └── build
│ ├── lib
│ └── lib.linux-x86_64-2.7
└── xls
└── (...)
In urls.py I just added:
url(r'^lang/', include(i18n))
which I'm using with form:
<form action="/lang/setlang/" method="post">
{% csrf_token %}
<input type="submit" value="{% trans 'Zmień język' %}" />
<select name="language">
{% for language in st.languages %}
<option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected="selected"{% endif %}>
{{ language.name_local }} ({{ language.code }})
</option>
{% endfor %}
</select>
</form>
st.languages is just:
'languages': [
{'code': 'pl',
'name_local': 'polski'},
{'code': 'en',
'name_local': 'english'}]
Anyone?