Django internationalization for static website

649 views Asked by At

I'm trying to make a double-languages (italian and english) site with Django and Python. I have followed this little tutorial and I'm stuck in a doubt.
I don't want any database (neither admin page) for this site, so I have deleted the database setup part in settings.py, then I activated "USE_I18N = True" and ugettext and everything else. In fact, when I go to localhost it shows correctly both languages translations with the /it/ and /en/ put after the localhost:8000.
I'm trying, now, to make a button for switching languages, adding the djangoproject code to my template file, here:

{% load i18n %}
<form action="{% url 'set_language' %}" method="post">
{% csrf_token %}
<input name="next" type="hidden" value="{{ redirect_to }}" />
<select name="language">
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected="selected"{% endif %}>
    {{ language.name_local }} ({{ language.code }})
</option>
{% endfor %}
</select>
<input type="submit" value="Go" />
</form>

The problem is that when I choose a language from the drop-down-menu, an error shows up

ImproperlyConfigured at /it/i18n/setlang/
settings.DATABASES is improperly configured. Please supply the ENGINE value. Check settings documentation for more details.
Request Method: POST
Request URL:    http://localhost:8000/it/i18n/setlang/
Django Version: 1.8.2
Exception Type: ImproperlyConfigured
Exception Value:    
settings.DATABASES is improperly configured. Please supply the ENGINE value. Check settings documentation for more details.

Here's the app tree:

sito_personale --- locale --- en --- LC_MESSAGES --- django.mo
                                                 --- django.po
                          --- it --- LC_MESSAGES --- django.mo
                                                 --- django.po
               --- pages --- migration
                         --- static
                         --- templates
               --- sito_personale
               --- manage.py

Is there anything I can do to solve this issue?

I really appreciate any help you can provide.

2

There are 2 answers

10
sthzg On

Django saves the selected language to the session. SESSION_ENGINE defaults to use the database and since you don't use the db this might result in the exception you are getting.

Try to set SESSION_ENGINE to django.contrib.sessions.backends.file, which instead will store session data on disk (see Using file-based sessions).

So in your settings.py add:

SESSION_ENGINE = 'django.contrib.sessions.backends.file'

Update

If your site doesn't need support for sessions you could also remove the session middleware. In that case Django will use cookies to store the language preference

The view expects to be called via the POST method, with a language parameter set in request. If session support is enabled, the view saves the language choice in the user’s session. Otherwise, it saves the language choice in a cookie that is by default named django_language. (The name can be changed through the LANGUAGE_COOKIE_NAME setting.)


Update Follow-up question from comment

As by the warning in the docs, the i18n pattern needs to be in the language independent urlpatterns:

Warning
Make sure that you don’t include the above URL within i18n_patterns() - it needs to be language-independent itself to work correctly.

Here is a quick example of how that might translate to your urls.py from above:

urlpatterns = solid_i18n_patterns('',
    # Examples:
    # url(r'^$', 'sito_personale.views.home', name='home'),
    # url(r'^blog/', include('blog.urls')),
    url(r'', include('pages.urls')),
)

urlpatterns += patterns('',
    url(r'^i18n/', include('django.conf.urls.i18n')),
)
0
Stefano De Rosso On

I may have found a solution, but I don't know if it's the correct/best one. I have changed, in the template code:

<input name="next" type="hidden" value="{{ redirect_to }}" />

to

<input name="next" type="hidden" value="/" />

and now it works flawlessly! I hope it's the best way to the solve the issue, if anyone could answer my doubt about it, I'd really appreciate that.